jebin2 commited on
Commit
0622274
Β·
1 Parent(s): 74158ea

change row black

Browse files
comic_panel_extractor/panel_extractor.py CHANGED
@@ -35,7 +35,7 @@ class PanelExtractor:
35
  def __init__(self, config: Config):
36
  self.config = config
37
 
38
- def extract_panels(self, dilated_path: str, row_thresh: int = 20, col_thresh: int = 20, min_width_ratio: float = 0.1, min_height_ratio: float = 0.1, min_area_ratio: float = 0.01) -> Tuple[List[np.ndarray], List[PanelData]]:
39
  """Extract comic panels using black percentage scan."""
40
  dilated = cv2.imread(dilated_path, cv2.IMREAD_GRAYSCALE)
41
  original = cv2.imread(self.config.input_path)
@@ -46,7 +46,7 @@ class PanelExtractor:
46
  height, width = dilated.shape
47
 
48
  # Find row gutters and panel rows
49
- panel_rows = self._find_panel_rows(dilated, row_thresh)
50
 
51
  # Extract panels from each row
52
  all_panels = []
@@ -66,36 +66,104 @@ class PanelExtractor:
66
 
67
  return panel_images, panel_data, all_panel_path
68
 
69
- def _find_panel_rows(self, dilated: np.ndarray, row_thresh: int) -> List[Tuple[int, int]]:
70
- """Find panel rows by analyzing horizontal black percentages."""
71
  height, width = dilated.shape
 
 
72
  row_black_percentage = np.sum(dilated == 0, axis=1) / width * 100
73
-
74
- # Find row gutters
 
 
 
 
 
 
 
 
 
75
  row_gutters = []
76
- in_gutter = False
77
- for y, percent_black in enumerate(row_black_percentage):
78
- if percent_black >= row_thresh and not in_gutter:
79
- start_row = y
80
- in_gutter = True
81
- elif percent_black < row_thresh and in_gutter:
82
- end_row = y
83
- row_gutters.append((start_row, end_row))
84
- in_gutter = False
85
-
86
- # Convert gutters to panel rows
87
- panel_rows = []
88
- prev_end = 0
89
- for start, end in row_gutters:
90
- if start - prev_end > 10: # Minimum row height
91
- panel_rows.append((prev_end, start))
92
- prev_end = end
93
-
94
- if height - prev_end > 10:
95
- panel_rows.append((prev_end, height))
96
-
97
- return panel_rows
98
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  def _extract_panels_from_row(self, dilated: np.ndarray, y1: int, y2: int,
100
  col_thresh: int) -> List[Tuple[int, int, int, int]]:
101
  """Extract panels from a single row."""
 
35
  def __init__(self, config: Config):
36
  self.config = config
37
 
38
+ def extract_panels(self, dilated_path: str, row_thresh: int = 20, col_thresh: int = 20, min_width_ratio: float = 0.001, min_height_ratio: float = 0.001, min_area_ratio: float = 0) -> Tuple[List[np.ndarray], List[PanelData]]:
39
  """Extract comic panels using black percentage scan."""
40
  dilated = cv2.imread(dilated_path, cv2.IMREAD_GRAYSCALE)
41
  original = cv2.imread(self.config.input_path)
 
46
  height, width = dilated.shape
47
 
48
  # Find row gutters and panel rows
49
+ panel_rows = self._find_panel_rows(dilated, row_thresh, min_height_ratio)
50
 
51
  # Extract panels from each row
52
  all_panels = []
 
66
 
67
  return panel_images, panel_data, all_panel_path
68
 
69
+ def _find_panel_rows(self, dilated: np.ndarray, row_thresh: int, min_height_ratio: float) -> List[Tuple[int, int]]:
70
+ """Find panel rows where consecutive rows meet the threshold and height constraint."""
71
  height, width = dilated.shape
72
+
73
+ # Calculate black percentage for each row
74
  row_black_percentage = np.sum(dilated == 0, axis=1) / width * 100
