Squashed commit of the following:
commit e5832a17356cebd43846c0542ce595bba5a8cdda
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Mon Feb 13 14:08:17 2023 +0100
reduce pytest parameter combinatons
commit a1e6c9e553545ed1fc4c017e67dddaa98fc2a1c9
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:56:16 2023 +0100
clear color map cache per pytest parameter combination
commit 21a9db25cdb55b967c664f5d129a9ac35aa1da0f
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:38:52 2023 +0100
Remove obsolete line
commit 90c367cc325dd3a4d3b8f7f37e06a79c30207867
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:38:05 2023 +0100
Refactoring: Move
commit 42d285e35b82ba0f36835eff6ff70c50bd80d20c
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:33:44 2023 +0100
Refactoring: Move
Move content generator into its own module
commit ddc92461d7442e08921408707ada6963f555f708
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:29:59 2023 +0100
Refactoring: Move
Move remaining segment generation functions into segments module
commit d2cb78d38f47a8c705a82dd725e24c0540a29710
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:27:26 2023 +0100
Refactoring: Move
Move zipmap and evert_nth into utils module
commit 9c401a977ce0749463cb2af509f412007f37a084
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:26:01 2023 +0100
Refactoring: Move
Move rectangle shrinking logic into new morphing module
commit b77951d4feb1e5dacdb32f0d36a399f6f94b2293
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:22:15 2023 +0100
Refactoring: Move
Move segment generation functions into their own module
commit c7b224a98a355f93653a0d576a10fbd2507ed1d8
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:14:54 2023 +0100
Refactoring: Move
Move cell class into its own module
commit f0072b0852f34f0448d467fc4993eee3a23a6c5b
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:12:18 2023 +0100
Refactoring: Move
Move table generation related code into new table module
commit 9fd87aff8ea69404959056b3d58c7f8856527c83
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:07:36 2023 +0100
Refactoring: Move
- Move random plot into its own module
- Move geometric predicates into their own module
commit 6728642a4fc07ec9c47db99efe12981c18f95ee5
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:59:54 2023 +0100
Refactoring: Move
Mode random helper functions
commit cc86a79ac7bc47e5ddb68e5c95327eebc97041d9
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:33:51 2023 +0100
Refactoring: Move
Move text block generator module into text module
commit 160d5b3473d7e4f6f6dbb8fcf51cf554d6b54543
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:29:29 2023 +0100
Remove unused code
commit 7b2f921472bb47b5c5d7848393ae471664eab583
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:28:17 2023 +0100
Refactoring: Move
Move text block generators into their own module
commit e258df899f4be39beec4a0bfc01eaea105218adb
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:24:54 2023 +0100
Refactoring: Move
Move text block into its own module
commit cef97b33f920488857c308e6ebcbc5a309de4b20
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:20:30 2023 +0100
Refactoring: Move
Move page partitioners into partitioner module
commit a54ccb2fdf44595720718fef44d5d3b1b8cbfe0a
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:15:40 2023 +0100
Refactoring: Move
Move text generation funtions into their own module
commit 1de938f2faa50cb805d7ebea3075c1d6d969d254
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:07:33 2023 +0100
Refactoring: Move
Move font related functions into font module
commit de9b3bad93d91b2d1820b59403fc357e243238e6
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:05:47 2023 +0100
Refactoring: Move
Move font picker into new font module
commit 9480d58a8a77b3feb7206cb1b7ac5c8a25516b39
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:59:31 2023 +0100
Refactoring: Move
Move line formatters into their own module
commit cc0094d3f73b258a0b89353981529e7fa6978b53
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:54:08 2023 +0100
Refactoring: Move
Move random content rectangle into its own module
commit 93a52080df8f5aa39b3b29f2c9a8dcbc8d72ad9d
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:52:57 2023 +0100
Remove unused code
commit 4ec3429dec932cadd828376610950b8ad84a51f4
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:51:03 2023 +0100
Refactoring: Move
Move page partitioner into its own module
commit bdcb2f1bef36357ea048c4f00b9dccfa25b13bd9
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:42:55 2023 +0100
Refactoring: Move
commit 845d1691949dcba049737af29fcee735825ecb8f
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:39:39 2023 +0100
Refactoring
commit 56c10490b965ccf3ca81aa9ba0403d9068871688
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:36:21 2023 +0100
Refactoring
commit 740a9cb3c25710a46452fa28dbef011daa03d6ed
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:33:32 2023 +0100
Refactoring
commit b3cf3e44548c71e7eff90e94ce8ce671a0d8f343
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:29:03 2023 +0100
Refactoring
Add fixture for page partitioner
commit 2fb450943e74d0a2a49ca0e20c9507d0230e4373
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:25:50 2023 +0100
Refactoring: Move
commit fd76933b5ac1fbab1b508ef1f3f199d04189cf81
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:16:16 2023 +0100
Refactoring: Move
Move image operations such as blurring into their own module.
commit 809590054315266286c75fb0ef2f81b506aaf20c
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:10:48 2023 +0100
Fix effectless bug
commit d42f053c81105e3144fcc54a7c6e924c777b3665
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 13:22:16 2023 +0100
Refactoring: Re-order
commit 04a617b9df0ee62e73f87508c8b09c4d3817a6e3
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 13:19:25 2023 +0100
Refactoring
Move content rectangle base class
267 lines
5.7 KiB
Python
267 lines
5.7 KiB
Python
import sys
|
|
from typing import Tuple, Iterable, List
|
|
|
|
import blend_modes
|
|
import numpy as np
|
|
import pytest
|
|
from PIL import Image, ImageEnhance
|
|
from PIL.Image import Transpose
|
|
from funcy import (
|
|
juxt,
|
|
compose,
|
|
identity,
|
|
)
|
|
from loguru import logger
|
|
|
|
from cv_analysis.locations import TEST_PAGE_TEXTURES_DIR
|
|
from cv_analysis.utils.conversion import normalize_image_format_to_array, normalize_image_format_to_pil
|
|
from cv_analysis.utils.image_operations import blur, sharpen, overlay, superimpose
|
|
from cv_analysis.utils.rectangle import Rectangle
|
|
from synthesis.content_generator import ContentGenerator
|
|
from synthesis.partitioner.two_column import TwoColumnPagePartitioner
|
|
from synthesis.random import rnd
|
|
from synthesis.segment.table.table import paste_contents
|
|
|
|
logger.remove()
|
|
logger.add(sys.stderr, level="INFO")
|
|
|
|
|
|
@pytest.fixture(
|
|
params=[
|
|
# "rough_grain",
|
|
# "plain",
|
|
# "digital",
|
|
"crumpled",
|
|
]
|
|
)
|
|
def base_texture(request, size):
|
|
texture = Image.open(TEST_PAGE_TEXTURES_DIR / (request.param + ".jpg"))
|
|
texture = texture.resize(size)
|
|
return texture
|
|
|
|
|
|
@pytest.fixture(
|
|
params=[
|
|
# "portrait",
|
|
"landscape",
|
|
]
|
|
)
|
|
def orientation(request):
|
|
return request.param
|
|
|
|
|
|
@pytest.fixture(
|
|
params=[
|
|
# 30,
|
|
100,
|
|
]
|
|
)
|
|
def dpi(request):
|
|
return request.param
|
|
|
|
|
|
@pytest.fixture(
|
|
params=[
|
|
# "brown",
|
|
"sepia",
|
|
# "gray",
|
|
# "white",
|
|
# "light_red",
|
|
# "light_blue",
|
|
]
|
|
)
|
|
def color_name(request):
|
|
return request.param
|
|
|
|
|
|
@pytest.fixture(
|
|
params=[
|
|
# "smooth",
|
|
# "coarse",
|
|
"neutral",
|
|
]
|
|
)
|
|
def texture_name(request):
|
|
return request.param
|
|
|
|
|
|
@pytest.fixture(
|
|
params=[
|
|
# 30,
|
|
70,
|
|
# 150,
|
|
]
|
|
)
|
|
def color_intensity(request):
|
|
return request.param
|
|
|
|
|
|
def random_flip(image):
|
|
if rnd.choice([True, False]):
|
|
image = image.transpose(Transpose.FLIP_LEFT_RIGHT)
|
|
if rnd.choice([True, False]):
|
|
image = image.transpose(Transpose.FLIP_TOP_BOTTOM)
|
|
return image
|
|
|
|
|
|
@pytest.fixture
|
|
def color(color_name):
|
|
return {
|
|
"brown": "#7d6c5b",
|
|
"sepia": "#b8af88",
|
|
"gray": "#9c9c9c",
|
|
"white": "#ffffff",
|
|
"light_red": "#d68c8b",
|
|
"light_blue": "#8bd6d6",
|
|
}[color_name]
|
|
|
|
|
|
@pytest.fixture
|
|
def texture_fn(texture_name, size):
|
|
if texture_name == "smooth":
|
|
fn = blur
|
|
elif texture_name == "coarse":
|
|
fn = compose(overlay, juxt(blur, sharpen))
|
|
else:
|
|
fn = identity
|
|
|
|
return normalize_image_function(fn)
|
|
|
|
|
|
def normalize_image_function(func):
|
|
def inner(image):
|
|
image = normalize_image_format_to_array(image)
|
|
image = func(image)
|
|
image = normalize_image_format_to_pil(image)
|
|
return image
|
|
|
|
return inner
|
|
|
|
|
|
@pytest.fixture
|
|
def texture(tinted_blank_page, base_texture):
|
|
texture = superimpose(base_texture, tinted_blank_page)
|
|
return texture
|
|
|
|
|
|
@pytest.fixture
|
|
def tinted_blank_page(size, color, color_intensity):
|
|
tinted_page = Image.new("RGBA", size, color)
|
|
tinted_page.putalpha(color_intensity)
|
|
return tinted_page
|
|
|
|
|
|
@pytest.fixture
|
|
def blank_page(size, color, color_intensity):
|
|
page = Image.new("RGBA", size, color=(255, 255, 255, 0))
|
|
return page
|
|
|
|
|
|
@pytest.fixture
|
|
def size(dpi, orientation):
|
|
if orientation == "portrait":
|
|
size = (8.5 * dpi, 11 * dpi)
|
|
elif orientation == "landscape":
|
|
size = (11 * dpi, 8.5 * dpi)
|
|
else:
|
|
raise ValueError(f"Unknown orientation: {orientation}")
|
|
size = tuple(map(int, size))
|
|
return size
|
|
|
|
|
|
@pytest.fixture(
|
|
params=[
|
|
TwoColumnPagePartitioner,
|
|
# RandomPagePartitioner
|
|
]
|
|
)
|
|
def page_partitioner(request):
|
|
return request.param()
|
|
|
|
|
|
@pytest.fixture
|
|
def boxes(page_partitioner, blank_page):
|
|
boxes = page_partitioner(blank_page)
|
|
return boxes
|
|
|
|
|
|
@pytest.fixture
|
|
def prepared_texture(texture, texture_fn):
|
|
texture = random_flip(texture)
|
|
texture = texture_fn(texture)
|
|
return texture
|
|
|
|
|
|
@pytest.fixture
|
|
def content_boxes(boxes):
|
|
content_generator = ContentGenerator()
|
|
content_boxes = content_generator(boxes)
|
|
return content_boxes
|
|
|
|
|
|
@pytest.fixture
|
|
def page_with_opaque_content(
|
|
blank_page, tinted_blank_page, prepared_texture, content_boxes
|
|
) -> Tuple[np.ndarray, Iterable[Rectangle]]:
|
|
"""Creates a page with content"""
|
|
page = paste_contents(prepared_texture, content_boxes)
|
|
|
|
return page, content_boxes
|
|
|
|
|
|
@pytest.fixture
|
|
def page_with_translucent_content(
|
|
blank_page, tinted_blank_page, prepared_texture, content_boxes
|
|
) -> Tuple[np.ndarray, List[Rectangle]]:
|
|
"""Creates a page with content"""
|
|
page_content = paste_contents(blank_page, content_boxes)
|
|
page = blend_by_multiply(page_content, prepared_texture)
|
|
|
|
return page, content_boxes
|
|
|
|
|
|
def blend_by_multiply(page_content, texture):
|
|
def to_array(image: Image) -> np.ndarray:
|
|
return np.array(image).astype(np.float32)
|
|
|
|
texture.putalpha(255)
|
|
page_content.putalpha(255)
|
|
factor = 1.2
|
|
enhancer = ImageEnhance.Contrast(texture)
|
|
texture = enhancer.enhance(factor)
|
|
|
|
page = blend_modes.multiply(
|
|
*map(
|
|
to_array,
|
|
(
|
|
page_content,
|
|
texture,
|
|
),
|
|
),
|
|
opacity=1,
|
|
).astype(np.uint8)
|
|
return page
|
|
|
|
|
|
@pytest.fixture(scope="function")
|
|
def random_seeding():
|
|
from synthesis.segment.plot import pick_colormap
|
|
|
|
seed = str(rnd.randint(0, 2**32 - 1))
|
|
logger.info(f"Random seed: {seed}")
|
|
rnd.seed(seed)
|
|
pick_colormap.cache_clear()
|
|
|
|
|
|
@pytest.fixture
|
|
def page_with_content(
|
|
random_seeding,
|
|
page_with_translucent_content,
|
|
# page_with_opaque_content,
|
|
) -> np.ndarray:
|
|
|
|
page, boxes = page_with_translucent_content
|
|
# page, boxes = page_with_opaque_content
|
|
|
|
return page, boxes
|