Skip to content

Commit

Permalink
feat: New model and preprocessing
Browse files Browse the repository at this point in the history
  • Loading branch information
Kohulan committed Jun 29, 2023
1 parent 0f99e12 commit 782c5b9
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 64 deletions.
4 changes: 2 additions & 2 deletions DECIMER/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-

"""
DECIMER V2.2.3 Python Package.
DECIMER V2.3.0 Python Package.
============================
This repository contains DECIMER-V2,Deep lEarning for Chemical ImagE Recognition) project
Expand All @@ -23,7 +23,7 @@
"""

__version__ = "2.2.3"
__version__ = "2.3.0"

__all__ = [
"DECIMER",
Expand Down
95 changes: 43 additions & 52 deletions DECIMER/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ def resize_byratio(image):
This function takes a Pillow Image object and will resize the image by 512 x 512
To upscale or to downscale the image LANCZOS resampling method is used.
with the new pillow version the antialias is turned on when using LANCZOS.
___
im: PIL.Image
___
output: PIL.Image
Args: PIL.Image
Returns: PIL.Image
"""
maxwidth = 512
ratio = maxwidth / max(image.width, image.height)
Expand All @@ -31,66 +29,58 @@ def resize_byratio(image):
return resized_image


def central_square_image(im):
def central_square_image(image):
"""
This function takes a Pillow Image object and will add white padding
so that the image has a square shape with the width/height of the longest side
of the original image.
___
im: PIL.Image
___
output: PIL.Image
Args: PIL.Image
Returns: PIL.Image
"""
max_wh = int(1.2 * max(im.size))
max_wh = int(1.2 * max(image.size))
# If the new image is smaller than 299x299, then let's paste it into an empty image
# of that size instead of distorting it later while resizing.
if max_wh < 512:
max_wh = 512
new_im = Image.new(im.mode, (max_wh, max_wh), "white")
new_im = Image.new(image.mode, (max_wh, max_wh), "white")
paste_pos = (
int((new_im.size[0] - im.size[0]) / 2),
int((new_im.size[1] - im.size[1]) / 2),
int((new_im.size[0] - image.size[0]) / 2),
int((new_im.size[1] - image.size[1]) / 2),
)
new_im.paste(im, paste_pos)
new_im.paste(image, paste_pos)
return new_im


def delete_empty_borders(im):
def delete_empty_borders(image):
"""This function takes a Pillow Image object, converts it to grayscale and
deletes white space at the borders.
___
im: PIL.Image
___
output: PIL.Image
Args: PIL.Image
Returns: PIL.Image
"""
im = np.asarray(im.convert("L"))
mask = im > 200
image = np.asarray(image.convert("L"))
mask = image > 200
rows = np.flatnonzero((~mask).sum(axis=1))
cols = np.flatnonzero((~mask).sum(axis=0))
crop = im[rows.min() : rows.max() + 1, cols.min() : cols.max() + 1]
crop = image[rows.min() : rows.max() + 1, cols.min() : cols.max() + 1]
return Image.fromarray(crop)


def PIL_im_to_BytesIO(im):
def PIL_im_to_BytesIO(image):
"""
Convert pillow image to io.BytesIO object
___
im: PIL.Image
___
Output: io.BytesIO object with the image data
Args: PIL.Image
Returns: io.BytesIO object with the image data
"""
output = io.BytesIO()
im.save(output, format="PNG")
image.save(output, format="PNG")
return output


def HEIF_to_pillow(image_path: str):
"""
Converts Apple's HEIF format to useful pillow object
___
image_path (str): path of input image
___
Output: PIL.Image
Returns: image_path (str): path of input image
Returns: PIL.Image
"""
register_heif_opener()

Expand All @@ -101,10 +91,8 @@ def HEIF_to_pillow(image_path: str):
def remove_transparent(image_path: str):
"""
Removes the transparent layer from a PNG image with an alpha channel
___
image_path (str): path of input image
___
Output: PIL.Image
Args: image_path (str): path of input image
Returns: PIL.Image
"""
try:
png = Image.open(image_path).convert("RGBA")
Expand All @@ -125,28 +113,24 @@ def remove_transparent(image_path: str):
def get_bnw_image(image):
"""
converts images to black and white
___
image: PIL.Image
___
Output: PIL.Image
Args: PIL.Image
Returns: PIL.Image
"""

im_np = np.asarray(image)
grayscale = cv2.cvtColor(im_np, cv2.COLOR_BGR2GRAY)
# (thresh, im_bw) = cv2.threshold(grayscale, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
im_pil = Image.fromarray(grayscale)
enhancer = ImageEnhance.Contrast(im_pil)
im_output = enhancer.enhance(1.2)
im_output = enhancer.enhance(1.8)
return im_output


def increase_contrast(image):
"""
This function increases the contrast of an image input.
___
image: PIL.Image
___
Output: PIL.Image
Args: PIL.Image
Returns: PIL.Image
"""

# Get brightness range
Expand All @@ -166,27 +150,33 @@ def increase_contrast(image):
def get_resize(image):
"""
This function used to decide how to resize a given image without losing much information.
___
image: PIL.Image
___
Output: PIL.Image
Args: PIL.Image
Returns: PIL.Image
"""

width, height = image.size

# Checks the image size and resizes using the LANCOS image resampling
if (width == height) and (width < 512):
image = image.resize((512, 512), resample=Image.LANCZOS)

elif width >= 512 or height >= 512:
return image

else:
image = resize_byratio(image)

return image


def increase_brightness(image):
"""
This function adjusts the brightness of the given image.
Args: PIL.Image
Returns: PIL.Image
"""
enhancer = ImageEnhance.Brightness(image)
image = enhancer.enhance(1.6)
return image


def decode_image(image_path: str):
"""
Loads an image and preprocesses the input image in several steps to get the image ready for DECIMER input.
Expand All @@ -203,6 +193,7 @@ def decode_image(image_path: str):
img = get_resize(img)
img = delete_empty_borders(img)
img = central_square_image(img)
img = increase_brightness(img)
img = PIL_im_to_BytesIO(img)
img = tf.image.decode_png(img.getvalue(), channels=3)
img = tf.image.resize(img, (512, 512), method="gaussian", antialias=True)
Expand Down
7 changes: 2 additions & 5 deletions DECIMER/decimer.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,11 @@
default_path = pystow.join("DECIMER-V2")

# model download location
model_url = "https://zenodo.org/record/7624994/files/models.zip"
model_url = "https://zenodo.org/record/8093783/files/models.zip"
model_path = str(default_path) + "/DECIMER_model/"

# download models to a default location
if (
os.path.exists(model_path)
and os.stat(model_path + "/saved_model.pb").st_size != 28425789
):
if os.path.exists(model_path):
shutil.rmtree(model_path)
config.download_trained_weights(model_url, default_path)
elif not os.path.exists(model_path):
Expand Down
10 changes: 5 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@
if (
platform.processor() == "arm" or platform.processor() == "i386"
) and platform.system() == "Darwin":
tensorflow_os = "tensorflow-macos==2.10.0"
tensorflow_os = "tensorflow-macos>=2.10.0"
else:
tensorflow_os = "tensorflow==2.10.1"
tensorflow_os = "tensorflow==2.12.0"

with open("README.md", "r") as fh:
long_description = fh.read()

setuptools.setup(
name="decimer",
version="2.2.3",
version="2.3.0",
author="Kohulan Rajan",
author_email="kohulan.rajan@uni-jena.de",
maintainer="Kohulan Rajan",
maintainer_email="kohulan.rajan@uni-jena.de",
maintainer="Kohulan Rajan, Otto Brinkhaus ",
maintainer_email="kohulan.rajan@uni-jena.de, otto.brinkhaus@uni-jena.de",
description="DECIMER 2.0: Deep Learning for Chemical Image Recognition using Efficient-Net V2 + Transformer",
long_description=long_description,
long_description_content_type="text/markdown",
Expand Down

0 comments on commit 782c5b9

Please sign in to comment.