75
+
76
+ # Find all rows meeting threshold
77
+ black_rows = [y for y, p in enumerate(row_black_percentage) if p >= row_thresh]
78
+
79
+ # Forcefully include first and last row
80
+ if 0 not in black_rows:
81
+ black_rows.insert(0, 0)
82
+ if (height - 1) not in black_rows:
83
+ black_rows.append(height - 1)
84
+
85
+ # Group consecutive rows into gutters
86
  row_gutters = []
87
+ if black_rows:
88
+ start_row = black_rows[0]
89
+ prev_row = black_rows[0]
90
+ for y in black_rows:
91
+ if y != start_row:
92
+ # Only extend if combined height meets min_height_ratio
93
+ combined_height = y - start_row + 1
94
+ if combined_height / height >= min_height_ratio:
95
+ prev_row = y
96
+ row_gutters.append((start_row, prev_row))
97
+ start_row = y
98
+
99
+ if start_row != prev_row:
100
+ row_gutters.append((start_row, prev_row)) # Add last gutter
101
+
102
+ print(f"βœ… Detected panel row gutters: {row_gutters}")
103
+
104
+ # ⚑ Draw detected rows on a color copy
105
+ visual = cv2.cvtColor(dilated, cv2.COLOR_GRAY2BGR)
106
+ for (y1, y2) in row_gutters:
107
+ cv2.line(visual, (0, y1), (width, y1), (0, 255, 0), thickness=5)
108
+ cv2.line(visual, (0, y2), (width, y2), (0, 0, 255), thickness=5)
109
+
110
+ # Save visualization
111
+ output_path = f"{self.config.output_folder}/row_gutters_visualization.jpg"
112
+ cv2.imwrite(output_path, visual)
113
+ print(f"πŸ“„ Saved row gutter visualization: {output_path}")
114
+
115
+ return row_gutters
116
+
117
+ def _find_panel_columns(self, dilated: np.ndarray, col_thresh: int, min_width_ratio: float) -> List[Tuple[int, int]]:
118
+ """
119
+ Find panel columns where consecutive columns meet the threshold and width constraint.
120
+ """
121
+ height, width = dilated.shape
122
+
123
+ # Calculate black percentage for each column
124
+ col_black_percentage = np.sum(dilated == 0, axis=0) / height * 100
125
+
126
+ # Find all columns meeting threshold
127
+ black_cols = [x for x, p in enumerate(col_black_percentage) if p >= col_thresh]
128
+
129
+ # Forcefully include first and last column
130
+ if 0 not in black_cols:
131
+ black_cols.insert(0, 0)
132
+ if (width - 1) not in black_cols:
133
+ black_cols.append(width - 1)
134
+
135
+ # Group consecutive columns into gutters
136
+ col_gutters = []
137
+ if black_cols:
138
+ start_col = black_cols[0]
139
+ prev_col = black_cols[0]
140
+ for x in black_cols:
141
+ if x != start_col:
142
+ # Only extend if combined width meets min_width_ratio
143
+ combined_width = x - start_col + 1
144
+ if combined_width / width >= min_width_ratio:
145
+ prev_col = x
146
+ col_gutters.append((start_col, prev_col))
147
+ start_col = x
148
+
149
+ if start_col != prev_col:
150
+ col_gutters.append((start_col, prev_col)) # Add last gutter
151
+
152
+ print(f"βœ… Detected panel column gutters: {col_gutters}")
153
+
154
+ # ⚑ Draw detected columns on a color copy
155
+ visual = cv2.cvtColor(dilated, cv2.COLOR_GRAY2BGR)
156
+ for (x1, x2) in col_gutters:
157
+ cv2.line(visual, (x1, 0), (x1, height), (255, 0, 0), thickness=5)
158
+ cv2.line(visual, (x2, 0), (x2, height), (0, 255, 255), thickness=5)
159
+
160
+ # Save visualization
161
+ output_path = f"{self.config.output_folder}/col_gutters_visualization.jpg"
162
+ cv2.imwrite(output_path, visual)
163
+ print(f"πŸ“„ Saved column gutter visualization: {output_path}")
164
+
165
+ return col_gutters
166
+
167
  def _extract_panels_from_row(self, dilated: np.ndarray, y1: int, y2: int,
168
  col_thresh: int) -> List[Tuple[int, int, int, int]]:
169
  """Extract panels from a single row."""