小言_互联网的博客

22.【实战】车辆统计

394人阅读  评论(0)

理论知识见上一节,最终效果如下

涉及到的内容

(1)窗口的展示

(2)图像/视频的加载

(3)基本图形的绘制

(4)车辆识别

基本图像运算与处理、形态学处理、轮廓查找

涉及到的知识点

加载视频

通过形态学识别车辆

对车辆进行统计

显示车辆统计信息

加载视频


  
  1. import cv2
  2. import numpy as np
  3. cap = cv2.VideoCapture( 'E:\\video.mp4') #加载视频
  4. while True:
  5. ret, frame = cap.read()
  6. if (ret == True) :
  7. cv2.imshow( 'video',frame)
  8. key = cv2.waitKey( 1)
  9. if(key == 27) : #esc键
  10. break
  11. cap.release()
  12. cv2.destroyAllWindows()

去除背景(关键)

运动的物体为前景,静止的物体为背景。将前景提取出来,把背景去除。

createBackgroundSubtractorMOG()

history:缓冲,表示多少毫秒,可不指定参数,用默认的即可;
具体实现原理比较复杂,用到了一些视频序列关联信息,把像素值不变的认为是背景;

注意:在opencv中已经不支持该函数,而是用createBackgroundSubtractorMOG2()替代;如果需要使用可以安装opencv_contrib模块,在其中的bgsegm中保留了该函数;

API使用默认参数即可,调整比较多的是history

在视频中,以时间轴为顺序。如果像素在整个时间轴内不发生变化,则认为是背景,如果发生变化且很频繁,则认为是前景。

去除背景参考论文:

An Improved Adaptive Background Mixture Model for Real-time Tracking with Shadow Detection

在去除背景之前去噪:首先将原始图像进行灰度化,然后经过高斯滤波进行去噪


  
  1. import cv2
  2. import numpy as np
  3. cap = cv2.VideoCapture( 'E:\\video.mp4') #加载视频
  4. bgsubmog = cv2.createBackgroundSubtractorMOG2()
  5. test = cv2.createBackgroundSubtractorMOG2() #测试未经过高斯去噪的图像效果
  6. while True:
  7. ret, frame = cap.read()
  8. if (ret == True) :
  9. # 灰度化处理
  10. cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  11. # 去噪(高斯)
  12. blur = cv2.GaussianBlur(frame, ( 7, 7), 5)
  13. # 去背景
  14. mask = bgsubmog.apply(blur)
  15. test1 = test.apply(frame)
  16. cv2.imshow( 'video', mask)
  17. cv2.imshow( 'test1', test1)
  18. key = cv2.waitKey( 1)
  19. if(key == 27) : #esc键
  20. break
  21. cap.release()
  22. cv2.destroyAllWindows()

形态学处理

腐蚀、膨胀、开运算、闭运算、顶帽、黑帽


  
  1. import cv2
  2. from cv2 import erode
  3. from cv2 import dilate
  4. import numpy as np
  5. cap = cv2.VideoCapture( 'E:\\video.mp4') #加载视频
  6. bgsubmog = cv2.createBackgroundSubtractorMOG2()
  7. # 形态学kernel
  8. kernel = cv2.getStructuringElement(cv2.MORPH_RECT, ( 5, 5))
  9. while True:
  10. ret, frame = cap.read()
  11. if (ret == True) :
  12. # 灰度化处理
  13. cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  14. # 去噪(高斯)
  15. blur = cv2.GaussianBlur(frame, ( 7, 7), 5)
  16. # 去背景
  17. mask = bgsubmog.apply(blur)
  18. # 腐蚀
  19. erode = cv2.erode(mask, kernel)
  20. # 膨胀
  21. dilate = cv2.dilate(erode, kernel, iterations= 2)
  22. # 形态学闭运算,去除图像里面的噪点
  23. close = cv2.morphologyEx(dilate, cv2.MORPH_CLOSE, kernel)
  24. # 查找轮廓
  25. cnts, h = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
  26. # 对所有轮廓进行遍历
  27. for (i, c) in enumerate(cnts):
  28. (x,y,w,h) = cv2.boundingRect(c)
  29. cv2.rectangle(frame, (x,y),(x+w,y+h),( 0, 0, 255), 2)
  30. cv2.imshow( 'video', frame)
  31. # cv2.imshow('close', close)
  32. key = cv2.waitKey( 1)
  33. if(key == 27) : # esc键
  34. break
  35. cap.release()
  36. cv2.destroyAllWindows()

 逻辑处理

