基于opencv的BackgroundSubtractorMOG2目标追踪

举报
风吹稻花香 发表于 2021/06/04 23:53:19 2021/06/04
【摘要】 基于opencv的BackgroundSubtractorMOG2目标追踪 BackgroundSubtractorMOG2是以高斯混合模型为基础的背景/前景分割算法。它是以2004年和2006年Z.Zivkovic的两篇文章为基础的。这个算法的一个特点是它为每一个像素选择一个合适数目的高斯分布。(上一个方法中我们使用是K高斯分布)。这样就会对由于亮度等发生变...


基于opencv的BackgroundSubtractorMOG2目标追踪

BackgroundSubtractorMOG2是以高斯混合模型为基础的背景/前景分割算法。它是以2004年和2006年Z.Zivkovic的两篇文章为基础的。这个算法的一个特点是它为每一个像素选择一个合适数目的高斯分布。(上一个方法中我们使用是K高斯分布)。这样就会对由于亮度等发生变化引起的场景变化产生更好的适应。和前面一样我们需要创建一个背景对象。但在这里我们我们可以选择是否检测阴影。如果detectShadows = True(默认值),它就会检测并将影子标记出来,但是这样做会降低处理速度。影子会被标记为灰色。

这里我们采用opencv实现视频追踪,对于opencv的安装、配置和使用,网上有很多教程,我们这里就不在说明。如果你对opencv不太了解,请自行查资料学习。话归正题,这里我将会分别从Python和c++实现BackgroundSubtractorMOG2,我使用的是opencv3.1linux版本。
Python代码:


    
  1. import numpy as np
  2. import cv2
  3. import time
  4. import datetime
  5. cap = cv2.VideoCapture(0)
  6. kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
  7. fgbg = cv2.createBackgroundSubtractorMOG2()
  8. fourcc = cv2.VideoWriter_fourcc(*'XVID')
  9. frame1 = np.zeros((640,480))
  10. out = cv2.VideoWriter(datetime.datetime.now().strftime("%A_%d_%B_%Y_%I_%M_%S%p")+'.avi',fourcc, 5.0, np.shape(frame1))
  11. while(1):
  12. ret, frame = cap.read()
  13. fgmask = fgbg.apply(frame)
  14. (_,cnts, _) = cv2.findContours(fgmask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  15. maxArea = 0
  16. for c in cnts:
  17. Area = cv2.contourArea(c)
  18. if Area < maxArea :
  19. #if cv2.contourArea(c) < 500:
  20. (x, y, w, h) = (0,0,0,0)
  21. continue
  22. else:
  23. if Area < 1000:
  24. (x, y, w, h) = (0,0,0,0)
  25. continue
  26. else:
  27. maxArea = Area
  28. m=c
  29. (x, y, w, h) = cv2.boundingRect(m)
  30. cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
  31. out.write(frame)
  32. cv2.imshow('frame',frame)
  33. k = cv2.waitKey(30)&0xff
  34. if k==27:
  35. break
  36. out.release()
  37. cap.release()
  38. cv2.destoryAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

c++版本:
VideoDetect.h


    
  1. #pragma once
  2. #include <opencv2/opencv.hpp>
  3. #include <opencv2/highgui.hpp>
  4. using namespace std;
  5. using namespace cv;
  6. enum VIDEOTYPE
  7. {
  8. CAMERAVIDEO/*摄像头*/,FILEVIDEO/*视频*/
  9. };
  10. class MOG2Detector
  11. {
  12. public:
  13. MOG2Detector();
  14. ~MOG2Detector();
  15. /*
  16. VIDEOTYPE 指定摄像头或者文件
  17. path 文件路径
  18. WindowName opencv可视化窗口名称
  19. */
  20. MOG2Detector(VIDEOTYPE type,char * path = "E:/image/s.avi",char * WindowName = "Video");
  21. //开始
  22. void startDecect();
  23. private:
  24. char * WinName;
  25. VIDEOTYPE VideoType;
  26. cv::VideoCapture capture;
  27. cv::Ptr<cv::BackgroundSubtractorMOG2> fgbg;
  28. };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

VideoDetect.cpp:


    
  1. #include "stdafx.h"
  2. #include "MOG2Detector.h"
  3. MOG2Detector::MOG2Detector()
  4. {
  5. }
  6. MOG2Detector::~MOG2Detector()
  7. {
  8. }
  9. MOG2Detector::MOG2Detector(VIDEOTYPE type, char * path, char * WindowName)
  10. {
  11. if (type == CAMERAVIDEO)
  12. {
  13. capture.open(0);
  14. }
  15. else if (type == FILEVIDEO)
  16. {
  17. capture.open("E:/image/s.avi");
  18. }
  19. else
  20. {
  21. cout << "Type is error, you can input CAMERAVIDEO or FILEVIDEO" << endl;
  22. return;
  23. }
  24. if (!capture.isOpened())
  25. {
  26. std::cout << "video camera capture open fail! \n" << std::endl;
  27. exit(1);
  28. }
  29. fgbg = cv::createBackgroundSubtractorMOG2();
  30. WinName = WindowName;
  31. }
  32. void MOG2Detector::startDecect()
  33. {
  34. cv::Mat frame, fgmask;
  35. //cnts存储边缘信息
  36. std::vector<std::vector<cv::Point> > cnts;
  37. cv::namedWindow("video", 1);
  38. while (1)
  39. {
  40. capture.read(frame);
  41. fgbg->apply(frame, fgmask);
  42. //检测每一帧边缘
  43. findContours(fgmask, cnts, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
  44. float Area;
  45. Rect rect;
  46. vector<Point> m;
  47. for (int i = cnts.size() - 1; i >= 0; i--)
  48. {
  49. vector<Point> c = cnts[i];
  50. //获取面积
  51. Area = contourArea(c);
  52. if (Area < 50)//50这个值根据需求设定,这里指的是目标的大小
  53. {
  54. continue;
  55. }
  56. else
  57. {
  58. m = c;
  59. }
  60. rect = boundingRect(m);
  61. rectangle(frame, rect, Scalar(0, 255, 0), 2);
  62. }
  63. resize(frame, frame, Size(480, 320));
  64. imshow("video", frame);
  65. char c = waitKey(33);
  66. if (c == 27)
  67. break;
  68. }
  69. //释放资源
  70. capture.release();
  71. cv::destroyWindow("video");
  72. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80

最近比较忙,等到有时间在完善这些代码,添加注释!
实验结果
实验结果

文章来源: blog.csdn.net,作者:网奇,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/jacke121/article/details/78365682

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。