Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated benchmarks and added Stains. #422

Merged
merged 2 commits into from
Dec 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,13 @@ The benchmark results are computed with Augraphy 8.2 and Tobacco3482 dataset (re
|ColorPaper | 4.83| 105.66| 4.99| 105.66| 4.96| 105.66| 4.96| 105.66|
|ColorShift | 0.79| 126.94| 0.82| 126.94| 0.77| 126.94| 0.76| 126.94|
|DelaunayTessellation| 0.11| 60.41| 0.12| 60.29| 0.11| 60.36| 0.10| 60.37|
|DepthSimulatedBlur | 0.01| 76.08| 0.01| 76.08| 0.01| 76.08| 0.01| 76.08|
|DirtyDrum | 0.83| 482.51| 0.94| 481.56| 0.90| 481.68| 0.92| 481.52|
|DirtyRollers | 1.47| 249.55| 1.77| 249.43| 1.80| 249.43| 1.78| 249.43|
|DirtyScreen | 0.78| 435.36| 0.78| 435.36| 0.77| 435.36| 0.77| 435.36|
|Dithering | 3.39| 126.82| 3.66| 126.80| 3.66| 126.81| 3.79| 126.80|
|DotMatrix | 0.53| 80.75| 0.57| 80.52| 0.57| 80.52| 0.57| 80.52|
|DoubleExposure | 1.64| 63.40| 1.67| 63.40| 1.62| 63.40| 1.65| 63.40|
|Faxify | 1.37| 138.34| 1.43| 141.28| 1.41| 136.95| 1.27| 149.24|
|Folding | 3.18| 57.50| 1.24| 60.40| 3.44| 57.60| 3.55| 57.20|
|Gamma | 29.26| 25.36| 26.90| 25.36| 28.23| 25.36| 32.03| 25.36|
Expand All @@ -144,14 +147,17 @@ The benchmark results are computed with Augraphy 8.2 and Tobacco3482 dataset (re
|InkColorSwap | 3.47| 51.99| 3.58| 51.99| 3.51| 51.99| 3.61| 51.99|
|InkMottling | 5.41| 55.99| 5.47| 55.99| 5.49| 55.99| 5.39| 55.99|
|InkShifter | 0.17| 426.86| 0.15| 426.43| 0.17| 426.78| 0.17| 426.58|
|LCDScreenPattern | 2.14| 494.09| 2.12| 493.62| 2.14| 494.74| 2.13| 496.46|
|Jpeg | 5.55| 25.87| 5.60| 25.86| 5.52| 25.87| 5.66| 25.87|
|LensFlare | 0.02| 405.97| 0.01| 405.82| 0.01| 405.82| 0.01| 405.82|
|Letterpress | 0.35| 135.71| 0.33| 140.72| 0.34| 137.25| 0.34| 136.31|
|LightingGradient | 0.37| 638.31| 0.38| 638.30| 0.39| 638.30| 0.40| 638.30|
|LinesDegradation | 1.28| 174.76| 1.27| 174.93| 1.28| 174.92| 1.31| 174.59|
|LowInkPeriodicLines | 5.17| 12.75| 5.26| 12.75| 5.56| 12.75| 5.10| 12.75|
|LowInkRandomLines | 91.52| 12.75| 86.12| 12.75| 87.58| 12.75| 98.28| 12.75|
|LowLightNoise | 0.27| 481.95| 0.28| 481.95| 0.27| 481.95| 0.27| 481.95|
|Markup | 2.33| 161.88| 2.41| 158.13| 2.58| 146.27| 2.60| 147.53|
|Moire | 0.97| 575.74| 1.03| 575.57| 1.05| 575.57| 1.05| 575.57|
|NoiseTexturize | 0.83| 249.36| 0.85| 249.36| 0.80| 249.36| 0.82| 249.36|
|NoisyLines | 0.89| 446.65| 0.83| 448.43| 0.86| 447.88| 0.85| 448.52|
|PageBorder | 0.49| 193.95| 0.49| 188.46| 0.48| 188.30| 0.49| 192.04|
Expand Down
2 changes: 2 additions & 0 deletions augraphy/augmentations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
from augraphy.augmentations.sectionshift import SectionShift
from augraphy.augmentations.shadowcast import ShadowCast
from augraphy.augmentations.squish import Squish
from augraphy.augmentations.stains import Stains
from augraphy.augmentations.subtlenoise import SubtleNoise
from augraphy.augmentations.voronoi import VoronoiTessellation
from augraphy.augmentations.watermark import WaterMark
Expand Down Expand Up @@ -97,6 +98,7 @@
"SectionShift",
"ShadowCast",
"Squish",
"Stains",
"SubtleNoise",
"VoronoiTessellation",
"WaterMark",
Expand Down
108 changes: 108 additions & 0 deletions augraphy/augmentations/stains.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import random

import cv2
import numpy as np

from augraphy.base.augmentation import Augmentation
from augraphy.utilities.overlaybuilder import OverlayBuilder
from augraphy.utilities.texturegenerator import TextureGenerator


class Stains(Augmentation):
"""Creates a stains texture and the stains texture is blended into the input image by using OverlayBuilder.


:param stains_type: Types of stains. Use "random" for random stains effect.
Select from "rough_stains", "fine_stains", "severe_stains", "light_stains".
:type stains_type: tuple, optional
:param stains_blend_method: The blending method to blend stains texture into the input image.
:type stains_blend_method: string, optional
:param stains_blend_alpha: The blending alpha value for blending method with the usage of alpha.
:type stains_blend_alpha: float, optional
:param p: The probability this Augmentation will be applied.
:type p: float, optional

"""

def __init__(
self,
stains_type="random",
stains_blend_method="darken",
stains_blend_alpha=0.5,
p=1,
):
"""Constructor method"""
super().__init__(p=p)
self.stains_type = stains_type
self.stains_blend_method = stains_blend_method
self.stains_blend_alpha = stains_blend_alpha

# Constructs a string representation of this Augmentation.
def __repr__(self):
return f"stains(stains_type={self.stains_type}, stains_blend_method={self.stains_blend_method}, stains_blend_alpha={self.stains_blend_alpha}, p={self.p})"

# Applies the Augmentation to input data.
def __call__(self, image, layer=None, mask=None, keypoints=None, bounding_boxes=None, force=False):
if force or self.should_run():
image = image.copy()

# convert and make sure image is color image
has_alpha = 0
if len(image.shape) > 2:
is_gray = 0
if image.shape[2] == 4:
has_alpha = 1
image, image_alpha = image[:, :, :3], image[:, :, 3]
else:
is_gray = 1
image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)

ysize, xsize = image.shape[:2]

stains = ["rough_stains", "fine_stains", "severe_stains", "light_stains"]
if self.stains_type not in stains:
stains_type = random.choice(stains)
else:
stains_type = self.stains_type

# generator to create stains
stains_generator = TextureGenerator()

# generate stains
image_stains = stains_generator(
texture_type=stains_type,
texture_width=xsize,
texture_height=ysize,
quilt_texture=0,
)

# blend points image into input again
ob = OverlayBuilder(
self.stains_blend_method,
image_stains,
image,
1,
(1, 1),
"center",
0,
self.stains_blend_alpha,
)
image_output = ob.build_overlay()

# return image follows the input image color channel
if is_gray:
image_output = cv2.cvtColor(image_output, cv2.COLOR_BGR2GRAY)
if has_alpha:
image_output = np.dstack((image_output, image_alpha))

# check for additional output of mask, keypoints and bounding boxes
outputs_extra = []
if mask is not None or keypoints is not None or bounding_boxes is not None:
outputs_extra = [mask, keypoints, bounding_boxes]

# returns additional mask, keypoints and bounding boxes if there is additional input
if outputs_extra:
# returns in the format of [image, mask, keypoints, bounding_boxes]
return [image_output] + outputs_extra
else:
return image_output
6 changes: 6 additions & 0 deletions benchmark/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ python run_benchmarks.py --folder_path folder_path_with_images
|ColorPaper | 4.83| 105.66| 4.99| 105.66| 4.96| 105.66| 4.96| 105.66|
|ColorShift | 0.79| 126.94| 0.82| 126.94| 0.77| 126.94| 0.76| 126.94|
|DelaunayTessellation| 0.11| 60.41| 0.12| 60.29| 0.11| 60.36| 0.10| 60.37|
|DepthSimulatedBlur | 0.01| 76.08| 0.01| 76.08| 0.01| 76.08| 0.01| 76.08|
|DirtyDrum | 0.83| 482.51| 0.94| 481.56| 0.90| 481.68| 0.92| 481.52|
|DirtyRollers | 1.47| 249.55| 1.77| 249.43| 1.80| 249.43| 1.78| 249.43|
|DirtyScreen | 0.78| 435.36| 0.78| 435.36| 0.77| 435.36| 0.77| 435.36|
|Dithering | 3.39| 126.82| 3.66| 126.80| 3.66| 126.81| 3.79| 126.80|
|DotMatrix | 0.53| 80.75| 0.57| 80.52| 0.57| 80.52| 0.57| 80.52|
|DoubleExposure | 1.64| 63.40| 1.67| 63.40| 1.62| 63.40| 1.65| 63.40|
|Faxify | 1.37| 138.34| 1.43| 141.28| 1.41| 136.95| 1.27| 149.24|
|Folding | 3.18| 57.50| 1.24| 60.40| 3.44| 57.60| 3.55| 57.20|
|Gamma | 29.26| 25.36| 26.90| 25.36| 28.23| 25.36| 32.03| 25.36|
Expand All @@ -31,14 +34,17 @@ python run_benchmarks.py --folder_path folder_path_with_images
|InkColorSwap | 3.47| 51.99| 3.58| 51.99| 3.51| 51.99| 3.61| 51.99|
|InkMottling | 5.41| 55.99| 5.47| 55.99| 5.49| 55.99| 5.39| 55.99|
|InkShifter | 0.17| 426.86| 0.15| 426.43| 0.17| 426.78| 0.17| 426.58|
|LCDScreenPattern | 2.14| 494.09| 2.12| 493.62| 2.14| 494.74| 2.13| 496.46|
|Jpeg | 5.55| 25.87| 5.60| 25.86| 5.52| 25.87| 5.66| 25.87|
|LensFlare | 0.02| 405.97| 0.01| 405.82| 0.01| 405.82| 0.01| 405.82|
|Letterpress | 0.35| 135.71| 0.33| 140.72| 0.34| 137.25| 0.34| 136.31|
|LightingGradient | 0.37| 638.31| 0.38| 638.30| 0.39| 638.30| 0.40| 638.30|
|LinesDegradation | 1.28| 174.76| 1.27| 174.93| 1.28| 174.92| 1.31| 174.59|
|LowInkPeriodicLines | 5.17| 12.75| 5.26| 12.75| 5.56| 12.75| 5.10| 12.75|
|LowInkRandomLines | 91.52| 12.75| 86.12| 12.75| 87.58| 12.75| 98.28| 12.75|
|LowLightNoise | 0.27| 481.95| 0.28| 481.95| 0.27| 481.95| 0.27| 481.95|
|Markup | 2.33| 161.88| 2.41| 158.13| 2.58| 146.27| 2.60| 147.53|
|Moire | 0.97| 575.74| 1.03| 575.57| 1.05| 575.57| 1.05| 575.57|
|NoiseTexturize | 0.83| 249.36| 0.85| 249.36| 0.80| 249.36| 0.82| 249.36|
|NoisyLines | 0.89| 446.65| 0.83| 448.43| 0.86| 447.88| 0.85| 448.52|
|PageBorder | 0.49| 193.95| 0.49| 188.46| 0.48| 188.30| 0.49| 192.04|
Expand Down
7 changes: 7 additions & 0 deletions benchmark/run_benchmarks.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,10 +290,13 @@ def main(folder_path):
ColorPaper,
ColorShift,
DelaunayTessellation,
DepthSimulatedBlur,
DirtyDrum,
DirtyRollers,
DirtyScreen,
Dithering,
DotMatrix,
DoubleExposure,
Faxify,
Folding,
Gamma,
Expand All @@ -304,14 +307,17 @@ def main(folder_path):
InkColorSwap,
InkMottling,
InkShifter,
LCDScreenPattern,
Jpeg,
LensFlare,
Letterpress,
LightingGradient,
LinesDegradation,
LowInkPeriodicLines,
LowInkRandomLines,
LowLightNoise,
Markup,
Moire,
NoiseTexturize,
NoisyLines,
PageBorder,
Expand All @@ -321,6 +327,7 @@ def main(folder_path):
SectionShift,
ShadowCast,
Squish,
Stains,
SubtleNoise,
VoronoiTessellation,
WaterMark,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 66 additions & 0 deletions doc/source/augmentations/stains.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
******
Stains
******

.. autoclass:: augraphy.augmentations.stains.Stains
:members:
:undoc-members:
:show-inheritance:

--------
Overview
--------
The Stains augmentation creates a stains texture and the stains texture is blended into the input image by using OverlayBuilder.


Initially, a clean image with single line of text is created.

Code example:

::

# import libraries
import cv2
import numpy as np
from augraphy import *


# create a clean image with single line of text
image = np.full((500, 1500,3), 250, dtype="uint8")
cv2.putText(
image,
"Lorem ipsum dolor sit amet, consectetur adipiscing elit",
(80, 250),
cv2.FONT_HERSHEY_SIMPLEX,
1.5,
0,
3,
)

cv2.imshow("Input image", image)

Clean image:

.. figure:: augmentations/input.png

---------
Example 1
---------
In this example, a Stains augmentation instance is initialized and the stains type is set to severe stains (stains_type="severe_stains"). The method to blend stains texture into image is set to darken (stains_blend_method="darken").


Code example:

::

stains = Stains(stains_type="severe_stains",
stains_blend_method="darken",
)

img_stains = stains(image)

cv2.imshow("stains", img_stains)

Augmented image:

.. figure:: augmentations/stains/stains.png
Loading