opencv质心以及轮廓的识别,视频的跟踪处理二值化
2017-09-10 13:44
555 查看
- #include "stdafx.h"
- #include <iostream>
- #include <opencv2/core/core.hpp>
- #include <opencv/cv.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include <time.h>
- #include <math.h>
- #include <ctype.h>
- #include <stdio.h>
- #include <string.h>
- #include<windows.h>
- #include <mmsystem.h>
- //跟踪参数
- const double MHI_DURATION = 0.5;//最大跟踪时间
- const double MAX_TIME_DELTA = 0.5;
- const double MIN_TIME_DELTA = 0.05;
- const int N = 3;
- const int CONTOUR_MAX_AERA = 100;//矩形面积
- IplImage **buf = 0;
- int last = 0;
- int flag;
- IplImage *mhi = 0; // MHI: motion history image
- CvConnectedComp *cur_comp, min_comp;
- CvConnectedComp comp;
- CvMemStorage *storage;
- CvPoint pt[4];
- // img – 输入视频帧
- // dst – 检测结果
- using namespace cv;
- using namespace std;
- Mat src;
- Mat src_gray;
- int thresh = 30;
- int max_thresh = 255;
- void update_mhi(IplImage* img, IplImage* dst, int diff_threshold)
- {
- double timestamp = clock() / 100.; //获取当前时间
- CvSize size = cvSize(img->width, img->height);
- int i, idx1, idx2;
- IplImage* silh;
- IplImage* pyr = cvCreateImage(cvSize((size.width & -2) / 2, (size.height & -2) / 2), 8, 1);
- CvMemStorage *stor;
- CvSeq *cont;
- if (!mhi || mhi->width != size.width || mhi->height != size.height)
- {
- if (buf == 0)
- {
- buf = (IplImage**)malloc(N*sizeof(buf[0]));//动态内存分配
- memset(buf, 0, N*sizeof(buf[0]));
- }
- for (i = 0; i < N; i++)
- {
- cvReleaseImage(&buf[i]);
- buf[i] = cvCreateImage(size, IPL_DEPTH_8U, 1);
- cvZero(buf[i]);
- }
- cvReleaseImage(&mhi);
- mhi = cvCreateImage(size, IPL_DEPTH_32F, 1);
- cvZero(mhi);
- }
- cvCvtColor(img, buf[last], CV_BGR2GRAY); //rgb->gray
- idx1 = last;
- idx2 = (last + 1) % N;
- last = idx2;
- // 做帧差
- silh = buf[idx2];
- cvAbsDiff(buf[idx1], buf[idx2], silh); //两帧差异
- // 对差图像做二值化
- cvThreshold(silh, silh, 30, 255, CV_THRESH_BINARY); //src(x,y)>threshold ,dst(x,y) = max_value; 否则,dst(x,y)=0;
- cvUpdateMotionHistory(silh, mhi, timestamp, MHI_DURATION); //更新像素点的运动历史
- cvCvtScale(mhi, dst, 255. / MHI_DURATION,
- (MHI_DURATION - timestamp)*255. / MHI_DURATION);//timestamp是时间戳;MHI_DURATION,获得的是当前时间
- cvCvtScale(mhi, dst, 255. / MHI_DURATION, 0);
- // 中值滤波,消除小的噪声
- cvSmooth(dst, dst, CV_MEDIAN, 3, 0, 0, 0);
- // 向下采样,去掉噪声
- cvPyrDown(dst, pyr, 7);
- cvDilate(pyr, pyr, 0, 1); // 做膨胀操作,消除目标的不连续空洞
- cvPyrUp(pyr, dst, 7);
- //
- vector<vector<Point> > contours;
- vector<Vec4i> hierarchy;
- Mat canny_output(dst);
- // 找到所有轮廓
- findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
- //计算轮廓矩
- vector<Moments> mu(contours.size() );
- for( int i = 0; i < contours.size(); i++ )
- {
- mu[i] = moments( contours[i], false );
- }
- //计算轮廓的质心
- vector<Point2f> mc( contours.size() );
- for( int i = 0; i < contours.size(); i++ )
- {
- mc[i] = Point2d( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 );
- }
- // 直接使用CONTOUR中的矩形来画轮廓
- int order = 1;
- Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
- for( int i = 0; i< contours.size(); i++ )
- {
- Scalar color = Scalar( 255, 0, 0);
- double area = mu[i].m00;//面积
- Rect ret1 = boundingRect(Mat(contours[i])); //获取目标序列号放置位置
- if(area > 50) //剔除小面积轮廓
- {
- drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
- circle( drawing, mc[i], 5, Scalar( 0, 0, 255), -1, 8, 0 );
- rectangle(drawing, boundingRect(contours.at(i)), cvScalar(0,255,0));
- char tam[100];
- sprintf(tam, "(%0.0f,%0.0f)",mc[i].x,mc[i].y);
- putText(drawing, tam, Point(mc[i].x, mc[i].y), FONT_HERSHEY_SIMPLEX, 0.4, cvScalar(255,0,255),1);
- char tam1[100];
- sprintf(tam1, "%d",order++);
- putText(drawing, tam1, Point(ret1.x+ret1.width, ret1.y+ret1.height), FONT_HERSHEY_SIMPLEX, 0.4, cvScalar(0,255,255),1);
- }
- }
- namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
- imshow( "Contours", drawing );
- moveWindow("Contours",0,0);
- //waitKey(0);
- }
- int main(int argc, char** argv)
- {
- IplImage* motion = 0;
- CvCapture* capture = 0; //视频获取结构
- while (1){
- //capture = cvCreateCameraCapture(0);//读摄像头视频
- capture = cvCreateFileCapture("C:\\Users\\Lijunliang\\Desktop\\0.5X.avi"); //读本地视频文件
- if (capture)
- {
- cvNamedWindow("Motion", 1);
- for (;;)
- {
- SYSTEMTIME sys;//获取当前系统时间
- GetLocalTime(&sys);
- char* t_y = new char[128];
- sprintf(t_y, ("%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d"),
- sys.wYear, sys.wMonth, sys.wDay,
- sys.wHour, sys.wMinute, sys.wSecond);
- CvFont font;
- cvInitFont(&font, CV_FONT_HERSHEY_COMPLEX, 0.5, 0.5, 0, 2, 8);
- IplImage* image;
- if (!cvGrabFrame(capture)) //从摄像头或者视频文件中抓取帧
- break;
- image = cvRetrieveFrame(capture); //取回由函数cvGrabFrame抓取的图像,返回由函数cvGrabFrame 抓取的图像的指针
- if (image)
- {
- if (!motion)
- {
- motion = cvCreateImage(cvSize(image->width, image->height), 8, 1);
- cvZero(motion);
- motion->origin = image->origin; ///* 0 - 顶—左结构, 1 - 底—左结构 (Windows bitmaps 风格) */
- }
- }
- update_mhi(image, motion, 6);
- cvPutText(image, t_y, cvPoint(10, 25), &font, CV_RGB(255, 0, 0));
- //cvShowImage("Motion", image);
- if (cvWaitKey(10) >= 0)
- break;
- }
- cvReleaseCapture(&capture);
- //cvDestroyWindow("Motion");
- }
- }
- return 0;
- }
- 主要理解Opencv运动跟踪,以及质点提取等方法探讨.
阅读更多
相关文章推荐
- opencv 图片基本处理(灰度化,反色,二值化,膨胀腐蚀以及ROI的copy等)
- iOS-OpenCV之视频流身份证轮廓识别
- 【OpenCV学习笔记】三十一、轮廓特征属性及应用(八)——颜色物体识别与跟踪
- opencv颜色识别并用二值化处理
- 初学图像处理+opencv----跟踪视频中运动物体
- 【IOS】OpenCV摄像头实时图像处理(灰度,二值化,轮廓检测)
- 视频二值化处理基本方法以及简单代码实现
- 《cv中文参考手册-图像轮廓处理-结构分析与形状识别-获取各个对象的质心》HuMoments
- 代码C++, opencv实现人脸识别,人脸检测,人脸匹配,视频中的人脸检测,摄像头下的人脸检测等
- opencv轮廓提取、轮廓识别相关要点
- (7)Air Band数字图像处理基础-边缘检测和轮廓跟踪
- opencv---视频处理--拌线检测(越线检测)
- 基于OPENCV的视频图像处理算法和应用
- openCV中的视频处理。。。
- qt+opencv实现拍照,打开视频,图像处理操作
- Python-OpenCV 处理图像(六)(七)(八):对象识别 图像灰度化处理 图像二值化处理
- opencv-python人眼识别图像处理基础
- OpenCv中avi视频的读取问题,以及内部格式要求
- 图像处理与计算机视觉:基础,经典以及最近发展(3)计算机视觉中的信号处理与模式识别
- opencv 视频处理框架,面向对象,简单实用,可扩展