通过宽和高去除小的矩形

绘制检测线,计算车的中心点

如果车的中心点落在检测线的有效区域内,则计数加1

显示车辆统计信息

将统计的信息显示在视频中,车辆被重复计数产生的原因:检测线过宽,车辆还未完全出去就又被统计一次,还有一个原因是检测线的位置

传统的车辆检测方法弊端:车速过慢容易造成重复检测,车速过快造成漏检

目前用的较多的方法为深度学习,对车辆进行跟踪

完整程序如下:


  
  1. from asyncio import CancelledError
  2. import cv2
  3. from cv2 import erode
  4. from cv2 import dilate
  5. import numpy as np
  6. # 滤除的最小矩形的范围
  7. min_w = 90
  8. min_h = 90
  9. # 定义检测线的高度,与视频大小有关,视频左上角为(0,0)
  10. line_high = 550
  11. # 线的偏移量
  12. offset = 7
  13. # 统计车的数量
  14. carno = 0
  15. # 存放有效车辆的数组
  16. cars = []
  17. # 求车的中心点
  18. def center( x,y,w,h):
  19. x1 = int(w/ 2)
  20. y1 = int(h/ 2)
  21. cx = x + x1
  22. cy = y + y1
  23. return cx,cy
  24. cap = cv2.VideoCapture( 'E:\\video.mp4') #加载视频
  25. bgsubmog = cv2.createBackgroundSubtractorMOG2()
  26. # 形态学kernel
  27. kernel = cv2.getStructuringElement(cv2.MORPH_RECT, ( 5, 5))
  28. while True:
  29. ret, frame = cap.read()
  30. if (ret == True) :
  31. # 灰度化处理
  32. cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  33. # print(frame.shape) # 获取视频大小的信息
  34. # exit() # 该命令之后的所有程序都不执行
  35. # 去噪(高斯)
  36. blur = cv2.GaussianBlur(frame, ( 7, 7), 5)
  37. # 去背景
  38. mask = bgsubmog.apply(blur)
  39. # 腐蚀
  40. erode = cv2.erode(mask, kernel)
  41. # 膨胀
  42. dilate = cv2.dilate(erode, kernel, iterations= 2)
  43. # 形态学闭运算,去除图像里面的噪点
  44. close = cv2.morphologyEx(dilate, cv2.MORPH_CLOSE, kernel)
  45. # 查找轮廓
  46. cnts, h = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
  47. # 绘制一条检测线
  48. cv2.line(frame, ( 10,line_high),( 1200, line_high),( 255, 255, 0), 3)
  49. # 对所有轮廓进行遍历
  50. for (i, c) in enumerate(cnts):
  51. (x,y,w,h) = cv2.boundingRect(c)
  52. # 对车辆的宽高进行判断,以验证是否为有效的车辆
  53. isValid = (w >= min_w) and ( h >= min_h)
  54. if( not isValid):
  55. continue
  56. # 到这里都是有效的车,绘制车的矩形
  57. cv2.rectangle(frame, (x,y),(x+w,y+h),( 0, 0, 255), 2)
  58. # 存储车的中心点
  59. cpoint = center(x,y,w,h) # 计算车的中心点
  60. cars.append(cpoint) # 将中心点数据存储到cars这个数组中
  61. for (x,y) in cars : # 遍历数组,如果车的中心点落在检测线的有效区域内,则计数+1,然后去除该数组
  62. if ((y > line_high - offset) and (y < line_high + offset)):
  63. carno += 1
  64. cars.remove((x,y))
  65. print(carno)
  66. # 显示统计信息
  67. cv2.putText(frame, "Cars Count:" + str(carno),( 500, 60), cv2.FONT_HERSHEY_SIMPLEX, 2, ( 255, 0, 0), 5)
  68. cv2.imshow( 'video', frame)
  69. # cv2.imshow('close', close)
  70. key = cv2.waitKey( 1)
  71. if(key == 27) : # esc键
  72. break
  73. cap.release()
  74. cv2.destroyAllWindows()


转载:https://blog.csdn.net/qq_45355603/article/details/125286992
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场