correct.py 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import cv2
  2. import math
  3. import numpy as np
  4. from scipy import ndimage
  5. class HorizontalCorrection:
  6. def __init__(self):
  7. self.rotate_vector = np.array([0, 1]) # 图片中地面的法线向量
  8. self.rotate_theta = 0 # 旋转的角度
  9. self.rotate_img = None
  10. def process(self, img):
  11. img = cv2.imread(img) # 读取图片
  12. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二值化
  13. edges = cv2.Canny(gray, 350, 400, apertureSize=3) # canny算子
  14. cv2.imshow('edges.png', edges)
  15. cv2.waitKey(1)
  16. # 霍夫变换
  17. lines = cv2.HoughLines(edges, 1, np.pi / 180, 120)
  18. _sum = 0
  19. count = 0
  20. for r_theta in lines:
  21. arr = np.array(r_theta[0], dtype=np.float64)
  22. rho, theta = arr
  23. a = np.cos(theta)
  24. b = np.sin(theta)
  25. x0 = a * rho
  26. y0 = b * rho
  27. x1 = int(x0 + 1000 * (-b))
  28. y1 = int(y0 + 1000 * a)
  29. x2 = int(x0 - 1000 * (-b))
  30. y2 = int(y0 - 1000 * a)
  31. if x2 != x1:
  32. t = float(y2 - y1) / (x2 - x1)
  33. if np.pi / 5 >= t >= - np.pi / 5:
  34. rotate_angle = math.degrees(math.atan(t))
  35. _sum += rotate_angle
  36. count += 1
  37. cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
  38. if count == 0:
  39. avg_rotate_angle = 0
  40. else:
  41. avg_rotate_angle = _sum / count
  42. self.rotate_img = ndimage.rotate(img, avg_rotate_angle) # 逆时针旋转
  43. self.rotate_theta = avg_rotate_angle # 向量顺时针旋转公式
  44. self.count_rotate_vector()
  45. def count_rotate_vector(self):
  46. v1_new = (self.rotate_vector[0] * np.cos(self.rotate_theta / 180)) - \
  47. (self.rotate_vector[1] * np.sin(self.rotate_theta / 180))
  48. v2_new = (self.rotate_vector[1] * np.cos(self.rotate_theta / 180)) + \
  49. (self.rotate_vector[0] * np.sin(self.rotate_theta / 180))
  50. self.rotate_vector = np.array([v1_new, v2_new])
  51. def manual_set_rotate_vector(self, rotate_theta):
  52. self.rotate_theta = rotate_theta
  53. self.count_rotate_vector()
  54. def canny_threshold(self, img_path):
  55. img_original = cv2.imread(img_path)
  56. # 设置窗口
  57. cv2.namedWindow('Canny')
  58. # 定义回调函数
  59. def nothing(x):
  60. pass
  61. # 创建两个滑动条,分别控制threshold1,threshold2
  62. cv2.createTrackbar('threshold1', 'Canny', 20, 400, nothing)
  63. cv2.createTrackbar('threshold2', 'Canny', 100, 400, nothing)
  64. while True:
  65. # 返回滑动条所在位置的值
  66. threshold1 = cv2.getTrackbarPos('threshold1', 'Canny')
  67. threshold2 = cv2.getTrackbarPos('threshold2', 'Canny')
  68. # Canny边缘检测
  69. img_edges = cv2.Canny(img_original, threshold1, threshold2)
  70. # 显示图片
  71. cv2.imshow('original', img_original)
  72. cv2.imshow('Canny', img_edges)
  73. if cv2.waitKey(1) == ord('q'):
  74. break
  75. cv2.destroyAllWindows()
  76. if __name__ == '__main__':
  77. horizontal_correction = HorizontalCorrection()
  78. # horizontal_correction.canny_threshold(r'img/17.jpg')
  79. horizontal_correction.process(r'img/17.jpg')
  80. print(horizontal_correction.rotate_theta)
  81. cv2.imshow('rotate', horizontal_correction.rotate_img)
  82. cv2.waitKey()