您的位置:首页 > 运维架构

OPencv笔记2:光流法检测——特征点

2013-04-26 14:23 295 查看
#include "stdafx.h"
#include <highgui.h>
#include <cxcore.h>
#include <cv.h>
#include <stdio.h>
#define max_corner 100

int main(int argc, char* argv[])
{
CvCapture * capture = cvCaptureFromAVI("rgb.avi");
IplImage * cur_frame = NULL;
IplImage * cur_copy = NULL;
IplImage * cur_mov = NULL;
IplImage * cur_gray = NULL;
IplImage * pre_gray = NULL;
IplImage * TempFrame = NULL;
IplImage * TempFrame1 = NULL;
IplImage * pre_pyramid = NULL;
IplImage * cur_pyramid = NULL;
CvPoint2D32f pre_feature[max_corner];
CvPoint2D32f cur_feature[max_corner];
int corner_num = max_corner;
int reverse_num = 0;
int frmnum = 0;
char FeatureFound[max_corner];
CvPoint Point1 = cvPoint(160,30);
CvRect ROIRect = cvRect(Point1.x,Point1.y,300,210);
CvRect ROIRect1 = cvRect(Point1.x,Point1.y,90,180);
CvRect ROIRect2 = cvRect(Point1.x+ROIRect1.width,Point1.y,135,210);
CvRect ROIRect3 = cvRect(Point1.x+ROIRect1.width+ROIRect2.width,Point1.y,80,210);
//	cvNamedWindow("pre_feature",1);
cvNamedWindow("cur_feature",1);
cvNamedWindow("cur_mov",1);
while(cur_frame = cvQueryFrame(capture))
{
frmnum++;
//cur_frame->origin = 0;
//	cvFlip(cur_frame,NULL,0);
if(frmnum == 1){
cur_copy = cvCreateImage(cvGetSize(cur_frame),IPL_DEPTH_8U,3);
cur_mov = cvCreateImage(cvGetSize(cur_frame),IPL_DEPTH_8U,3);
}
cvCopy(cur_frame,cur_copy,0);//cur_copy是用来标记角点的图像
cvCopy(cur_frame,cur_mov,0);//cur_mov是用来标记角点运动的图像
//	cvShowImage("src",cur_frame);
//		cvWaitKey(0);
//cvRectangle(cur_frame,cvPoint(430,30),cvPoint(430+ROIRect3.width,30+ROIRect3.height),CV_RGB(255,0,0),3,8);
/*cvNamedWindow("cur_frame",1);
cvShowImage("cur_frame",cur_frame);
cvWaitKey(1);
cvDestroyWindow("cur_frame");*/
cvSetImageROI(cur_frame,ROIRect);

if(frmnum == 1)
{
cur_gray = cvCreateImage(cvGetSize(cur_frame),IPL_DEPTH_8U,1);
pre_gray = cvCreateImage(cvGetSize(cur_frame),IPL_DEPTH_8U,1);
TempFrame = cvCreateImage(cvGetSize(cur_frame),IPL_DEPTH_32F,1);
TempFrame1 = cvCreateImage(cvGetSize(cur_frame),IPL_DEPTH_32F,1);
pre_pyramid = cvCreateImage(cvGetSize(cur_frame),IPL_DEPTH_32F,1);
cur_pyramid = cvCreateImage(cvGetSize(cur_frame),IPL_DEPTH_32F,1);
cvCvtColor(cur_frame,cur_gray,CV_BGR2GRAY);
cvCopy(cur_gray,pre_gray,0);//保存第一帧
}

else //if((frmnum-1)%15==0)
{
/*cvNamedWindow("preGRAY",1);
cvShowImage("preGRAY",pre_gray);
cvWaitKey(1);
cvDestroyWindow("preGRAY");*/
cvCvtColor(cur_frame,cur_gray,CV_BGR2GRAY);
//cvRectangle(cur_gray,Point1,cvPoint(Point1.x+ROIRect.width,Point1.y+ROIRect.height),CV_RGB(255,0,0),3,8);
/*cvNamedWindow("ROIGRAY",1);
cvShowImage("ROIGRAY",cur_gray);
cvWaitKey(1);
cvDestroyWindow("ROIGRAY");
cvNamedWindow("preGRAY1",1);
cvShowImage("preGRAY1",pre_gray);
cvWaitKey(1);
cvDestroyWindow("preGRAY1");*/

//找角   点
cvGoodFeaturesToTrack(
pre_gray,//输入图像,8-位或浮点32-比特,单通道
TempFrame,//临时浮点32-位图像,尺寸与输入图像一致
TempFrame1, //另外一个临时图像,格式与尺寸与 eig_image 一致
pre_feature,//输出参数,检测到的角点
&corner_num,//
0.01, //经验值,最大最小特征值的乘法因子。定义可接受图像角点的最小质量因子。
3,//0.01, //经验值,限制因子。得到的角点的最小距离。使用 Euclidian 距离
NULL);
//在cur_copy(彩色图像)中标出上一帧的角点位置
for(int i=0;i<corner_num;i++)
{
int x = pre_feature[i].x + Point1.x;
int y = pre_feature[i].y + Point1.y;//因为标记时是以主窗口的左上角为起始点的,而非兴趣区域的坐标原点
cvLine(cur_copy,cvPoint(x,y),cvPoint(x,y),CV_RGB(255,0,0),3,8,0);//画出角点
}
//		cvNamedWindow("pre_feature",1);
//	cvShowImage("pre_feature",cur_copy);
//	cvWaitKey(0);
//		cvDestroyWindow("pre_feature");

//找到当前帧中与上一帧匹配的角点位置
if(corner_num==0)
return 0;
CvSize ModelWind = cvSize(3,3);
CvTermCriteria termination_criteria = cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.3 );
cvCalcOpticalFlowPyrLK( //&&&金字塔光流法跟踪
pre_gray,					cur_gray,
pre_pyramid,//第一帧的金字塔缓存
cur_pyramid, //第二帧的金字塔缓存
pre_feature,//需要发现光流的点集
cur_feature,//包含新计算出来的位置的 点集
corner_num,

ModelWind, //每个金字塔层的搜索窗口尺寸
5, //经验值,金字塔层数
FeatureFound,//数组。如果对应特征的光流被发现,数组中的每一个元素都被设置为 1, 否则设置为 0。
0,//经验值
termination_criteria,//经验值
0 );
//在cur_copy(彩色图像)中标出当前帧匹配到的角点位置
for(int i=0;i<corner_num;i++)
{
int x1 = cur_feature[i].x + Point1.x;
int y1 = cur_feature[i].y + Point1.y;//因为标记时是以主窗口的左上角为起始点的,而非兴趣区域的坐标原点
cvLine(cur_copy,cvPoint(x1,y1),cvPoint(x1,y1),CV_RGB(0,255,0),3,8,0);
}
//				cvNamedWindow("cur_feature",1);
cvShowImage("cur_feature",cur_copy);
cvWaitKey(0);
//				cvDestroyWindow("cur_feature");
//统计角点的运动方向
int mov_corner = 0;
int vy = 0;
reverse_num = 0;
for(int i=0;i<corner_num;i++){
if(FeatureFound[i]==0)
continue;
int x = abs(pre_feature[i].x);
int y = abs(pre_feature[i].y);
int x1 = abs(cur_feature[i].x);
int y1 = abs(cur_feature[i].y);
double v = sqrt((double)((y1 - y)*(y1 - y) + (x1 - x)*(x1 - x)));
int abs_vx = abs(x1 - x);
vy = y1 - y;
int abs_vy = abs(vy);
if(abs_vy >= 50)
continue;
if(v <= 5 && abs(vy) <= 3)
continue;
mov_corner++;
//if(vy < 0)
{
reverse_num++;

x += Point1.x;
y += Point1.y;//因为标记时是以主窗口的左上角为起始点的,而非兴趣区域的坐标原点
cvLine(cur_mov,cvPoint(x,y),cvPoint(x,y),CV_RGB(255,0,0),3,8,0);
x1 += Point1.x;
y1 += Point1.y;//因为标记时是以主窗口的左上角为起始点的,而非兴趣区域的坐标原点
cvLine(cur_mov,cvPoint(x,y),cvPoint(x1,y1),CV_RGB(255,255,255),1,8,0);
}

}
//				cvNamedWindow("cur_mov",1);
cvShowImage("cur_mov",cur_mov);
cvWaitKey(100);
//				cvDestroyWindow("cur_mov");

cvCopy(cur_gray,pre_gray,0);
}

}
cvReleaseImage(&cur_frame);
cvReleaseImage(&cur_copy);
cvReleaseImage(&cur_mov);
cvReleaseImage(&cur_gray);
cvReleaseImage(&pre_gray);
cvReleaseImage(&TempFrame);
cvReleaseImage(&TempFrame1);
cvReleaseImage(&pre_pyramid);
cvReleaseImage(&cur_pyramid);
cvReleaseCapture(&capture);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