refactor: rename package from image_panel_border_cleaner to manga_panel_processor
Browse files- app.py +1 -1
- image_processing/panel.py +3 -67
- requirements.txt +1 -1
app.py
CHANGED
|
@@ -15,7 +15,7 @@ import shutil
|
|
| 15 |
from tqdm import tqdm
|
| 16 |
|
| 17 |
from image_processing.panel import generate_panel_blocks, generate_panel_blocks_by_ai
|
| 18 |
-
from
|
| 19 |
|
| 20 |
# --- UI Description ---
|
| 21 |
DESCRIPTION = """
|
|
|
|
| 15 |
from tqdm import tqdm
|
| 16 |
|
| 17 |
from image_processing.panel import generate_panel_blocks, generate_panel_blocks_by_ai
|
| 18 |
+
from manga_panel_processor import remove_border
|
| 19 |
|
| 20 |
# --- UI Description ---
|
| 21 |
DESCRIPTION = """
|
image_processing/panel.py
CHANGED
|
@@ -7,6 +7,7 @@ from image_processing.image import is_contour_rectangular, apply_adaptive_thresh
|
|
| 7 |
from myutils.myutils import load_images, load_image
|
| 8 |
from tqdm import tqdm
|
| 9 |
from image_processing.model import model
|
|
|
|
| 10 |
|
| 11 |
class OutputMode:
|
| 12 |
BOUNDING = 'bounding'
|
|
@@ -308,71 +309,6 @@ def get_fallback_panels(
|
|
| 308 |
|
| 309 |
return panels
|
| 310 |
|
| 311 |
-
def _sort_items_by_reading_order(items: list, rtl_order: bool, image_height: int) -> list:
|
| 312 |
-
"""
|
| 313 |
-
Sorts contours or bounding boxes based on reading order (top-to-bottom, then LTR/RTL).
|
| 314 |
-
This function is robust against minor vertical misalignments by grouping items into rows.
|
| 315 |
-
|
| 316 |
-
Parameters:
|
| 317 |
-
- items: A list of contours (np.ndarray) or bounding boxes (tuple of x,y,w,h).
|
| 318 |
-
- rtl_order: If True, sort horizontally from right-to-left.
|
| 319 |
-
- image_height: The height of the original image, used for calculating tolerance.
|
| 320 |
-
|
| 321 |
-
Returns:
|
| 322 |
-
- A sorted list of the input items.
|
| 323 |
-
"""
|
| 324 |
-
if not items:
|
| 325 |
-
return []
|
| 326 |
-
|
| 327 |
-
# Unify items into a list of (item, bbox) tuples for consistent processing
|
| 328 |
-
item_bboxes = []
|
| 329 |
-
for item in items:
|
| 330 |
-
if isinstance(item, np.ndarray): # It's a contour
|
| 331 |
-
bbox = cv2.boundingRect(item)
|
| 332 |
-
else: # It's already a bbox tuple
|
| 333 |
-
bbox = item
|
| 334 |
-
item_bboxes.append((item, bbox))
|
| 335 |
-
|
| 336 |
-
# Initial sort by top y-coordinate
|
| 337 |
-
item_bboxes.sort(key=lambda x: x[1][1])
|
| 338 |
-
|
| 339 |
-
rows = []
|
| 340 |
-
current_row = []
|
| 341 |
-
if item_bboxes:
|
| 342 |
-
# Start the first row
|
| 343 |
-
current_row.append(item_bboxes[0])
|
| 344 |
-
first_item_in_row_bbox = item_bboxes[0][1]
|
| 345 |
-
|
| 346 |
-
# Define a dynamic tolerance based on the height of the first panel in a row.
|
| 347 |
-
# A panel can be considered in the same row if its top is not lower than
|
| 348 |
-
# the first panel's top + 30% of its height. This is a robust heuristic.
|
| 349 |
-
# We also add a minimum tolerance for very short panels.
|
| 350 |
-
y_tolerance = max(10, int(first_item_in_row_bbox[3] * 0.3))
|
| 351 |
-
|
| 352 |
-
for item, bbox in item_bboxes[1:]:
|
| 353 |
-
# If the current panel's y is within the tolerance of the current row's start y
|
| 354 |
-
if bbox[1] < first_item_in_row_bbox[1] + y_tolerance:
|
| 355 |
-
current_row.append((item, bbox))
|
| 356 |
-
else:
|
| 357 |
-
# Finish the current row
|
| 358 |
-
# Sort the completed row horizontally
|
| 359 |
-
current_row.sort(key=lambda x: -x[1][0] if rtl_order else x[1][0])
|
| 360 |
-
rows.append(current_row)
|
| 361 |
-
|
| 362 |
-
# Start a new row
|
| 363 |
-
current_row = [(item, bbox)]
|
| 364 |
-
first_item_in_row_bbox = bbox
|
| 365 |
-
y_tolerance = max(10, int(first_item_in_row_bbox[3] * 0.3))
|
| 366 |
-
|
| 367 |
-
# Add the last processed row
|
| 368 |
-
if current_row:
|
| 369 |
-
current_row.sort(key=lambda x: -x[1][0] if rtl_order else x[1][0])
|
| 370 |
-
rows.append(current_row)
|
| 371 |
-
|
| 372 |
-
# Flatten the rows and extract the original items in the correct order
|
| 373 |
-
sorted_items = [item for row in rows for item, bbox in row]
|
| 374 |
-
|
| 375 |
-
return sorted_items
|
| 376 |
|
| 377 |
def generate_panel_blocks(
|
| 378 |
image: np.ndarray,
|
|
@@ -404,7 +340,7 @@ def generate_panel_blocks(
|
|
| 404 |
# For RTL, we sort by x-coordinate in descending order (by negating it).
|
| 405 |
if contours:
|
| 406 |
image_height = image.shape[0]
|
| 407 |
-
contours =
|
| 408 |
|
| 409 |
def get_panels(contours):
|
| 410 |
panels = extract_panels(image, contours, mode=mode)
|
|
@@ -453,7 +389,7 @@ def generate_panel_blocks_by_ai(
|
|
| 453 |
# Bounding boxes are already (x, y, w, h), so we access coordinates directly.
|
| 454 |
if bounding_boxes:
|
| 455 |
image_height = image.shape[0]
|
| 456 |
-
bounding_boxes =
|
| 457 |
|
| 458 |
def get_panels(bounding_boxes):
|
| 459 |
panels = []
|
|
|
|
| 7 |
from myutils.myutils import load_images, load_image
|
| 8 |
from tqdm import tqdm
|
| 9 |
from image_processing.model import model
|
| 10 |
+
from manga_panel_processor import sort_panels_by_column_then_row
|
| 11 |
|
| 12 |
class OutputMode:
|
| 13 |
BOUNDING = 'bounding'
|
|
|
|
| 309 |
|
| 310 |
return panels
|
| 311 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 312 |
|
| 313 |
def generate_panel_blocks(
|
| 314 |
image: np.ndarray,
|
|
|
|
| 340 |
# For RTL, we sort by x-coordinate in descending order (by negating it).
|
| 341 |
if contours:
|
| 342 |
image_height = image.shape[0]
|
| 343 |
+
contours = sort_panels_by_column_then_row(contours, rtl_order)
|
| 344 |
|
| 345 |
def get_panels(contours):
|
| 346 |
panels = extract_panels(image, contours, mode=mode)
|
|
|
|
| 389 |
# Bounding boxes are already (x, y, w, h), so we access coordinates directly.
|
| 390 |
if bounding_boxes:
|
| 391 |
image_height = image.shape[0]
|
| 392 |
+
bounding_boxes = sort_panels_by_column_then_row(bounding_boxes, rtl_order)
|
| 393 |
|
| 394 |
def get_panels(bounding_boxes):
|
| 395 |
panels = []
|
requirements.txt
CHANGED
|
@@ -7,4 +7,4 @@ tqdm
|
|
| 7 |
torch
|
| 8 |
yolov5
|
| 9 |
|
| 10 |
-
git+https://github.com/avan06/
|
|
|
|
| 7 |
torch
|
| 8 |
yolov5
|
| 9 |
|
| 10 |
+
git+https://github.com/avan06/manga-panel-processor.git
|