from argparse import ArgumentParser from pathlib import Path import cv2 as cv import numpy as np parser = ArgumentParser() parser.add_argument("--input", default="input/scene.png", help="Image to scan") parser.add_argument("--output", default="output/hough-lines.png", help="Annotated output image") parser.add_argument("--canny-low", type=int, default=50, help="Lower Canny threshold") parser.add_argument("--canny-high", type=int, default=150, help="Upper Canny threshold") parser.add_argument("--votes", type=int, default=60, help="Minimum Hough accumulator votes") parser.add_argument("--min-length", type=int, default=80, help="Minimum line segment length") parser.add_argument("--max-gap", type=int, default=12, help="Maximum gap joined into one segment") args = parser.parse_args() input_path = Path(args.input) output_path = Path(args.output) gray = cv.imread(str(input_path), cv.IMREAD_GRAYSCALE) color = cv.imread(str(input_path), cv.IMREAD_COLOR) if gray is None or color is None: raise SystemExit(f"could not read input image: {input_path}") blurred = cv.GaussianBlur(gray, (5, 5), 0) edges = cv.Canny(blurred, args.canny_low, args.canny_high, apertureSize=3) lines = cv.HoughLinesP( edges, rho=1, theta=np.pi / 180, threshold=args.votes, minLineLength=args.min_length, maxLineGap=args.max_gap, ) segments = [] if lines is None else [line[0] for line in lines] annotated = color.copy() for x1, y1, x2, y2 in segments: cv.line(annotated, (x1, y1), (x2, y2), (0, 180, 0), 3, cv.LINE_AA) output_path.parent.mkdir(parents=True, exist_ok=True) if not cv.imwrite(str(output_path), annotated): raise SystemExit(f"could not write output image: {output_path}") edge_pixels = int(cv.countNonZero(edges)) print(f"image size: {gray.shape[1]}x{gray.shape[0]}") print(f"edge pixels: {edge_pixels}") print(f"line segments: {len(segments)}") print(f"minimum segment length: {args.min_length}") print(f"maximum join gap: {args.max_gap}") if segments: longest = max( segments, key=lambda segment: np.hypot(segment[2] - segment[0], segment[3] - segment[1]), ) x1, y1, x2, y2 = longest length = np.hypot(x2 - x1, y2 - y1) print(f"longest segment: ({x1},{y1}) to ({x2},{y2}) length={length:.1f}") print(f"wrote: {output_path}")