from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter def parse_args(argv=None): ap = ArgumentParser( prog="app.py", description="CLI для лабораторной №6: Стеганография в изображениях", formatter_class=ArgumentDefaultsHelpFormatter, ) sub = ap.add_subparsers(dest="cmd", required=True) # -------- Parent parsers -------- parent_channel_seq = ArgumentParser(add_help=False) parent_channel_seq.add_argument( "-c", "--channel", choices=["Y", "Cb", "Cr", "y", "cb", "cr"], default="Cb", help="Канал для встраивания/извлечения: Y, Cb или Cr", ) parent_channel_seq.add_argument( "--seq0", type=str, default="01010101", help="8-битная последовательность для бита 0 (seq1 считается инверсией seq0)", ) parent_gen_common = ArgumentParser(add_help=False) parent_gen_common.add_argument( "--size", type=int, default=512, help="Размер стороны квадратного изображения", ) parent_gen_common.add_argument( "--channels", type=int, choices=[1, 3], default=3, help="Количество каналов: 1 (grayscale) или 3 (RGB)", ) parent_gen_common.add_argument( "-o", "--output", required=True, help="Куда сохранить изображение", ) # ---------------- EMBED ---------------- sp_embed = sub.add_parser( "embed", parents=[parent_channel_seq], help="Встраивание метки в изображение-контейнер", formatter_class=ArgumentDefaultsHelpFormatter, ) sp_embed.add_argument( "-i", "--input", required=True, help="Путь к исходному изображению-контейнеру (512x512, RGB)", ) sp_embed.add_argument( "-l", "--label", required=True, help="Путь к бинарной метке (64x64)", ) sp_embed.add_argument( "-o", "--output", required=True, help="Куда сохранить стего-изображение", ) # ---------------- EXTRACT ---------------- sp_extract = sub.add_parser( "extract", parents=[parent_channel_seq], help="Извлечение метки из стего-изображения", formatter_class=ArgumentDefaultsHelpFormatter, ) sp_extract.add_argument( "-i", "--input", required=True, help="Путь к стего-изображению", ) sp_extract.add_argument( "-o", "--output", required=True, help="Куда сохранить восстановленную бинарную метку (64x64)", ) # ---------------- ANALYZE ---------------- sp_analyze = sub.add_parser( "analyze", help="Сравнение изображений и метрик качества", formatter_class=ArgumentDefaultsHelpFormatter, ) sp_analyze.add_argument( "-a", "--original", required=True, help="Путь к исходному изображению-контейнеру", ) sp_analyze.add_argument( "-b", "--stego", required=True, help="Путь к стего-изображению", ) sp_analyze.add_argument( "--space", choices=["rgb", "ycbcr"], default="ycbcr", help="Цветовое пространство для метрик", ) sp_analyze.add_argument( "--metrics", nargs="+", choices=["psnr"], default=["psnr"], help="Набор метрик", ) # ---------------- GENERATE ---------------- sp_gen = sub.add_parser( "generate", help="Генерация изображений", formatter_class=ArgumentDefaultsHelpFormatter, ) gen_sub = sp_gen.add_subparsers(dest="gen", required=True) gen_sub.add_parser( "gradient", parents=[parent_gen_common], help="Сгенерировать градиент", formatter_class=ArgumentDefaultsHelpFormatter, ) sp_chess = gen_sub.add_parser( "chess", parents=[parent_gen_common], help="Сгенерировать шахматную доску", formatter_class=ArgumentDefaultsHelpFormatter, ) sp_chess.add_argument( "--tile", type=int, default=32, help="Размер квадрата (должен делить --size)", ) return ap.parse_args(argv)