Skip to content

Instantly share code, notes, and snippets.

@as8190255
Created September 18, 2018 08:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save as8190255/474512f214aa715f69f1cfad2ea81eb7 to your computer and use it in GitHub Desktop.
Save as8190255/474512f214aa715f69f1cfad2ea81eb7 to your computer and use it in GitHub Desktop.
opencv c++ 摄像头移动物体追踪 [待完善, API版本有兼容问题]
#include "stdafx.h"
#include "OpenTest1.h"
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include <opencv2\opencv.hpp>
using namespace std;
using namespace cv;
//----------------------------------------------------------------MOG2 algorithm MOG2 背景减法
//https://www.youtube.com/user/feelmare
//http://study.marearts.com/2014/04/opencv-study-background-subtraction-and.html
void InitData3() {
//global variables
Mat frame; //current frame
Mat resize_blur_Img;
Mat fgMaskMOG2; //fg mask fg mask generated by MOG2 method
Mat binaryImg;
//Mat TestImg;
Mat ContourImg; //fg mask fg mask generated by MOG2 method
Ptr<BackgroundSubtractor> pMOG2; //MOG2 Background subtractor
pMOG2 = new BackgroundSubtractorMOG2(300, 32, true);//300,0.0);
char fileName[100] = "mm2.avi"; //video\\mm2.avi"; //mm2.avi"; //cctv 2.mov"; //mm2.avi"; //";//_p1.avi";
VideoCapture stream1(fileName); //0 is the id of video device.0 if you have only one camera
//morphology element
Mat element = getStructuringElement(MORPH_RECT, Size(7, 7), Point(3, 3));
//unconditional loop
while (true) {
Mat cameraFrame;
if (!(stream1.read(frame))) //get one frame form video
break;
//Resize
resize(frame, resize_blur_Img, Size(frame.size().width / 3, frame.size().height / 3));
//Blur
blur(resize_blur_Img, resize_blur_Img, Size(4, 4));
//Background subtraction
pMOG2->operator()(resize_blur_Img, fgMaskMOG2, -1);//,-0.5);
///////////////////////////////////////////////////////////////////
//pre procesing
//1 point delete
//morphologyEx(fgMaskMOG2, fgMaskMOG2, CV_MOP_ERODE, element);
morphologyEx(fgMaskMOG2, binaryImg, CV_MOP_CLOSE, element);
//morphologyEx(fgMaskMOG2, testImg, CV_MOP_OPEN, element);
//Shadow delete
//Binary
threshold(binaryImg, binaryImg, 128, 255, CV_THRESH_BINARY);
//Find contour
ContourImg = binaryImg.clone();
//less blob delete
vector< vector< Point> > contours;
findContours(ContourImg,
contours, // a vector of contours
CV_RETR_EXTERNAL, // retrieve the external contours
CV_CHAIN_APPROX_NONE); // all pixels of each contours
vector< Rect > output;
vector< vector< Point> >::iterator itc = contours.begin();
while (itc != contours.end()) {
//Create bounding rect of object
//rect draw on origin image
Rect mr = boundingRect(Mat(*itc));
rectangle(resize_blur_Img, mr, CV_RGB(255, 0, 0));
++itc;
}
///////////////////////////////////////////////////////////////////
//Display
imshow("Shadow_Removed", binaryImg);
imshow("Blur_Resize", resize_blur_Img);
imshow("MOG2", fgMaskMOG2);
if (waitKey(5) >= 0)
break;
}
}
//---------------------------------------------------------------目标追踪之前景建模(定期背景更新模型)
//https://blog.csdn.net/smuevian/article/details/70215946
void process(Mat& frame, Mat &background, Mat &backImage, Mat &foreground, Mat &output, int threshold, double learningRate) {
//当前灰度图像
Mat gray;
//将读取的帧图像转化为灰度图像
cvtColor(frame, gray, CV_BGR2GRAY);
if (background.empty())
//第一帧
gray.convertTo(background, CV_32F);
//背景转为CV_8U格式以便求取和当前帧差的绝对值
background.convertTo(backImage, CV_8U);
//求当前帧与背景的差别
absdiff(backImage, gray, foreground);
//过滤掉前景中与背景差别不大的扰动点 [二值化]
cv::threshold(foreground, output, threshold, 255, THRESH_BINARY_INV);
//更新背景,output作为掩码
accumulateWeighted(gray, background, learningRate, output);
imshow("testBack", background / 255);
}
void InitData2() {
//视频路径
//string FilePath = "E:/study/book/opencv/opencv-2-cookbook-src-master/images/bike.avi";
//读取视频
VideoCapture capture(0);
if (!capture.isOpened()) {
//cout << "Can't open the video!" << endl;
return;
}
//读取帧率
double rate = capture.get(CV_CAP_PROP_FPS);
rate = 25;
bool stop(false);
namedWindow("Extracted Frame");
Mat frame;
int delay = 1000 / rate;
Mat gray; //当前灰度图像
Mat background;//累积的背景图像
Mat backImage; //背景图像
Mat foreground;//前景图像
Mat output;
double learningRate = 0.5;
int threshold = 10;
while (!stop) {
if (!capture.read(frame))
break;
//处理的程序应该放在这里...
process(frame, background, backImage, foreground, output, threshold, learningRate);
//imshow("Extracted Frame", frame);
imshow("Extracted Frame", output);
if (waitKey(delay) > 0)
stop = true;
}
capture.release();
waitKey();
}
//---------------------------------------------------------------最简单的实现差值运算显示内容
Mat background;
int count3 = 0;
//最简单的差值处理
void displayImage(Mat src) {
Mat resultx = src.clone();
Mat gray1, gray2;
Mat diff;
cvtColor(background, gray1, CV_BGR2GRAY);
cvtColor(src, gray2, CV_BGR2GRAY);
absdiff(gray1, gray2, diff);
imshow("DiffImag", diff);
medianBlur(diff, diff, 5);//中值滤波
imshow("medianBlurImag", diff);
Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));
dilate(diff, diff, element);
imshow("dilateImag", diff);
//threshold(diff, diff, 50, 255, CV_THRESH_BINARY);//灰度二值化
//imshow("thresholdImag", diff);
}
void InitData() {
Mat frame;
VideoCapture cap(0);
if (!cap.isOpened())
{
return;
}
while (true)
{
cap >> frame;
if (!frame.empty())
{
count3++;
if (count3 < 10)
{
waitKey(10);
continue;
}
if (count3 == 10) {
background = frame.clone(); //提取第一帧为背景帧
}
displayImage(frame);
imshow("nowImage", frame);
waitKey(10);
}
}
cap.release();
}
OpenTest1::OpenTest1()
{
//InitData();
InitData2();
}
OpenTest1::~OpenTest1()
{
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment