|
|
|
|
|
""" |
|
|
Developed by Nikhil Nageshwar Inturi |
|
|
|
|
|
This module provides ImageSplitter for splitting PNG images into |
|
|
equal-sized sub-images and saving them to an output directory. |
|
|
""" |
|
|
|
|
|
|
|
|
from pathlib import Path |
|
|
import numpy as np, cv2, logging |
|
|
from PIL import Image |
|
|
|
|
|
from utils.constants import setup_logging |
|
|
Image.MAX_IMAGE_PIXELS = None |
|
|
|
|
|
|
|
|
class ImageSplitter: |
|
|
""" |
|
|
Splits all PNG images in a source directory into sub-images of specified width and height. |
|
|
""" |
|
|
|
|
|
def __init__(self, source_dir: Path, output_dir: Path, sub_image_width: int, sub_image_height: int) -> None: |
|
|
self.source_dir = Path(source_dir) |
|
|
self.output_dir = Path(output_dir) |
|
|
self.sub_w = sub_image_width |
|
|
self.sub_h = sub_image_height |
|
|
self.logger = logging.getLogger(self.__class__.__name__) |
|
|
self._setup_output_directory() |
|
|
|
|
|
def _setup_output_directory(self) -> None: |
|
|
try: |
|
|
self.output_dir.mkdir(parents=True, exist_ok=True) |
|
|
self.logger.debug(f"Output directory ready: {self.output_dir}") |
|
|
except Exception as e: |
|
|
self.logger.error(f"Failed to create output directory {self.output_dir}: {e}") |
|
|
raise |
|
|
|
|
|
def split_all(self) -> None: |
|
|
""" |
|
|
Iterate over all PNG files in source_dir and split them. |
|
|
""" |
|
|
png_files = list(self.source_dir.glob("*.png")) |
|
|
if not png_files: |
|
|
self.logger.warning(f"No .png files found in {self.source_dir}") |
|
|
return |
|
|
|
|
|
for png_file in png_files: |
|
|
try: |
|
|
self.split_file(png_file) |
|
|
except Exception: |
|
|
self.logger.exception(f"Error splitting file: {png_file}") |
|
|
|
|
|
def split_file(self, png_path: Path) -> None: |
|
|
""" |
|
|
Split a single PNG image into sub-images. |
|
|
|
|
|
Args: |
|
|
png_path: Path to the input .png file. |
|
|
""" |
|
|
with Image.open(png_path) as pil_img: |
|
|
img = np.array(pil_img) |
|
|
self.logger.debug(f"Loaded {png_path.name} with shape {img.shape}") |
|
|
|
|
|
height, width = img.shape[:2] |
|
|
cols = (width + self.sub_w - 1) // self.sub_w |
|
|
rows = (height + self.sub_h - 1) // self.sub_h |
|
|
|
|
|
for row in range(rows): |
|
|
for col in range(cols): |
|
|
x0 = col * self.sub_w |
|
|
y0 = row * self.sub_h |
|
|
x1 = min(x0 + self.sub_w, width) |
|
|
y1 = min(y0 + self.sub_h, height) |
|
|
sub_img = img[y0:y1, x0:x1] |
|
|
|
|
|
output_name = f"{png_path.stem}_{row}_{col}.png" |
|
|
output_path = self.output_dir / output_name |
|
|
|
|
|
sub_img_bgr = cv2.cvtColor(sub_img, cv2.COLOR_RGB2BGR) |
|
|
success = cv2.imwrite(str(output_path), sub_img_bgr) |
|
|
if success: |
|
|
self.logger.info(f"Saved sub-image: {output_name}") |
|
|
else: |
|
|
self.logger.error(f"Failed to save sub-image: {output_name}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|