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
|