1"""Дополнительное задание: перевод цветного изображения в оттенки серого."""23import argparse45import matplotlib.pyplot as plt6import numpy as np789def grayscale_slow(image: np.ndarray) -> np.ndarray:10 """Учебная реализация с двумя циклами."""11 rgb = image[..., :3]12 result = np.empty(rgb.shape[:2], dtype=float)13 for row in range(rgb.shape[0]):14 for column in range(rgb.shape[1]):15 result[row, column] = np.mean(rgb[row, column])16 return result171819def grayscale_fast(image: np.ndarray) -> np.ndarray:20 """Векторизованная реализация NumPy без циклов Python."""21 return np.mean(image[..., :3], axis=2)222324def main() -> None:25 parser = argparse.ArgumentParser()26 parser.add_argument("image", help="Путь к исходному изображению")27 parser.add_argument("--output", default="grayscale.png")28 args = parser.parse_args()2930 image = plt.imread(args.image)31 slow = grayscale_slow(image)32 fast = grayscale_fast(image)3334 if not np.allclose(slow, fast):35 raise RuntimeError("Медленный и быстрый способы дали разные результаты")3637 figure, axes = plt.subplots(1, 3, figsize=(13, 4))38 axes[0].imshow(image)39 axes[0].set_title("Исходное изображение")40 axes[1].imshow(slow, cmap="gray")41 axes[1].set_title("Два цикла")42 axes[2].imshow(fast, cmap="gray")43 axes[2].set_title("Векторизация NumPy")44 for axis in axes:45 axis.axis("off")46 figure.tight_layout()47 figure.savefig(args.output, dpi=160)48 print(f"Результат сохранён: {args.output}")495051if __name__ == "__main__":52 main()