将图像转换为灰度并进行高斯模糊后,我们使用自适应阈值获取二值图像
从这里我们可以找到轮廓并使用轮廓面积进行过滤,以去除小噪声颗粒和大边框。我们将通过此过滤器的任何轮廓绘制到掩码上。
为了确定角度,我们根据图像的尺寸将其分成两半。如果宽度>高度
,则必须是水平图像,因此我们在垂直方向上将其分成两半。如果高度>宽度
,则必须是竖直图像,因此我们在水平方向上将其分成两半。
现在我们有了两半部分,可以使用cv2.countNonZero()
来确定每一半的白色像素数量。以下是确定角度的逻辑:
if horizontal
if left >= right
degree -> 0
else
degree -> 180
if vertical
if top >= bottom
degree -> 270
else
degree -> 90
左侧 9703
右侧 3975
左 3975
右 9703
我们可以得出结论,该图像翻转了180度。
以下是竖直图像的结果。请注意,由于这是一张竖直图像,我们将其水平分割。
顶部 3947
底部 9550
因此结果为90度
import cv2
import numpy as np
def detect_angle(image):
mask = np.zeros(image.shape, dtype=np.uint8)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
adaptive = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,15,4)
cnts = cv2.findContours(adaptive, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area < 45000 and area > 20:
cv2.drawContours(mask, [c], -1, (255,255,255), -1)
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
h, w = mask.shape
# Horizontal
if w > h:
left = mask[0:h, 0:0+w//2]
right = mask[0:h, w//2:]
left_pixels = cv2.countNonZero(left)
right_pixels = cv2.countNonZero(right)
return 0 if left_pixels >= right_pixels else 180
# Vertical
else:
top = mask[0:h//2, 0:w]
bottom = mask[h//2:, 0:w]
top_pixels = cv2.countNonZero(top)
bottom_pixels = cv2.countNonZero(bottom)
return 90 if bottom_pixels >= top_pixels else 270
if __name__ == '__main__':
image = cv2.imread('1.png')
angle = detect_angle(image)
print(angle)