CommonZhuan Preprocessing Scripts 1.0
This commit is contained in:
143
PreProcessing_Common/scripts/run_preprocessing.py
Normal file
143
PreProcessing_Common/scripts/run_preprocessing.py
Normal file
@@ -0,0 +1,143 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
import cv2
|
||||
|
||||
import clean_characters
|
||||
import vectorize_characters
|
||||
|
||||
|
||||
def process_image(
|
||||
image_path: Path,
|
||||
image_output_dir: Path,
|
||||
svg_output_dir: Path,
|
||||
min_component_area: int | None,
|
||||
max_hole_area: int | None,
|
||||
max_isolated_speck_area: int | None,
|
||||
clean_smooth: bool,
|
||||
vector_smooth_iterations: int | None,
|
||||
epsilon_ratio: float | None,
|
||||
) -> None:
|
||||
original = clean_characters.read_image(image_path)
|
||||
gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)
|
||||
binary = clean_characters.binarize_foreground(gray)
|
||||
(
|
||||
adaptive_min_area,
|
||||
adaptive_max_hole_area,
|
||||
adaptive_max_isolated_speck_area,
|
||||
) = clean_characters.adaptive_clean_params(binary)
|
||||
|
||||
cleaned = clean_characters.clean_mask(
|
||||
binary,
|
||||
min_component_area=(
|
||||
adaptive_min_area if min_component_area is None else min_component_area
|
||||
),
|
||||
max_hole_area=(
|
||||
adaptive_max_hole_area if max_hole_area is None else max_hole_area
|
||||
),
|
||||
max_isolated_speck_area=(
|
||||
adaptive_max_isolated_speck_area
|
||||
if max_isolated_speck_area is None
|
||||
else max_isolated_speck_area
|
||||
),
|
||||
smooth=clean_smooth,
|
||||
)
|
||||
|
||||
auto_smooth_iterations, auto_epsilon_ratio = vectorize_characters.vector_params(
|
||||
cleaned
|
||||
)
|
||||
smoothed = vectorize_characters.smooth_mask(
|
||||
cleaned,
|
||||
iterations=(
|
||||
auto_smooth_iterations
|
||||
if vector_smooth_iterations is None
|
||||
else vector_smooth_iterations
|
||||
),
|
||||
)
|
||||
ratio = auto_epsilon_ratio if epsilon_ratio is None else epsilon_ratio
|
||||
|
||||
stem = image_path.stem
|
||||
clean_characters.write_image(
|
||||
image_output_dir / f"{stem}_cleaned_smoothed.png",
|
||||
clean_characters.mask_to_display(smoothed),
|
||||
)
|
||||
svg = vectorize_characters.mask_to_svg(
|
||||
smoothed,
|
||||
title=stem,
|
||||
epsilon_ratio=ratio,
|
||||
)
|
||||
(svg_output_dir / f"{stem}.svg").write_text(svg, encoding="utf-8")
|
||||
|
||||
|
||||
def build_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Clean, smooth, and vectorize complex seal-script characters."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--input-dir",
|
||||
type=Path,
|
||||
default=Path("PreProcessing_Common/original_characters"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--image-output-dir",
|
||||
type=Path,
|
||||
default=Path("PreProcessing_Common/processed_characters"),
|
||||
help="Output folder for clean+smoothed PNG files.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--svg-output-dir",
|
||||
type=Path,
|
||||
default=Path("PreProcessing_Common/vector_characters"),
|
||||
help="Output folder for SVG vector files.",
|
||||
)
|
||||
parser.add_argument("--min-component-area", type=int, default=None)
|
||||
parser.add_argument("--max-hole-area", type=int, default=None)
|
||||
parser.add_argument("--max-isolated-speck-area", type=int, default=None)
|
||||
parser.add_argument(
|
||||
"--no-clean-smooth",
|
||||
action="store_true",
|
||||
help="Skip the light 3x3 smoothing inside the clean stage.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--vector-smooth-iterations",
|
||||
type=int,
|
||||
default=None,
|
||||
help="Override automatic vector smoothing. Dense characters default to less smoothing.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--epsilon-ratio",
|
||||
type=float,
|
||||
default=None,
|
||||
help="Override contour simplification ratio. Smaller values keep more detail.",
|
||||
)
|
||||
return parser
|
||||
|
||||
|
||||
def main() -> None:
|
||||
args = build_parser().parse_args()
|
||||
args.image_output_dir.mkdir(parents=True, exist_ok=True)
|
||||
args.svg_output_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
image_paths = clean_characters.iter_images(args.input_dir)
|
||||
if not image_paths:
|
||||
raise SystemExit(f"No images found in {args.input_dir}")
|
||||
|
||||
for image_path in image_paths:
|
||||
process_image(
|
||||
image_path=image_path,
|
||||
image_output_dir=args.image_output_dir,
|
||||
svg_output_dir=args.svg_output_dir,
|
||||
min_component_area=args.min_component_area,
|
||||
max_hole_area=args.max_hole_area,
|
||||
max_isolated_speck_area=args.max_isolated_speck_area,
|
||||
clean_smooth=not args.no_clean_smooth,
|
||||
vector_smooth_iterations=args.vector_smooth_iterations,
|
||||
epsilon_ratio=args.epsilon_ratio,
|
||||
)
|
||||
print(f"processed: {image_path.name}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user