k4d3 commited on
Commit
b6f2240
·
1 Parent(s): 9e5b82e

Refactor image processing in img_clean_sketch.py to enhance functionality

Browse files

This commit modifies the img_clean_sketch.py script to improve image processing capabilities. Key changes include:
- Updated the process_image function to create a new data array for modifications, ensuring the original data remains unchanged.
- Enhanced white and grayscale pixel detection logic for better accuracy.
- Refactored process_directory to process multiple files and directories, improving flexibility in handling input paths.
- Updated the main function to accept multiple paths as arguments.

These improvements streamline the image processing workflow and enhance the script's usability.

Files changed (1) hide show
  1. utils/img_clean_sketch.py +76 -49
utils/img_clean_sketch.py CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env python
2
  # -*- coding: utf-8 -*-
3
  #
4
  # 画像の白い背景を透明にし、グレースケールを黒に変換する
@@ -10,6 +10,7 @@ from PIL import Image
10
  import argparse
11
  from pathlib import Path
12
  import os
 
13
 
14
  def process_image(image_path: Path, tolerance: int = 10, gray_tolerance: int = 5) -> None:
15
  """
@@ -25,69 +26,105 @@ def process_image(image_path: Path, tolerance: int = 10, gray_tolerance: int = 5
25
  img = Image.open(image_path).convert("RGBA")
26
  data = np.array(img)
27
 
28
- # Create alpha mask based on white detection
 
 
 
29
  r, g, b = data[:, :, 0], data[:, :, 1], data[:, :, 2]
30
- white_mask = (abs(r - 255) <= tolerance) & \
31
- (abs(g - 255) <= tolerance) & \
32
- (abs(b - 255) <= tolerance)
33
 
34
- # Detect grayscale pixels (where R ≈ G ≈ B)
35
- gray_mask = (abs(r - g) <= gray_tolerance) & \
36
- (abs(g - b) <= gray_tolerance) & \
37
- (abs(r - b) <= gray_tolerance) & \
38
- ~white_mask # Exclude white pixels
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
- # Set alpha channel to 0 where white is detected
41
- data[:, :, 3] = np.where(white_mask, 0, data[:, :, 3])
42
 
43
- # Convert grayscale pixels to black
44
- data[gray_mask, 0:3] = 0 # Set RGB to 0 (black)
 
 
 
 
 
 
45
 
46
  # Create output path with suffix
47
  output_path = image_path.parent / f"{image_path.stem}-processed.png"
48
 
49
  # Save the modified image
50
- Image.fromarray(data).save(output_path, "PNG")
51
  print(f"Processed image saved as {output_path}")
52
 
53
  except Exception as e:
54
  print(f"Error processing {image_path}: {e}")
55
 
56
- def process_directory(directory: Path, tolerance: int = 10, gray_tolerance: int = 5, recursive: bool = False) -> None:
57
  """
58
- Process all images in a directory.
59
 
60
  Args:
61
- directory (Path): Directory containing image files
62
- tolerance (int): Color tolerance for white detection
63
- gray_tolerance (int): Tolerance for grayscale detection
64
- recursive (bool): Whether to process subdirectories
65
  """
66
- # Supported image extensions (from imgproc_utils.py pattern)
67
  extensions = {".png", ".jpg", ".jpeg", ".webp", ".bmp"}
68
 
69
- # Get file list based on recursive flag
70
- if recursive:
71
- files = [f for ext in extensions for f in directory.rglob(f"*{ext}")]
72
- else:
73
- files = [f for ext in extensions for f in directory.glob(f"*{ext}")]
74
-
75
- if not files:
76
- print(f"No supported image files found in {directory}")
77
- return
78
-
79
- for file_path in files:
80
- process_image(file_path, tolerance, gray_tolerance)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
  def main():
83
  parser = argparse.ArgumentParser(
84
  description="Remove white background and convert grayscale colors to black."
85
  )
86
  parser.add_argument(
87
- "-d", "--directory",
88
- type=str,
89
- default=".",
90
- help="Directory containing the image files (default: current directory)"
91
  )
92
  parser.add_argument(
93
  "-t", "--tolerance",
@@ -108,17 +145,7 @@ def main():
108
  )
109
  args = parser.parse_args()
110
 
111
- target_directory = Path(args.directory)
112
- if not target_directory.exists():
113
- print(f"Error: Directory {target_directory} does not exist.")
114
- return 1
115
-
116
- process_directory(
117
- target_directory,
118
- args.tolerance,
119
- args.gray_tolerance,
120
- args.recursive
121
- )
122
  return 0
123
 
124
  if __name__ == "__main__":
 
1
+ #!/usr/bin/env python
2
  # -*- coding: utf-8 -*-
3
  #
4
  # 画像の白い背景を透明にし、グレースケールを黒に変換する
 
10
  import argparse
11
  from pathlib import Path
12
  import os
13
+ from typing import List, Union
14
 
15
  def process_image(image_path: Path, tolerance: int = 10, gray_tolerance: int = 5) -> None:
16
  """
 
