From 6fd6aa2733ce0fc1e6406e6e94a2faef7bcc9672 Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Mon, 22 May 2023 20:32:50 +0100 Subject: [PATCH] fixes to split photos --- scripts/split_photos.py | 62 +++++++------------ .../templates/other/extract-image-scans.html | 2 +- 2 files changed, 23 insertions(+), 41 deletions(-) diff --git a/scripts/split_photos.py b/scripts/split_photos.py index 939a333e..49ecc22c 100644 --- a/scripts/split_photos.py +++ b/scripts/split_photos.py @@ -1,3 +1,4 @@ +import argparse import sys import cv2 import numpy as np @@ -36,33 +37,21 @@ def estimate_background_color(image, sample_points=5): return np.median(colors, axis=0) -def auto_rotate(image, angle_threshold=10): +def auto_rotate(image, angle_threshold=1): gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) - ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) - contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + edges = cv2.Canny(gray, 50, 150, apertureSize=3) + lines = cv2.HoughLines(edges, 1, np.pi / 180, 200) - if len(contours) == 0: + if lines is None: return image - largest_contour = max(contours, key=cv2.contourArea) - mu = cv2.moments(largest_contour) + # compute the median angle of the lines + angles = [] + for rho, theta in lines[:, 0]: + angles.append((theta * 180) / np.pi - 90) - if mu["m00"] == 0: - return image + angle = np.median(angles) - x_centroid = int(mu["m10"] / mu["m00"]) - y_centroid = int(mu["m01"] / mu["m00"]) - - coords = np.column_stack(np.where(binary > 0)) - u, _, vt = np.linalg.svd(coords - np.array([[y_centroid, x_centroid]]), full_matrices=False) - - angle = np.arctan2(u[1, 0], u[0, 0]) * 180 / np.pi - - if angle < -45: - angle = -(90 + angle) - else: - angle = -angle - if abs(angle) < angle_threshold: return image @@ -73,6 +62,7 @@ def auto_rotate(image, angle_threshold=10): + def crop_borders(image, border_color, tolerance=30): mask = cv2.inRange(image, border_color - tolerance, border_color + tolerance) @@ -112,23 +102,15 @@ def split_photos(input_file, output_directory, tolerance=30, min_area=10000, min print(f"Saved {output_path}") if __name__ == "__main__": - if len(sys.argv) < 2: - print("Usage: python3 split_photos.py [tolerance] [min_area] [min_contour_area] [angle_threshold] [border_size]") - print("\nParameters:") - print(" - The input scanned image containing multiple photos.") - print(" - The directory where the result images should be placed.") - print(" [tolerance] - Optional. Determines the range of color variation around the estimated background color (default: 30).") - print(" [min_area] - Optional. Sets the minimum area threshold for a photo (default: 10000).") - print(" [min_contour_area] - Optional. Sets the minimum contour area threshold for a photo (default: 500).") - print(" [angle_threshold] - Optional. Sets the minimum absolute angle required for the image to be rotated (default: 10).") - print(" [border_size] - Optional. Sets the size of the border added and removed to prevent white borders in the output (default: 0).") - sys.exit(1) + parser = argparse.ArgumentParser(description="Split photos in an image") + parser.add_argument("input_file", help="The input scanned image containing multiple photos.") + parser.add_argument("output_directory", help="The directory where the result images should be placed.") + parser.add_argument("--tolerance", type=int, default=30, help="Determines the range of color variation around the estimated background color (default: 30).") + parser.add_argument("--min_area", type=int, default=10000, help="Sets the minimum area threshold for a photo (default: 10000).") + parser.add_argument("--min_contour_area", type=int, default=500, help="Sets the minimum contour area threshold for a photo (default: 500).") + parser.add_argument("--angle_threshold", type=int, default=10, help="Sets the minimum absolute angle required for the image to be rotated (default: 10).") + parser.add_argument("--border_size", type=int, default=0, help="Sets the size of the border added and removed to prevent white borders in the output (default: 0).") + + args = parser.parse_args() - input_file = sys.argv[1] - output_directory = sys.argv[2] - tolerance = int(sys.argv[6]) if len(sys.argv) > 3 else 20 - min_area = int(sys.argv[8]) if len(sys.argv) > 4 else 8000 - min_contour_area = int(sys.argv[10]) if len(sys.argv) > 5 else 500 - angle_threshold = int(sys.argv[4]) if len(sys.argv) > 6 else 60 - border_size = int(sys.argv[12]) if len(sys.argv) > 7 else 0 - split_photos(input_file, output_directory, tolerance=tolerance, min_area=min_area, min_contour_area=min_contour_area, angle_threshold=angle_threshold, border_size=border_size) + split_photos(args.input_file, args.output_directory, tolerance=args.tolerance, min_area=args.min_area, min_contour_area=args.min_contour_area, angle_threshold=args.angle_threshold, border_size=args.border_size) diff --git a/src/main/resources/templates/other/extract-image-scans.html b/src/main/resources/templates/other/extract-image-scans.html index cffddfc7..bc8c869b 100644 --- a/src/main/resources/templates/other/extract-image-scans.html +++ b/src/main/resources/templates/other/extract-image-scans.html @@ -18,7 +18,7 @@
- +