当前位置:   article > 正文

Python + OpenCV 简单车辆统计

Python + OpenCV 简单车辆统计

目录

1 源码

2 运行结果


 Python + OpenCV 简单车辆统计

IDE : PyChram

1 源码

函数 car_count() 简单车辆统计

  1. # 这是一个示例 Python 脚本。
  2. # 按 Shift+F10 执行或将其替换为您的代码。
  3. # 按 双击 Shift 在所有地方搜索类、文件、工具窗口、操作和设置。
  4. import cv2
  5. import numpy
  6. import time
  7. def mouse_callback(event, x, y, flags, userdata):
  8. print(event, x, y, flags, userdata)
  9. def mouse_control():
  10. cv2.namedWindow('mouse', cv2.WINDOW_NORMAL)
  11. cv2.resizeWindow('mouse', 640, 360)
  12. img = numpy.zeros((360, 640, 3), numpy.uint8)
  13. cv2.setMouseCallback('mouse', mouse_callback, '123')
  14. while True:
  15. cv2.imshow('mouse', img)
  16. key = cv2.waitKey(1)
  17. if key == ord('q'):
  18. break
  19. cv2.destroyAllWindows()
  20. def test():
  21. """
  22. :return:
  23. """
  24. print("hello test")
  25. win_name = "frame"
  26. cv2.namedWindow(win_name, cv2.WINDOW_NORMAL)
  27. cv2.resizeWindow(win_name, 640, 480)
  28. cap = cv2.VideoCapture(0)
  29. fourcc = cv2.VideoWriter_fourcc(*'mp4v')
  30. vm = cv2.VideoWriter('output.mp4', fourcc, 20, (640, 480))
  31. if not cap.isOpened():
  32. print("video capture err")
  33. exit()
  34. while True:
  35. ret, frame = cap.read()
  36. if ret:
  37. vm.write(frame)
  38. cv2.imshow(win_name, frame)
  39. if cv2.waitKey(1) & 0xff == ord('q'):
  40. break
  41. else:
  42. break
  43. cap.release()
  44. vm.release()
  45. cv2.destroyAllWindows()
  46. def test_split_merge():
  47. img = numpy.zeros((480, 640, 3), numpy.uint8)
  48. b, g, r = cv2.split(img)
  49. b[10:100, 10:100] = 255
  50. g[10:100, 10:100] = 255
  51. img2 = cv2.merge((b, g, r))
  52. # 在图像上绘制文本
  53. font = cv2.FONT_HERSHEY_SIMPLEX
  54. text = 'Hello, OpenCV!'
  55. org = (50, 50)
  56. font_scale = 1
  57. color = (255, 0, 0) # BGR
  58. thickness = 2
  59. cv2.putText(img, text, org, font, font_scale, color, thickness, cv2.LINE_AA)
  60. cv2.line(img, (10, 10), (100, 100), (255, 111, 222))
  61. cv2.imshow("img", numpy.hstack((img, img2)))
  62. cv2.waitKey(0)
  63. cv2.destroyAllWindows()
  64. def image_flip(flip_code):
  65. image = cv2.imread('dog.png')
  66. image = cv2.flip(image, flip_code)
  67. image = cv2.rotate(image, cv2.ROTATE_180)
  68. cv2.imshow('image', image)
  69. cv2.waitKey(0)
  70. def warp_affine():
  71. dog = cv2.imread('dog.png')
  72. h, w, ch = dog.shape
  73. # m = numpy.float32([[1, 0, 100], [0, 1, 0]])
  74. m = cv2.getRotationMatrix2D((w / 2, h / 2,), 15, 1.0)
  75. new = cv2.warpAffine(dog, m, (w, h))
  76. cv2.imshow('new', new)
  77. cv2.waitKey(0)
  78. def print_hi(name):
  79. # 在下面的代码行中使用断点来调试脚本。
  80. print(f'Hi, {name}') # 按 Ctrl+F8 切换断点。
  81. warp_affine()
  82. def calculate_rectangle_center(x, y, width, height):
  83. """
  84. 根据矩形的起点坐标、宽和高计算中心点的函数
  85. 参数:
  86. x, y -- 矩形起点的坐标
  87. width -- 矩形的宽度
  88. height -- 矩形的高度
  89. 返回:
  90. cx, cy -- 矩形中心点的坐标
  91. """
  92. cx = int(x + width / 2)
  93. cy = int(y + height / 2)
  94. return cx, cy
  95. def car_count():
  96. print('car count')
  97. count = 0
  98. cap = cv2.VideoCapture('./car.mp4')
  99. if not cap.isOpened():
  100. print('video open fail')
  101. exit()
  102. # 创建一个基于高斯混合模型(Gaussian Mixture Model, GMM)的背景减法器对象
  103. bgs = cv2.createBackgroundSubtractorMOG2()
  104. kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
  105. while True:
  106. ret, frame = cap.read()
  107. if not ret:
  108. # 如果到达视频末尾,则重置视频捕获对象以从头开始播放
  109. cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
  110. # 重新读取第一帧
  111. ret, frame = cap.read()
  112. count = 0
  113. # 可选:如果不想立刻重头播放,可以在这里添加一些延时
  114. time.sleep(2) # 等待2秒
  115. if ret is True:
  116. if frame is None:
  117. break
  118. f_w = 640
  119. f_h = 480
  120. # 调整帧的大小
  121. resized_frame = cv2.resize(frame, (f_w, f_h), interpolation=cv2.INTER_AREA)
  122. # 灰度化处理
  123. gray = cv2.cvtColor(resized_frame, cv2.COLOR_BGR2GRAY)
  124. # 去噪
  125. blur = cv2.GaussianBlur(gray, (3, 3), 5)
  126. # 使用前面创建的背景减法器对象bgs来对一个视频帧frame进行处理
  127. fg_mask = bgs.apply(blur)
  128. # 腐蚀
  129. erode = cv2.erode(fg_mask, kernel)
  130. # 膨胀
  131. dilate = cv2.dilate(erode, kernel)
  132. # 闭运算
  133. close = cv2.morphologyEx(dilate, cv2.MORPH_CLOSE, kernel)
  134. # 查找轮廓
  135. contours, hierarchy = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  136. # 绘制轮廓
  137. # 你可以调整第三个参数来绘制所有轮廓或只绘制特定级别的轮廓
  138. # -1 表示绘制所有轮廓
  139. # cv2.drawContours(resized_frame, contours, -1, (0, 255, 0), 3)
  140. # 限制宽高
  141. w_limit = 40
  142. h_limit = 40
  143. # 画线的起点和终点
  144. line_sx = 10
  145. line_sy = f_h - 100
  146. line_ex = f_w - 10
  147. line_ey = line_sy
  148. offset = 3
  149. # 画线
  150. cv2.line(resized_frame, (line_sx, line_sy), (line_ex, line_ey), (0, 0, 255), 2)
  151. cars = []
  152. for contour in contours:
  153. # 最大外接矩形
  154. (x, y, w, h) = cv2.boundingRect(contour)
  155. # 过滤掉小矩形
  156. if w < w_limit or h < h_limit:
  157. continue
  158. if y < (f_h / 2):
  159. continue
  160. # print(f"Contour: x={x}, y={y}, width={w}, height={h}")
  161. cv2.rectangle(resized_frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
  162. cen_point = calculate_rectangle_center(x, y, w, h)
  163. cars.append(cen_point)
  164. cv2.circle(resized_frame, cen_point, 2, (0, 255, 0), -1)
  165. for (x, y) in cars:
  166. if (line_ey - offset) < y < (line_ey + offset):
  167. count += 1
  168. cars.remove((x, y))
  169. # print(count)
  170. cv2.putText(resized_frame, 'Cars Count:' + str(count), (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
  171. cv2.imshow('resized_frame', resized_frame)
  172. if cv2.waitKey(2) & 0xFF == 27:
  173. break
  174. cap.release()
  175. cv2.destroyAllWindows()
  176. # 按装订区域中的绿色按钮以运行脚本。
  177. if __name__ == '__main__':
  178. car_count()
  179. # 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
2 运行结果

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/823791
推荐阅读
相关标签
  

闽ICP备14008679号