1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- import cv2
- import math
- import numpy as np
- from scipy import ndimage
- class HorizontalCorrection:
- def __init__(self):
- self.rotate_vector = np.array([0, 1]) # 图片中地面的法线向量
- self.rotate_theta = 0 # 旋转的角度
- self.rotate_img = None
- def process(self, img):
- img = cv2.imread(img) # 读取图片
- gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二值化
- edges = cv2.Canny(gray, 350, 400, apertureSize=3) # canny算子
- cv2.imshow('edges.png', edges)
- cv2.waitKey(1)
- # 霍夫变换
- lines = cv2.HoughLines(edges, 1, np.pi / 180, 120)
- _sum = 0
- count = 0
- for r_theta in lines:
- arr = np.array(r_theta[0], dtype=np.float64)
- rho, theta = arr
- a = np.cos(theta)
- b = np.sin(theta)
- x0 = a * rho
- y0 = b * rho
- x1 = int(x0 + 1000 * (-b))
- y1 = int(y0 + 1000 * a)
- x2 = int(x0 - 1000 * (-b))
- y2 = int(y0 - 1000 * a)
- if x2 != x1:
- t = float(y2 - y1) / (x2 - x1)
- if np.pi / 5 >= t >= - np.pi / 5:
- rotate_angle = math.degrees(math.atan(t))
- _sum += rotate_angle
- count += 1
- cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
- if count == 0:
- avg_rotate_angle = 0
- else:
- avg_rotate_angle = _sum / count
- self.rotate_img = ndimage.rotate(img, avg_rotate_angle) # 逆时针旋转
- self.rotate_theta = avg_rotate_angle # 向量顺时针旋转公式
- self.count_rotate_vector()
- def count_rotate_vector(self):
- v1_new = (self.rotate_vector[0] * np.cos(self.rotate_theta / 180)) - \
- (self.rotate_vector[1] * np.sin(self.rotate_theta / 180))
- v2_new = (self.rotate_vector[1] * np.cos(self.rotate_theta / 180)) + \
- (self.rotate_vector[0] * np.sin(self.rotate_theta / 180))
- self.rotate_vector = np.array([v1_new, v2_new])
- def manual_set_rotate_vector(self, rotate_theta):
- self.rotate_theta = rotate_theta
- self.count_rotate_vector()
- def canny_threshold(self, img_path):
- img_original = cv2.imread(img_path)
- # 设置窗口
- cv2.namedWindow('Canny')
- # 定义回调函数
- def nothing(x):
- pass
- # 创建两个滑动条,分别控制threshold1,threshold2
- cv2.createTrackbar('threshold1', 'Canny', 20, 400, nothing)
- cv2.createTrackbar('threshold2', 'Canny', 100, 400, nothing)
- while True:
- # 返回滑动条所在位置的值
- threshold1 = cv2.getTrackbarPos('threshold1', 'Canny')
- threshold2 = cv2.getTrackbarPos('threshold2', 'Canny')
- # Canny边缘检测
- img_edges = cv2.Canny(img_original, threshold1, threshold2)
- # 显示图片
- cv2.imshow('original', img_original)
- cv2.imshow('Canny', img_edges)
- if cv2.waitKey(1) == ord('q'):
- break
- cv2.destroyAllWindows()
- if __name__ == '__main__':
- horizontal_correction = HorizontalCorrection()
- # horizontal_correction.canny_threshold(r'img/17.jpg')
- horizontal_correction.process(r'img/17.jpg')
- print(horizontal_correction.rotate_theta)
- cv2.imshow('rotate', horizontal_correction.rotate_img)
- cv2.waitKey()
|