vitordigitizing commited on
Commit
f0bb8ad
·
verified ·
1 Parent(s): 849c140

Update faceless_processing.py

Browse files
Files changed (1) hide show
  1. faceless_processing.py +19 -8
faceless_processing.py CHANGED
@@ -61,14 +61,15 @@ class LineartConfig:
61
  silhouette_line_thickness: int = 4 # outer contour stroke width (px); match interior for uniform look
62
 
63
  # Edge detection
64
- canny_low: int = 40
65
  canny_high: int = 110
66
  bilateral_d: int = 11
67
  bilateral_sigma_color: int = 80
68
  bilateral_sigma_space: int = 80
69
  gaussian_ksize: int = 9
70
- min_contour_perimeter: float = 50.0 # filters out short noisy lines
71
  interior_line_thickness: int = 3 # thickness of interior detail lines (>=1)
 
72
 
73
  # Face detection
74
  face_scale_factor: float = 1.05
@@ -188,23 +189,33 @@ def build_face_erase_mask(faces: list, shape: Tuple[int, int], cfg: LineartConfi
188
 
189
 
190
  def build_interior_edges(rgb: np.ndarray, subject_mask: np.ndarray, cfg: LineartConfig) -> np.ndarray:
191
- """Detect structural body lines using Canny, filtering noise."""
192
  gray = cv2.cvtColor(rgb, cv2.COLOR_RGB2GRAY)
193
  blurred = cv2.GaussianBlur(gray, (cfg.gaussian_ksize, cfg.gaussian_ksize), 0)
194
  blurred = cv2.bilateralFilter(blurred, cfg.bilateral_d, cfg.bilateral_sigma_color, cfg.bilateral_sigma_space)
195
  edges = cv2.Canny(blurred, cfg.canny_low, cfg.canny_high)
196
  edges = cv2.bitwise_and(edges, subject_mask)
197
 
198
- # Filter out short/noisy contours
199
  contours, _ = cv2.findContours(edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
200
- filtered = np.zeros_like(edges)
201
  for cnt in contours:
 
 
 
 
 
 
 
 
 
 
 
 
 
202
  if cv2.arcLength(cnt, False) > cfg.min_contour_perimeter:
203
  cv2.drawContours(filtered, [cnt], -1, 255, cfg.interior_line_thickness)
204
 
205
- # Mild dilation for uniform, solid strokes
206
- kernel_dilate = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
207
- filtered = cv2.dilate(filtered, kernel_dilate, iterations=1)
208
  return filtered
209
 
210
 
 
61
  silhouette_line_thickness: int = 4 # outer contour stroke width (px); match interior for uniform look
62
 
63
  # Edge detection
64
+ canny_low: int = 25 # lower = more body detail captured
65
  canny_high: int = 110
66
  bilateral_d: int = 11
67
  bilateral_sigma_color: int = 80
68
  bilateral_sigma_space: int = 80
69
  gaussian_ksize: int = 9
70
+ min_contour_perimeter: float = 30.0 # filters out short noisy lines
71
  interior_line_thickness: int = 3 # thickness of interior detail lines (>=1)
72
+ cluster_merge_radius: int = 5 # radius (px) to merge nearby parallel lines into one
73
 
74
  # Face detection
75
  face_scale_factor: float = 1.05
 
189
 
190
 
191
  def build_interior_edges(rgb: np.ndarray, subject_mask: np.ndarray, cfg: LineartConfig) -> np.ndarray:
192
+ """Detect structural body lines, capturing more detail then summarising clustered strokes."""
193
  gray = cv2.cvtColor(rgb, cv2.COLOR_RGB2GRAY)
194
  blurred = cv2.GaussianBlur(gray, (cfg.gaussian_ksize, cfg.gaussian_ksize), 0)
195
  blurred = cv2.bilateralFilter(blurred, cfg.bilateral_d, cfg.bilateral_sigma_color, cfg.bilateral_sigma_space)
196
  edges = cv2.Canny(blurred, cfg.canny_low, cfg.canny_high)
197
  edges = cv2.bitwise_and(edges, subject_mask)
198
 
199
+ # Step 1: draw all edges that pass the length filter
200
  contours, _ = cv2.findContours(edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
201
+ raw = np.zeros_like(edges)
202
  for cnt in contours:
203
+ if cv2.arcLength(cnt, False) > cfg.min_contour_perimeter:
204
+ cv2.drawContours(raw, [cnt], -1, 255, 1)
205
+
206
+ # Step 2: merge nearby parallel lines into single strokes
207
+ r = cfg.cluster_merge_radius
208
+ k_merge = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (r * 2 + 1, r * 2 + 1))
209
+ merged = cv2.morphologyEx(raw, cv2.MORPH_CLOSE, k_merge) # join close lines
210
+ merged = cv2.erode(merged, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (r, r)), iterations=1) # thin back
211
+
212
+ # Step 3: redraw surviving contours with final thickness for clean uniform strokes
213
+ contours2, _ = cv2.findContours(merged, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
214
+ filtered = np.zeros_like(edges)
215
+ for cnt in contours2:
216
  if cv2.arcLength(cnt, False) > cfg.min_contour_perimeter:
217
  cv2.drawContours(filtered, [cnt], -1, 255, cfg.interior_line_thickness)
218
 
 
 
 
219
  return filtered
220
 
221