• Python Opencv实践 - 车辆统计(2)检测线绘制,车辆数量计数和显示


            针对我所使用的视频,对上一节的代码进行了修改,增加了更多参数。

    Python Opencv实践 - 车辆统计(1)读取视频,移除背景,做预处理_亦枫Leonlew的博客-CSDN博客示例中的图像的腐蚀、膨胀和闭运算等需要根据具体视频进行实验得到最佳效果。https://blog.csdn.net/vivo01/article/details/133756184?spm=1001.2014.3001.5502        主要参数有,检测窗口过滤大小的变量min/max_w/h,检测线的位置和长度(detection_line_x/y/length),检测线上下偏移量阈值(detection_line_offset)。

            由于没有使用深度学习来识别车辆,只是通过传统的计算机视觉方法处理图像后,通过搜索轮廓来实现车辆检测。因此所有参数都是针对我所使用的视频进行了优化,实际运行中,还是会存在无法检测出部分车辆的问题。所有对图像的处理方法和相关参数,需要大家根据自己的视频来进行优化。对于我所使用的视频,我没有直接用MOG2来做背景移除,而是先通过Canny提取边缘后再进行背景移除处理,这一点只是实验出来对我所使用的视频来说效果最好,并非网上所看教程的做法。

    1. import cv2 as cv
    2. import numpy as np
    3. #读取视频文件
    4. videoFile = "../../SampleVideos/TrafficHEB.mp4"
    5. video = cv.VideoCapture(videoFile)
    6. FPS = 15
    7. DELAY = int(1000 / FPS)
    8. kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (3,3))
    9. min_w = 82
    10. min_h = 82
    11. max_w = 160
    12. max_h = 160
    13. detection_line_length = 1500
    14. detection_line_x = (1920 - detection_line_length) / 2
    15. detection_line_y = 900
    16. detection_line_offset = 1
    17. cars_detected = 0
    18. #训练MOG2背景移除对象
    19. def trainBgSubtractor(train_video, mog, frameNum):
    20. #train_video = cv.VideoCapture(videoFile)
    21. while True:
    22. ret, frame = train_video.read()
    23. if ret == False:
    24. break
    25. mog.apply(frame, None, 0.01)
    26. frameNum = frameNum - 1
    27. if frameNum <= 0:
    28. break
    29. #train_video.release()
    30. #增加对比度
    31. def imageAdjust(img, clipLimit = 1.5, gridSize = (3,3)):
    32. clahe = cv.createCLAHE(clipLimit, gridSize)
    33. adjusted_img = clahe.apply(img)
    34. return adjusted_img
    35. def filterMask(img, a=None):
    36. kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (3, 3))
    37. # Fill any small holes
    38. img = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)
    39. #img = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)
    40. # Remove noise
    41. img = cv.morphologyEx(img, cv.MORPH_OPEN, kernel)
    42. # Dilate to merge adjacent blobs
    43. img = cv.dilate(img, kernel, iterations=6)
    44. return img
    45. def rectCenter(x, y, w, h):
    46. return x + w / 2, y + h / 2
    47. #移除背景
    48. #参考资料:https://blog.csdn.net/u014737138/article/details/80389977
    49. #mog = cv.bgsegm.createBackgroundSubtractorMOG()
    50. mog = cv.createBackgroundSubtractorMOG2(history=100, detectShadows=True)
    51. #trainBgSubtractor(video, mog, 100)
    52. while True:
    53. cars_positions = []
    54. ret,frame = video.read()
    55. if ret == False:
    56. break;
    57. #变为灰度图做高斯滤波
    58. frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    59. frame_gray = cv.Canny(frame_gray, 65, 160)
    60. frame_gray = cv.GaussianBlur(frame_gray, (3,3), 3)
    61. #frame_gray = cv.medianBlur(frame_gray, 3)
    62. frame_gray = imageAdjust(frame_gray, 15, (3,3))
    63. foreground_mask = mog.apply(frame_gray, None, -1)
    64. foreground_mask[foreground_mask < 240] = 0
    65. #foreground_mask = cv.dilate(foreground_mask, kernel, iterations=2)
    66. forground_mask = cv.GaussianBlur(foreground_mask, (3,3), 3)
    67. foreground_mask = filterMask(foreground_mask)
    68. #画出检测线
    69. cv.line(frame,
    70. (int(detection_line_x), int(detection_line_y)),
    71. (int(detection_line_x + detection_line_length),int(detection_line_y)),
    72. (0,50,200))
    73. #查找轮廓
    74. contours,hierarchy = cv.findContours(foreground_mask, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_TC89_L1)
    75. #contours,hierarchy = cv.findContours(foreground_mask, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    76. #绘制轮廓
    77. for contour in contours:
    78. (x,y,w,h) = cv.boundingRect(contour)
    79. #过滤掉小的轮廓框
    80. if w >= min_w and h >= min_h and w <= max_w and h <= max_h:
    81. cv.rectangle(frame, (int(x),int(y)), (int(x + w), int(y + h)), (0,255,0), 2)
    82. #画出车辆中心点
    83. centerX,centerY = rectCenter(x, y, w , h)
    84. cv.circle(frame, (int(centerX), int(centerY)), 4, (0,0,255), -1)
    85. #将车辆加入检测到的车辆列表中
    86. cars_positions.append((centerX, centerY))
    87. #检测车辆中心点是否通过检测线
    88. for (x,y) in cars_positions:
    89. if (y > (detection_line_y - detection_line_offset) and y < (detection_line_y + detection_line_offset) and
    90. x > (detection_line_x) and x < (detection_line_x + detection_line_length)):
    91. cars_detected = cars_detected + 1
    92. print(cars_detected)
    93. #输出文字
    94. cv.putText(frame, 'Vehicle Detected:' + str(cars_detected), (900, 50), cv.FONT_HERSHEY_SIMPLEX, 2, (0,255,0), 5)
    95. cv.imshow("Traffic Original", frame)
    96. cv.imshow("Traffic Processing", foreground_mask)
    97. if cv.waitKey(DELAY) == 27:
    98. break;
    99. video.release()
    100. cv.destroyAllWindows();

  • 相关阅读:
    Web前端框架:深入探索与实践
    Ai时代降临,我们的未来又在哪里?
    Spring Boot : ORM 框架 JPA 与连接池 Hikari
    Java基础面试题总结(一)
    k8s+RabbitMQ单机部署
    [附源码]计算机毕业设计养生药膳推荐系统Springboot程序
    Factorial Divisibility(数论,1600)
    JAVA8新特性-Stream
    elasticsearch源码解析TODO列表
    气膜建筑是真正的节能环保建筑
  • 原文地址:https://blog.csdn.net/vivo01/article/details/133999797