Skip to content

Commit

Permalink
Added independent parser for image
Browse files Browse the repository at this point in the history
  • Loading branch information
ppizarror committed Feb 27, 2024
1 parent e30867c commit ca85364
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 37 deletions.
2 changes: 1 addition & 1 deletion MLStructFP/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
__description__ = 'Machine learning structural floor plan dataset'
__keywords__ = ['ml', 'ai', 'dataset', 'calc', 'matrix analysis', 'cnn', 'structural analysis', 'structural design']
__email__ = 'pablo@ppizarror.com'
__version__ = '0.5.0'
__version__ = '0.5.1'

# URL
__url__ = 'https://github.com/MLSTRUCT/MLSTRUCT-FP'
Expand Down
92 changes: 56 additions & 36 deletions MLStructFP/db/image/_rect_photo.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
import math
import numpy as np
import os
import time

if TYPE_CHECKING:
from MLStructFP.db._c_rect import Rect
from MLStructFP.db._floor import Floor

IMAGES_TO_CLEAR_MEMORY = 10000
MAX_STORED_FLOORS = 2
IMAGES_TO_CLEAR_MEMORY: int = 10000
MAX_STORED_FLOORS: int = 2


def _im_show(title: str, img: 'np.ndarray') -> None:
Expand Down Expand Up @@ -254,36 +255,32 @@ def __init__(
self._floor_images = {}
self._floor_center_d = {}

def _get_floor_image(self, floor: 'Floor') -> Tuple['np.ndarray', 'GeomPoint2D']:
def parse_image(self, ip: str, mutator_scale_x: float = 1, mutator_scale_y: float = 1,
mutator_angle: float = 0, verbose: bool = False) -> Tuple['np.ndarray', 'GeomPoint2D']:
"""
Get floor image numpy class.
:param floor: Floor object
:return: Image array
Process image.
:param ip: Image path
:param mutator_scale_x: Mutator scale on x-axis
:param mutator_scale_y: Mutator scale on y-axis
:param mutator_angle: Mutator angle
:param verbose: Verbose mode
:return: Parsed image, center
"""
floor_hash = f'{floor.id}{floor.mutator_angle}{floor.mutator_scale_x}{floor.mutator_scale_y}'
if floor_hash in self._floor_images.keys():
return self._floor_images[floor_hash], self._floor_center_d[floor_hash]
ip = floor.image_path
if self._verbose:
print(f'Loading image: {ip}')

# Make default empty color
pixels: 'np.ndarray'
if self._empty_color >= 0:
image: 'np.ndarray' = cv2.imread(ip, cv2.IMREAD_UNCHANGED)
if len(image.shape) == 3 and image.shape[2] == 4:
# Make mask of where the transparent bits are
trans_mask = image[:, :, 3] == 0

# Replace areas of transparency with white and not transparent
image[trans_mask] = [self._empty_color, self._empty_color, self._empty_color, 255]
pixels = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)
else:
pixels = image
else:
pixels = cv2.imread(ip)

# Turn all black lines to white
if len(pixels.shape) == 3 and np.max(pixels) == 0:
image = cv2.imread(ip, cv2.IMREAD_UNCHANGED)
Expand All @@ -298,37 +295,58 @@ def _get_floor_image(self, floor: 'Floor') -> Tuple['np.ndarray', 'GeomPoint2D']
pixels = np.stack([pixels, pixels, pixels], axis=-1)

# Flip image
if floor.mutator_scale_x < 0:
pixels = cv2.flip(pixels, 1)
if floor.mutator_scale_y < 0:
pixels = cv2.flip(pixels, 0)

# Transform image due to mutators
sy, sx, _ = pixels.shape
sx = int(math.ceil(abs(sx * floor.mutator_scale_x)))
sy = int(math.ceil(abs(sy * floor.mutator_scale_y)))
pixels = cv2.resize(pixels, (sx, sy))
if mutator_scale_x != 1 or mutator_scale_y != 1:
if mutator_scale_x < 0:
pixels = cv2.flip(pixels, 1)
if mutator_scale_y < 0:
pixels = cv2.flip(pixels, 0)

# Transform image due to mutators
sy, sx, _ = pixels.shape
sx = int(math.ceil(abs(sx * mutator_scale_x)))
sy = int(math.ceil(abs(sy * mutator_scale_y)))
pixels = cv2.resize(pixels, (sx, sy))

source_pixels: 'np.ndarray' = pixels
if self._verbose:
if verbose:
source_pixels = pixels.copy()
cy, cx = pixels.shape[:2] # Source center pixel
pc = GeomPoint2D(cx, cy)
pixels = _rotate_image(pixels, floor.mutator_angle)
if self._verbose:
pixels = _rotate_image(pixels, mutator_angle)
if verbose:
_show_img([source_pixels, pixels])

return pixels, GeomPoint2D(cx, cy)

def _get_floor_image(self, floor: 'Floor') -> Tuple['np.ndarray', 'GeomPoint2D']:
"""
Get floor image numpy class.
:param floor: Floor object
:return: Image array
"""
floor_hash = f'{floor.id}{floor.mutator_angle}{floor.mutator_scale_x}{floor.mutator_scale_y}'
if floor_hash in self._floor_images.keys():
return self._floor_images[floor_hash], self._floor_center_d[floor_hash]
ip = floor.image_path

if self._verbose:
print(f'Loading image: {ip}')
pixels, pc = self.parse_image(ip, floor.mutator_scale_x, floor.mutator_scale_y,
floor.mutator_angle, self._verbose)

# Store
self._floor_images[floor_hash] = pixels
self._floor_center_d[floor_hash] = pc
# print('Storing', self.name, floor_hash)
if self._verbose:
print('Storing', ip, floor_hash)

if len(self._floor_images) >= MAX_STORED_FLOORS:
key_iter = iter(self._floor_images.keys())
k1: str = next(key_iter)
del self._floor_images[k1] # Remove
del self._floor_center_d[k1]
# print('Removing', self.name, k1)
if self._verbose:
print('Removing', ip, k1)

return pixels, pc

Expand Down Expand Up @@ -487,6 +505,7 @@ def _get_crop_image(
:param rect: Rect object from the image
:return: Cropped image
"""
t = time.time()
x = [x1, x2]
y = [y1, y2]
x1, x2 = min(x), max(x)
Expand Down Expand Up @@ -529,8 +548,8 @@ def _get_crop_image(
"""
out_rz: 'np.ndarray' = cv2.resize(out_img, (self._image_size, self._image_size),
interpolation=cv2.INTER_AREA)
# if self._verbose:
# print('Process finished in {0} seconds'.format(int(time.time() - t)))
if self._verbose:
print('Process finished in {0} seconds'.format(int(time.time() - t)))
im = out_rz.astype(TYPE_IMAGE)
_alpha = -5
if self._empty_color == 0:
Expand All @@ -542,8 +561,9 @@ def _get_crop_image(
# Apply kernel
image_kernel = cv2.filter2D(adjusted, -1, self._kernel)

# _show_img([im, adjusted, cv2.convertScaleAbs(im, alpha=2 * _alpha, beta=0), 255 - adjusted, image_kernel],
# ['Base', 'Adjusted', 'Adjusted2', 'Negative adjusted', 'By kernel'])
if self._verbose:
_show_img([im, adjusted, cv2.convertScaleAbs(im, alpha=2 * _alpha, beta=0), 255 - adjusted, image_kernel],
['Base', 'Adjusted', 'Adjusted2', 'Negative adjusted', 'By kernel'])

return image_kernel

Expand Down

0 comments on commit ca85364

Please sign in to comment.