26
  img = Image.open(image_path).convert("RGBA")
27
  data = np.array(img)
28
 
29
+ # Get alpha channel
30
+ alpha = data[:, :, 3]
31
+
32
+ # Create masks for processing
33
  r, g, b = data[:, :, 0], data[:, :, 1], data[:, :, 2]
 
 
 
34
 
35
+ # Calculate color intensity (average of RGB)
36
+ color_intensity = (r + g + b) / 3.0
37
+
38
+ # Detect white pixels (only in areas that aren't already transparent)
39
+ white_mask = ((color_intensity >= 250) & # Very bright pixels
40
+ (abs(r - g) <= tolerance) & # Similar RGB values
41
+ (abs(g - b) <= tolerance) &
42
+ (abs(r - b) <= tolerance) &
43
+ (alpha > 0)) # Only non-transparent pixels
44
+
45
+ # Detect grayscale pixels (excluding white and transparent)
46
+ gray_mask = ((abs(r - g) <= gray_tolerance) &
47
+ (abs(g - b) <= gray_tolerance) &
48
+ (abs(r - b) <= gray_tolerance) &
49
+ (color_intensity < 250) & # Not too bright
50
+ (alpha > 0) & # Not transparent
51
+ ~white_mask) # Not white
52
+
53
+ # Debug info
54
+ print(f"Original alpha range: {alpha.min()}-{alpha.max()}")
55
+ print(f"White pixels detected: {white_mask.sum()}")
56
+ print(f"Gray pixels detected: {gray_mask.sum()}")
57
 
58
+ # Create new data array to avoid modifying original
59
+ new_data = data.copy()
60
 
61
+ # Make white pixels transparent
62
+ new_data[white_mask, 3] = 0
63
+
64
+ # Convert grayscale to black while preserving alpha
65
+ new_data[gray_mask, 0:3] = 0
66
+
67
+ # Debug info after modifications
68
+ print(f"Final alpha range: {new_data[:,:,3].min()}-{new_data[:,:,3].max()}")
69
 
70
  # Create output path with suffix
71
  output_path = image_path.parent / f"{image_path.stem}-processed.png"
72
 
73
  # Save the modified image
74
+ Image.fromarray(new_data).save(output_path, "PNG")
75
  print(f"Processed image saved as {output_path}")
76
 
77
  except Exception as e:
78
  print(f"Error processing {image_path}: {e}")
79
 
80
+ def process_paths(paths: List[Union[str, Path]], tolerance: int = 10, gray_tolerance: int = 5, recursive: bool = False) -> None:
81
  """
82
+ Process multiple files and/or directories.
83
 
84
  Args:
85
+ paths: List of file and directory paths to process
86
+ tolerance: Color tolerance for white detection
87
+ gray_tolerance: Tolerance for grayscale detection
88
+ recursive: Whether to process subdirectories recursively
89
  """
90
+ # Supported image extensions
91
  extensions = {".png", ".jpg", ".jpeg", ".webp", ".bmp"}
92
 
93
+ for path in paths:
94
+ path = Path(path)
95
+
96
+ if not path.exists():
97
+ print(f"Error: Path does not exist: {path}")
98
+ continue
99
+
100
+ if path.is_file():
101
+ if path.suffix.lower() in extensions:
102
+ process_image(path, tolerance, gray_tolerance)
103
+ else:
104
+ print(f"Skipping unsupported file: {path}")
105
+
106
+ elif path.is_dir():
107
+ # Process directory
108
+ if recursive:
109
+ files = [f for ext in extensions for f in path.rglob(f"*{ext}")]
110
+ else:
111
+ files = [f for ext in extensions for f in path.glob(f"*{ext}")]
112
+
113
+ if not files:
114
+ print(f"No supported image files found in {path}")
115
+ continue
116
+
117
+ for file_path in files:
118
+ process_image(file_path, tolerance, gray_tolerance)
119
 
120
  def main():
121
  parser = argparse.ArgumentParser(
122
  description="Remove white background and convert grayscale colors to black."
123
  )
124
  parser.add_argument(
125
+ "paths",
126
+ nargs="+",
127
+ help="One or more image files or directories to process"
 
128
  )
129
  parser.add_argument(
130
  "-t", "--tolerance",
 
145
  )
146
  args = parser.parse_args()
147
 
148
+ process_paths(args.paths, args.tolerance, args.gray_tolerance, args.recursive)
 
 
 
 
 
 
 
 
 
 
149
  return 0
150
 
151
  if __name__ == "__main__":