"""Command Line Interface (CLI) for CV Lab Camera operations.""" from __future__ import annotations import argparse import json import sys from pathlib import Path from developer_api import load_image, process_image, save_image from batch.dataset_processor import process_dataset def main(): parser = argparse.ArgumentParser(description="CV Lab Camera Command Line Interface for developers.") subparsers = parser.add_subparsers(dest="command", help="Sub-commands") # Filter subcommand filter_parser = subparsers.add_parser("filter", help="Apply built-in or saved image filter") filter_parser.add_argument("-i", "--input", required=True, help="Input image file path") filter_parser.add_argument("-f", "--filter", default="Sepia", help="Filter name (e.g. Sepia, Grayscale, Blur)") filter_parser.add_argument("-p", "--params", help="JSON params string") filter_parser.add_argument("-o", "--output", required=True, help="Output image file path") # Transform subcommand trans_parser = subparsers.add_parser("transform", help="Apply geometric transformation") trans_parser.add_argument("-i", "--input", required=True, help="Input image file path") trans_parser.add_argument("--op", default="Rotation", choices=["Translation", "Rotation", "Scaling", "Reflection"], help="Transformation type") trans_parser.add_argument("--angle", type=float, default=30.0, help="Rotation angle in degrees") trans_parser.add_argument("--tx", type=int, default=30, help="X translation offset") trans_parser.add_argument("--ty", type=int, default=30, help="Y translation offset") trans_parser.add_argument("-o", "--output", required=True, help="Output image file path") # Morphology subcommand morph_parser = subparsers.add_parser("morph", help="Apply morphological operations") morph_parser.add_argument("-i", "--input", required=True, help="Input image file path") morph_parser.add_argument("--op", default="Opening", help="Morphology operation (e.g. Opening, Erosion, Dilation)") morph_parser.add_argument("--size", type=int, default=5, help="Kernel size") morph_parser.add_argument("-o", "--output", required=True, help="Output image file path") # AR subcommand ar_parser = subparsers.add_parser("ar", help="Apply face AR filter") ar_parser.add_argument("-i", "--input", required=True, help="Input face image file path") ar_parser.add_argument("-f", "--filter", default="Glasses", help="AR filter name (e.g. Glasses, Cyberpunk Visor, Crown & Star Sparkles)") ar_parser.add_argument("-o", "--output", required=True, help="Output image file path") # Style subcommand style_parser = subparsers.add_parser("style", help="Apply neural style transfer") style_parser.add_argument("-i", "--input", required=True, help="Content image file path") style_parser.add_argument("-s", "--style-image", required=True, help="Style image file path") style_parser.add_argument("--max-size", type=int, default=512, help="Output max image resolution") style_parser.add_argument("-o", "--output", required=True, help="Output image file path") # Batch subcommand batch_parser = subparsers.add_parser("batch", help="Process image directory or list") batch_parser.add_argument("--files", nargs="*", help="List of input image or zip files") batch_parser.add_argument("--dir", help="Input directory") batch_parser.add_argument("-f", "--filter", default="Grayscale", help="Filter or pipeline name") batch_parser.add_argument("-o", "--output-zip", default="processed.zip", help="Output zip file path") args = parser.parse_args() if not args.command: parser.print_help() sys.exit(1) if args.command == "filter": params = json.loads(args.params) if args.params else {} _, meta = process_image(args.input, "filter", operation_name=args.filter, params=params, output_path=args.output) print(f"Applied filter '{args.filter}' -> Saved to {args.output}") elif args.command == "transform": params = {"angle": args.angle, "tx": args.tx, "ty": args.ty} _, meta = process_image(args.input, "transform", operation_name=args.op, params=params, output_path=args.output) print(f"Applied transform '{args.op}' -> Saved to {args.output}") elif args.command == "morph": params = {"size": args.size} _, meta = process_image(args.input, "morphology", operation_name=args.op, params=params, output_path=args.output) print(f"Applied morphology '{args.op}' -> Saved to {args.output}") elif args.command == "ar": _, meta = process_image(args.input, "ar", operation_name=args.filter, output_path=args.output) print(f"Applied AR filter '{args.filter}' ({meta.get('status')}) -> Saved to {args.output}") elif args.command == "style": params = {"style_image": args.style_image, "max_size": args.max_size} _, meta = process_image(args.input, "style", params=params, output_path=args.output) print(f"Applied neural style transfer -> Saved to {args.output}") elif args.command == "batch": zip_path = process_dataset(args.files, args.dir, args.filter) Path(zip_path).rename(args.output_zip) print(f"Batch dataset processed with '{args.filter}' -> Saved archive to {args.output_zip}") if __name__ == "__main__": main()