在Python中检测角度并旋转图像

36

在Python中检测角度并旋转图像

我想在图(a)左侧检测一个角度(即A),并将其旋转至正确的位置(即图b)。这张图片是答题纸。

我如何在Python中实现这个功能?


1
你的问题很宽泛,而且它所属的主题不是标准python的一部分。我建议你阅读有关opencv的内容。此外,鉴于你的声望应该知道在SO上你的问题是不合适的。 - eyllanesc
1个回答

72
你可以使用OpenCV和HoughLines在图像中检测线条。每条线的角度可以从此中找到。
import numpy as np
import cv2
import math
from scipy import ndimage

img_before = cv2.imread('rotate_me.png')

cv2.imshow("Before", img_before)    
key = cv2.waitKey(0)

img_gray = cv2.cvtColor(img_before, cv2.COLOR_BGR2GRAY)
img_edges = cv2.Canny(img_gray, 100, 100, apertureSize=3)
lines = cv2.HoughLinesP(img_edges, 1, math.pi / 180.0, 100, minLineLength=100, maxLineGap=5)

angles = []

for [[x1, y1, x2, y2]] in lines:
    cv2.line(img_before, (x1, y1), (x2, y2), (255, 0, 0), 3)
    angle = math.degrees(math.atan2(y2 - y1, x2 - x1))
    angles.append(angle)

cv2.imshow("Detected lines", img_before)    
key = cv2.waitKey(0)

median_angle = np.median(angles)
img_rotated = ndimage.rotate(img_before, median_angle)

print(f"Angle is {median_angle:.04f}")
cv2.imwrite('rotated.jpg', img_rotated)  

这将给你一个输出,如下所示:

rotated image

它显示了被检测到需要旋转的线条。计算得出的角度是:
Angle is 3.9793

statistics.median()如果您使用的是Python 3.4或更高版本,也可以使用它来替代numpy版本。

注意: angles保存了找到的角度列表,这些角度既可以是垂直的,也可以是水平的。根据图像的情况,您可能会发现最好使用不同的方法来决定使用哪个角度来旋转图像。例如,在对它们应用中位数函数之前,您可以先筛选出仅在某个特定范围内的角度。


2
非常感谢Martin Evans,这对我帮助很大。我想找到角度,这是一个好答案。 - Welcome789
5
你可以尝试调查 rotate 函数的 cval 参数。 - Martin Evans
1
for循环不应该是 for [[x1, y1, x2, y2]] in lines: 吗?另外,如果你写 print(...) 就是兼容Python3的 ;) - myrdd
@MartinEvans 我正在尝试解决类似于链接的用例。你能否请看一下这个问题? - Ekanshu
我建议您打印angles以查看正在被检测到的角度。对于您的情况,在应用中值函数之前,最好先丢弃不在某个范围内的条目。 - Martin Evans
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接