CommonZhuan Preprocessing Scripts 1.0

This commit is contained in:
CrbnsCat10n
2026-05-13 16:57:16 +08:00
parent 4e26779971
commit 629086e53c
9 changed files with 1009 additions and 6 deletions

View 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()