jebin2 commited on
Commit
e05ccab
·
1 Parent(s): 5ada1b3

made thin border

Browse files
.gitignore CHANGED
@@ -205,4 +205,7 @@ cython_debug/
205
  marimo/_static/
206
  marimo/_lsp/
207
  __marimo__/
208
- temp_dir
 
 
 
 
205
  marimo/_static/
206
  marimo/_lsp/
207
  __marimo__/
208
+ temp_dir
209
+ input.jpg
210
+ comic_panel_extractor/api_outputs/
211
+ temp.py
comic_panel_extractor/cli.py CHANGED
@@ -68,8 +68,6 @@ Examples:
68
  for key, value in config_data.items():
69
  if hasattr(config, key):
70
  setattr(config, key, value)
71
- if args.verbose:
72
- print(f"📄 Loaded configuration from: {args.config}")
73
  except Exception as e:
74
  print(f"⚠️ Warning: Could not load config file: {e}", file=sys.stderr)
75
 
 
68
  for key, value in config_data.items():
69
  if hasattr(config, key):
70
  setattr(config, key, value)
 
 
71
  except Exception as e:
72
  print(f"⚠️ Warning: Could not load config file: {e}", file=sys.stderr)
73
 
comic_panel_extractor/image_processor.py CHANGED
@@ -50,9 +50,40 @@ class ImageProcessor:
50
  cv2.imwrite(str(dilated_path), dilated)
51
 
52
  return str(gray_path), str(binary_path), str(dilated_path)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
  def clean_dilated_image(self, dilated_path: str,
55
- output_filename: str = "5_dilated_cleaned.jpg",
56
  max_neighbors: int = 2) -> str:
57
  """Clean dilated image by thinning thick borders."""
58
  dilated = cv2.imread(dilated_path, cv2.IMREAD_GRAYSCALE)
 
50
  cv2.imwrite(str(dilated_path), dilated)
51
 
52
  return str(gray_path), str(binary_path), str(dilated_path)
53
+
54
+ def thin_image_borders(self, processed_image_path: str, output_filename: str = "5_thin_border.jpg") -> str:
55
+ """
56
+ Clean dilated image by thinning thick borders and removing hanging clusters.
57
+ """
58
+ from skimage.morphology import skeletonize, remove_small_objects
59
+ from skimage.measure import label
60
+
61
+ # Load image
62
+ img = cv2.imread(processed_image_path, cv2.IMREAD_GRAYSCALE)
63
+ _, binary = cv2.threshold(img, 128, 1, cv2.THRESH_BINARY_INV) # invert, binary mask (0,1)
64
+
65
+ # Skeletonize
66
+ skeleton = skeletonize(binary).astype(np.uint8)
67
+
68
+ # Remove small hanging clusters
69
+ labeled = label(skeleton, connectivity=2)
70
+ cleaned = remove_small_objects(labeled, min_size=150) # Adjust min_size for more/less pruning
71
+
72
+ # Convert back to 0–255 uint8 image
73
+ final = (cleaned > 0).astype(np.uint8) * 255
74
+
75
+ # Invert back if needed
76
+ result = 255 - final
77
+
78
+ # Save
79
+ output_path = f'{self.config.output_folder}/{output_filename}'
80
+ cv2.imwrite(output_path, result)
81
+ print(f"✅ Cleaned and thinned image saved to: {output_path}")
82
+ return str(output_path)
83
+
84
 
85
  def clean_dilated_image(self, dilated_path: str,
86
+ output_filename: str = "6_dilated_cleaned.jpg",
87
  max_neighbors: int = 2) -> str:
88
  """Clean dilated image by thinning thick borders."""
89
  dilated = cv2.imread(dilated_path, cv2.IMREAD_GRAYSCALE)
comic_panel_extractor/main.py CHANGED
@@ -32,14 +32,16 @@ class ComicPanelExtractor:
32
  masked_image_path = self.image_processor.mask_text_regions([bubble["bbox"] for bubble in text_bubbles])
33
 
34
  # Step 2: Preprocess image
35
- _, _, dilated_path = self.image_processor.preprocess_image(masked_image_path)
36
-
 
 
37
  # Step 3: Clean dilated image
38
- cleaned_path = self.image_processor.clean_dilated_image(dilated_path)
39
 
40
  # Step 4: Extract panels
41
  panel_images, panel_data, all_panel_path = self.panel_extractor.extract_panels(
42
- cleaned_path, min_width_ratio=0.1
43
  )
44
 
45
  return panel_images, panel_data, all_panel_path
 
32
  masked_image_path = self.image_processor.mask_text_regions([bubble["bbox"] for bubble in text_bubbles])
33
 
34
  # Step 2: Preprocess image
35
+ _, _, processed_image_path = self.image_processor.preprocess_image(masked_image_path)
36
+
37
+ # Step 3: Thin border line
38
+ processed_image_path = self.image_processor.thin_image_borders(processed_image_path)
39
  # Step 3: Clean dilated image
40
+ # processed_image_path = self.image_processor.clean_dilated_image(processed_image_path)
41
 
42
  # Step 4: Extract panels
43
  panel_images, panel_data, all_panel_path = self.panel_extractor.extract_panels(
44
+ processed_image_path, min_width_ratio=0.1
45
  )
46
 
47
  return panel_images, panel_data, all_panel_path
comic_panel_extractor/panel_extractor.py CHANGED
@@ -102,7 +102,7 @@ class PanelExtractor:
102
  width = dilated.shape[1]
103
  row_slice = dilated[y1:y2, :]
104
  col_black_percentage = np.sum(row_slice == 0, axis=0) / (y2 - y1) * 100
105
-
106
  # Find column gutters
107
  col_gutters = []
108
  in_gutter = False
@@ -169,7 +169,7 @@ class PanelExtractor:
169
  panel_data.append(panel_info)
170
 
171
  # Save panel image
172
- panel_path = f'{self.config.output_folder}/panel_{idx}.jpg'
173
  cv2.imwrite(str(panel_path), panel_img)
174
  all_panel_path.append(panel_path)
175
 
 
102
  width = dilated.shape[1]
103
  row_slice = dilated[y1:y2, :]
104
  col_black_percentage = np.sum(row_slice == 0, axis=0) / (y2 - y1) * 100
105
+
106
  # Find column gutters
107
  col_gutters = []
108
  in_gutter = False
 
169
  panel_data.append(panel_info)
170
 
171
  # Save panel image
172
+ panel_path = f'{self.config.output_folder}/panel_{idx}_{(x1, y1, x2, y2)}.jpg'
173
  cv2.imwrite(str(panel_path), panel_img)
174
  all_panel_path.append(panel_path)
175
 
requirements.txt CHANGED
@@ -5,4 +5,5 @@ easyocr
5
  fastapi
6
  uvicorn
7
  python-multipart
8
- jinja2
 
 
5
  fastapi
6
  uvicorn
7
  python-multipart
8
+ jinja2
9
+ scikit-image