From ab705bc95d19afe358e31a02daa825bc4abc32ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Sat, 6 Nov 2021 09:16:54 +0100 Subject: [PATCH] Add num angle to increase the angle precision --- deskew/__init__.py | 10 ++++++---- deskew/cli.py | 5 ++++- tests/test_deskew.py | 41 +++++++++++++++++++++++++++++++++-------- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/deskew/__init__.py b/deskew/__init__.py index 6014136..f2839c2 100644 --- a/deskew/__init__.py +++ b/deskew/__init__.py @@ -47,7 +47,7 @@ def _calculate_deviation(angle: float) -> np.float64: def determine_skew_dev( - image: ImageType, sigma: float = 3.0, num_peaks: int = 20 + image: ImageType, sigma: float = 3.0, num_peaks: int = 20, num_angles: int = 180 ) -> Tuple[ Optional[np.float64], List[List[np.float64]], @@ -57,7 +57,7 @@ def determine_skew_dev( """Calculate skew angle.""" img = image edges = canny(img, sigma=sigma) - out, angles, distances = hough_line(edges) + out, angles, distances = hough_line(edges, np.linspace(-np.pi / 2, np.pi / 2, num_angles, endpoint=False)) _, angles_peaks, _ = hough_line_peaks(out, angles, distances, num_peaks=num_peaks) @@ -119,11 +119,13 @@ def determine_skew_dev( return rot_angle, angles, average_deviation, (out, angles, distances) -def determine_skew(image: ImageType, sigma: float = 3.0, num_peaks: int = 20) -> Optional[np.float64]: +def determine_skew( + image: ImageType, sigma: float = 3.0, num_peaks: int = 20, num_angles: int = 180 +) -> Optional[np.float64]: """ Calculate skew angle. Return None if no skew will be found """ - angle, _, _, _ = determine_skew_dev(image, sigma=sigma, num_peaks=num_peaks) + angle, _, _, _ = determine_skew_dev(image, sigma=sigma, num_peaks=num_peaks, num_angles=num_angles) return angle diff --git a/deskew/cli.py b/deskew/cli.py index f230352..be59aa3 100644 --- a/deskew/cli.py +++ b/deskew/cli.py @@ -15,7 +15,10 @@ def main() -> None: parser.add_argument("-o", "--output", default=None, help="Output file name") parser.add_argument("--sigma", default=3.0, help="The use sigma") - parser.add_argument("--num-peaks", default=20, help="The used num peaks") + parser.add_argument("--num-peaks", default=20, help="The used number of peaks") + parser.add_argument( + "--num-angles", default=180, help="The used number of angle (determine the pressision)" + ) parser.add_argument("--background", help="The used background color") parser.add_argument(default=None, dest="input", help="Input file name") options = parser.parse_args() diff --git a/tests/test_deskew.py b/tests/test_deskew.py index a97a8e8..536afad 100644 --- a/tests/test_deskew.py +++ b/tests/test_deskew.py @@ -10,14 +10,14 @@ @pytest.mark.parametrize( "image,expected_angle", [ - ("1", pytest.approx(-1.375, abs=0.37)), - ("2", pytest.approx(-2.185, abs=0.18)), - ("3", pytest.approx(-6.250, abs=0.22)), - ("4", pytest.approx(7.095, abs=0.1)), - ("5", pytest.approx(3.410, abs=0.7)), - ("6", pytest.approx(-2.810, abs=0.21)), - ("7", pytest.approx(3.395, abs=0.7)), - ("8", pytest.approx(15.084, abs=0.05)), + ("1", pytest.approx(-1.0, abs=0.01)), + ("2", pytest.approx(-2.0, abs=0.01)), + ("3", pytest.approx(-6.0, abs=0.01)), + ("4", pytest.approx(7.0, abs=0.01)), + ("5", pytest.approx(4.0, abs=0.01)), + ("6", pytest.approx(-3.0, abs=0.01)), + ("7", pytest.approx(3.0, abs=0.01)), + ("8", pytest.approx(15.0, abs=0.01)), ], ) def test_deskew(image, expected_angle): @@ -30,3 +30,28 @@ def test_deskew(image, expected_angle): angle = determine_skew(grayscale) print(angle - expected_angle.expected) assert angle == expected_angle + + +@pytest.mark.parametrize( + "image,expected_angle", + [ + ("1", pytest.approx(-1.4, abs=0.01)), + ("2", pytest.approx(-2.1, abs=0.01)), + ("3", pytest.approx(-6.2, abs=0.01)), + ("4", pytest.approx(7.1, abs=0.01)), + ("5", pytest.approx(3.4, abs=0.01)), + ("6", pytest.approx(-2.8, abs=0.01)), + ("7", pytest.approx(3.7, abs=0.01)), + ("8", pytest.approx(14.9, abs=0.01)), + ], +) +def test_deskew_higher_pressision(image, expected_angle): + root_folder = f"results/{image}" + if not os.path.exists(root_folder): + os.makedirs(root_folder) + + image = io.imread(os.path.join(os.path.dirname(__file__), f"deskew-{image}.png")) + grayscale = rgb2gray(image) + angle = determine_skew(grayscale, num_angles=1800) + print(angle - expected_angle.expected) + assert angle == expected_angle