博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Demo1:视频人体检测
阅读量:4298 次
发布时间:2019-05-27

本文共 13754 字,大约阅读时间需要 45 分钟。




/*#include
using namespace cv;int main(){ Mat img = imread("1.jpg"); imshow("测试图片",img); waitKey(50); return 0;}*//*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%% 欢迎到www.opencvchina.com下载源代码和资料 %%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*//* * Code written by Lya (GeckoGeek.fr) *///#include "stdafx.h"#include "opencv/highgui.h"#include "opencv/cv.h" #include
#include
#include
// Maths methods#define max(a, b) ((a) > (b) ? (a) : (b))#define min(a, b) ((a) < (b) ? (a) : (b)) #define abs(x) ((x) > 0 ? (x) : -(x))#define sign(x) ((x) > 0 ? 1 : -1)// Step mooving for object min & max#define STEP_MIN 5 #define STEP_MAX 100 //轮廓区域最小面积int detectarea=100;IplImage *image;IplImage *im; // Position of the object we overlayCvPoint objectPos = cvPoint(-1, -1); //目标当前位置// Color tracked and our tolerance towards itint h = 0, s = 0, v = 0, tolerance = 10;CvPoint temp ;int T_HSV[3]={111,111,23};// int HSV[3]={177,185,120}; int HSV[3]={179,79,81}; int HSV_f[3]={177,185,120};//int count=0;int countd=0; //在drawbody函数用到CvPoint HEAD;//上次的头部坐标CvPoint HAND[5];//用于存储上次的手部坐标CvPoint FOOT[5];//用于存储上次的脚坐标CvPoint point[10];//存储目标位置CvScalar color=CV_RGB(255,158,97); // Next position of the object we overlay CvPoint objectNextPos;//此函数用于画出image图片中是HSV[]色彩的所有轮廓,HSV[]是感兴趣的三通道色彩CvPoint ditalcontours(IplImage* image, int *nbPixels,int HSV[],int detectarea) { void drawcontours(IplImage* mask,IplImage* image); int x, y; //CvScalar pixel; IplImage *hsv, *mask; IplConvKernel *kernel; int sommeX = 0, sommeY = 0; *nbPixels = 0; // Create the mask &initialize it to white (no color detected) mask = cvCreateImage(cvGetSize(image), image->depth, 1); // Create the hsv image hsv = cvCloneImage(image); cvCvtColor(image, hsv, CV_BGR2HSV); // We create the mask cvInRangeS(hsv, cvScalar(HSV[0] - tolerance -1, HSV[1] - tolerance,0), cvScalar(HSV[0] + tolerance -1, HSV[1] + tolerance, 255), mask); //cvInRangeS(1,2,3,4)此函数就是从hsv图像中选出在范围在2到3之间的像素点,选出来符合的置为1,否则置为0。 //最后把二值化图像存在mask中 //cvShowImage("mask第一步", mask);//展示mask效果 // Create kernels for the morphological operation kernel = cvCreateStructuringElementEx(5, 5, 2, 2, CV_SHAPE_CROSS); //生成膨胀和溶解结构 kernel // Morphological opening (inverse because we have white pixels on black background) cvDilate(mask, mask, kernel, 1); //膨胀 cvErode(mask, mask, kernel, 1); //溶解 // We go through the mask to look for the tracked object and get its gravity center for(x = 0; x < mask->width; x++) { for(y = 0; y < mask->height; y++) { // If its a tracked pixel, count it to the center of gravity's calcul if(((uchar *)(mask->imageData + y*mask->widthStep))[x] == 255) { sommeX += x; //目标像素点x坐标总和 sommeY += y; //目标像素点y坐标总和 (*nbPixels)++; //目标像素点个数 } } } // Show the result of the mask image// cvShowImage("Mask第二部", mask); drawcontours(mask,image); // We release the memory of kernels cvReleaseStructuringElement(&kernel); // We release the memory of the mask cvReleaseImage(&mask); // We release the memory of the hsv image cvReleaseImage(&hsv); // If there is no pixel, we return a center outside the image, else we return the center of gravity if(*nbPixels > 0) return cvPoint((int)(sommeX / (*nbPixels)), (int)(sommeY / (*nbPixels))); //目标像素点的质心 else return cvPoint(-1, -1);} //此函数用于勾画黑白图mask的轮廓void drawcontours(IplImage* mask,IplImage* image){IplConvKernel *kernel = cvCreateStructuringElementEx(5, 5, 2, 2, CV_SHAPE_ELLIPSE);IplImage* pyr = cvCreateImage( cvSize((mask->width )/2, (mask->height)/2), 8, 1 ); CvMemStorage *stor; CvSeq *cont; // 中值滤波,消除小的噪声 cvSmooth( mask, mask, CV_MEDIAN, 3, 0, 0, 0 ); cvPyrDown( mask, pyr, CV_GAUSSIAN_5x5 );// 向下采样,去掉噪声,图像是原图像的四分之一 ,mask是pyr面积的四倍,要不然会内存溢出cvDilate( pyr, pyr, 0, 1 ); // 做膨胀操作,消除目标的不连续空洞 cvPyrUp( pyr,mask, CV_GAUSSIAN_5x5 );// 向上采样,恢复图像,图像是原图像的四倍 cvErode(mask, mask, kernel, 1); //溶解cvShowImage("Mask第三部", mask);// 下面的程序段用来找到轮廓 // Create dynamic structure and sequence. stor = cvCreateMemStorage(0); cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , stor); // 找到所有轮廓 //cvFindContors( dst, stor, &cont, sizeof(CvContour), //CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0)); cvFindContours( mask, stor, &cont, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0)); // 直接使用CONTOUR中的矩形来画轮廓 /* double area=0; CvSeq *contemp=cont;for(;contemp;contemp = contemp->h_next) { CvRect temp = ((CvContour*)cont)->rect; if(temp.height * temp.width>area) area=temp.height * temp.width;} */ for(int num=0;cont;cont = cont->h_next) { CvRect r = ((CvContour*)cont)->rect;if(r.height * r.width > detectarea) // 面积小的方形抛弃掉 { point[num%10].x=(2*r.x + r.width)/2; point[num%10].y= (2*r.y + r.height)/2; //cvRectangle( image, cvPoint(r.x,r.y), cvPoint(r.x + r.width, r.y + r.height), CV_RGB(255,0,0), 1, CV_AA,0); //给指定区域画轮廓 cvCircle(im,point[num%10],10,color,CV_FILLED,CV_AA,0);printf( "轮廓的开始位置 %d.%d ,中心x,y = %d.%d ,个数是%d\n",r.x,r.y ,point[num%10].x,point[num%10].y ,num); num++; } } cvReleaseStructuringElement(&kernel); // free memory cvReleaseMemStorage(&stor); // We release the memory of the hsv image cvReleaseImage(&pyr);} int SMINY(CvPoint P[]){ int i=0; int MAX=1000,c=0; while(P[i].x&&P[i].y) { if(P[i].y
0&&P[i].x>0) { MAX=P[i].y; c=i; } i++; } return c;}int SMINX(CvPoint P[]){ int i=0; int MAX=1000,c=0; while(P[i].x&&P[i].y) { if(P[i].x
0&&P[i].y>0) { MAX=P[i].x; c=i; } i++; } return c; }int SMAXX(CvPoint P[]){ int i=0; int MAX=0,c=0;while(P[i].x&&P[i].y) { if(P[i].x>MAX&&P[i].y>0) { MAX=P[i].x; c=i; } i++; }return c;}void drawupbody(CvPoint P[],CvPoint center,CvPoint P1[]){ int i=0; int c=0; CvPoint pt1_Rect; CvPoint pt2_Rect; CvPoint head; CvPoint body; CvPoint hand[2]; CvPoint foot[2]; char key='e'; int radius=0; //char str[15]; //CvFont font; c=SMINY(P); head.x=P[c].x; head.y=P[c].y; c=SMINX(P); hand[0].x=P[c].x; hand[0].y=P[c].y; c=SMAXX(P); hand[1].x=P[c].x; hand[1].y=P[c].y; body.x=center.x; body.y=center.y; c=SMINX(P1); foot[0].x=P1[c].x; foot[0].y=P1[c].y; c=SMAXX(P1); foot[1].x=P1[c].x; foot[1].y=P1[c].y; //对头部,手臂点 空间位置跳跃控制。减少乱跳现象 if(countd++<4) {HEAD.x=head.x; HEAD.y=head.y; for(int i=0;i<2;i++) { HAND[i].x=hand[i].x; HAND[i].y=hand[i].y; FOOT[i].x=foot[i].x; FOOT[i].y=foot[i].y; } } // printf( "轮廓的中心x,y = %d.%d \n", abs(HEAD.x-head.x),abs(HEAD.y-head.y)); if( abs(HEAD.x-head.x)>40||abs(HEAD.y-head.y)>40) {head.x=HEAD.x; head.y=HEAD.y; } HEAD.x=head.x; HEAD.y=head.y; for(int i=0;i<2;i++) { if( abs(HAND[i].x-hand[i].x)>60||abs(HAND[i].y-hand[i].y)>60) { hand[i].x=HAND[i].x; hand[i].y=HAND[i].y; } if( abs(FOOT[i].x-foot[i].x)>100||abs(FOOT[i].y-foot[i].y)>100) { foot[i].x=FOOT[i].x; foot[i].y=FOOT[i].y; } HAND[i].x=hand[i].x; HAND[i].y=hand[i].y; FOOT[i].x=foot[i].x; FOOT[i].y=foot[i].y; } //对头部,手臂点 空间位置跳跃控制。减少乱跳现象// printf("右手坐标是%d,%d",hand[1].x,hand[1].y); IplImage *img=cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,3); cvNamedWindow("image",CV_WINDOW_AUTOSIZE); pt1_Rect.x=0; pt1_Rect.y=0; pt2_Rect.x=600; pt2_Rect.y=600; color=CV_RGB(97,158,225); cvRectangle(img,pt1_Rect,pt2_Rect,color,CV_FILLED,CV_AA,0); color=CV_RGB(255,158,97); radius=35; cvCircle(img,head,radius,color,CV_FILLED,CV_AA,0);//头部 pt1_Rect.x=body.x-30; pt1_Rect.y=body.y-20; pt2_Rect.x=body.x+30; pt2_Rect.y=body.y+80; cvRectangle(img,pt1_Rect,pt2_Rect,color,CV_FILLED,CV_AA,0);//身体 cvLine(img,head,body,color,10,CV_AA,0);//颈部 color=CV_RGB(255,255,0); pt1_Rect.x=body.x-30; pt1_Rect.y=body.y-20; cvLine(img,pt1_Rect,hand[0],color,30,CV_AA,0);//手臂1 pt1_Rect.x=body.x+30; pt1_Rect.y=body.y-20; cvLine(img,pt1_Rect,hand[1],color,30,CV_AA,0);//手臂2 color=CV_RGB(255,255,0); pt1_Rect.x=body.x-30; pt1_Rect.y=body.y+70; cvLine(img,pt1_Rect,foot[0],color,30,CV_AA,0);//腿1 pt1_Rect.x=body.x+30; pt1_Rect.y=body.y+70; cvLine(img,pt1_Rect,foot[1],color,30,CV_AA,0);//腿1 cvShowImage("image",img); cvReleaseImage(&img);}//此函数截取人物部分,再来跟踪颜色质心对于人物跟踪更加精准void ditaldeal(IplImage* image, CvPoint t,int *nbPixels,int HSV[]){ int tem=*nbPixels; CvPoint h[5],f[5];im=cvCreateImage(cvGetSize(image),image->depth,image->nChannels);cvCopy(image,im,NULL);//cvSetImageROI(im,cvRect(t.x-70,t.y-150,140,400));detectarea=100;//最小区域面积的设定temp =ditalcontours(im,nbPixels,HSV,detectarea);for(int i=0;i<5;i++){h[i].x=point[i].x; h[i].y=point[i].y; }//找上身的点for(int i=0;i<5;i++){point[i].x=NULL; point[i].y=NULL; }//清空point//cvCopy(image,im,NULL);detectarea=50;temp =ditalcontours(im,nbPixels,HSV_f,detectarea);for(int i=0;i<5;i++){f[i].x=point[i].x; f[i].y=point[i].y; //printf("下半身的第%d点是x=%d,y=%d",i,f[i].x,f[i].y);}//找下身的点for(int i=0;i<5;i++){point[i].x=NULL; point[i].y=NULL; }//注意清空point[],以免下一帧有影响drawupbody(h,objectNextPos,f); }//此函数用于跟踪HSV[]三通道色彩像素点的质心CvPoint binarisation(IplImage* image, int *nbPixels,int HSV[]) { int x, y; //CvScalar pixel; IplImage *hsv, *mask; IplConvKernel *kernel; int sommeX = 0, sommeY = 0; *nbPixels = 0; // Create the mask &initialize it to white (no color detected) mask = cvCreateImage(cvGetSize(image), image->depth, 1); // Create the hsv image hsv = cvCloneImage(image); cvCvtColor(image, hsv, CV_BGR2HSV); // We create the mask cvInRangeS(hsv, cvScalar(HSV[0] - tolerance -1, HSV[1]- tolerance, 0), cvScalar(HSV[0] + tolerance -1, HSV[1] + tolerance, 255), mask); //cvInRangeS(1,2,3,4)此函数就是从hsv图像中选出在范围在2到3之间的像素点,选出来符合的置为1,否则置为0。 //最后把二值化图像存在mask中 //cvShowImage("mask第一步", mask);//展示mask效果 // Create kernels for the morphological operation kernel = cvCreateStructuringElementEx(5, 5, 2, 2, CV_SHAPE_ELLIPSE); //生成膨胀和溶解结构 kernel // Morphological opening (inverse because we have white pixels on black background) cvDilate(mask, mask, kernel, 1); //膨胀 cvErode(mask, mask, kernel, 1); //溶解 // We go through the mask to look for the tracked object and get its gravity center for(x = 0; x < mask->width; x++) { for(y = 0; y < mask->height; y++) { // If its a tracked pixel, count it to the center of gravity's calcul if(((uchar *)(mask->imageData + y*mask->widthStep))[x] == 255) { sommeX += x; //目标像素点x坐标总和 sommeY += y; //目标像素点y坐标总和 (*nbPixels)++; //目标像素点个数 } } } // Show the result of the mask image //cvShowImage("Mask第二部", mask); // We release the memory of kernels cvReleaseStructuringElement(&kernel); // We release the memory of the mask cvReleaseImage(&mask); // We release the memory of the hsv image cvReleaseImage(&hsv); // If there is no pixel, we return a center outside the image, else we return the center of gravity if(*nbPixels > 0) return cvPoint((int)(sommeX / (*nbPixels)), (int)(sommeY / (*nbPixels))); //目标像素点的质心 else return cvPoint(-1, -1);}//此函数用于给指定点的质心打点void addObjectToVideo(IplImage* image, CvPoint objectNextPos, int nbPixels) { int objectNextStepX, objectNextStepY; CvPoint t; t.x=objectNextPos.x; t.y=objectNextPos.y; // Draw an object (circle) centered on the calculated center of gravity if (nbPixels > 10) cvDrawCircle(image, objectNextPos, 10, CV_RGB(255, 0, 0), -1); cvRectangle( image, cvPoint(t.x-50,t.y-120), cvPoint(t.x + 50, t.y + 90), CV_RGB(255,0,0), 1, CV_AA,0); // We show the image on the window } //得到鼠标点击处的HSV[]三通道色彩void getObjectColor(int event, int x, int y, int flags, void *param = NULL) { // Vars CvScalar pixel; IplImage *hsv; if(event == CV_EVENT_LBUTTONUP) { // Get the hsv image hsv = cvCloneImage(image); cvCvtColor(image, hsv, CV_BGR2HSV); // Get the selected pixel pixel = cvGet2D(hsv, y, x); // Change the value of the tracked color with the color of the selected pixel h = (int)pixel.val[0]; //修改全局变量 h通道值 s = (int)pixel.val[1]; //修改全局变量 s通道值 v = (int)pixel.val[2]; //修改全局变量 v通道值 // { HSV[0]=h; HSV[1]=s; HSV[2]=v;} { T_HSV[0]=h; T_HSV[1]=s; T_HSV[2]=v;} // Release the memory of the hsv image cvReleaseImage(&hsv); } }/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%% 欢迎到www.opencvchina.com下载源代码和资料 %%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ int main() { double t; // Image & hsvImage IplImage *hsv; // Video Capture CvCapture *capture; // Key for keyboard event char key='e'; // Number of tracked pixels int nbPixels; // Initialize the video Capture (200 => CV_CAP_V4L2) // capture = cvCreateCameraCapture(0); capture = cvCaptureFromAVI("face.mp4" ); // Check if the capture is ok if (!capture) { printf("Can't initialize the video capture.\n"); return -1; } // Create the windows cvNamedWindow("GeckoGeek Color Tracking", CV_WINDOW_AUTOSIZE); cvMoveWindow("GeckoGeek Color Tracking", 0, 100); // Mouse event to select the tracked color on the original image cvSetMouseCallback("GeckoGeek Color Tracking", getObjectColor); //设置鼠标监听,修改目标颜色的h,s,v三个通道值 image = cvQueryFrame(capture); // While we don't want to quit while(key != 'Q' && key != 'q') { // We get the current image image = cvQueryFrame(capture); // If there is no image, we exit the loop if(!image) continue; objectNextPos = binarisation(image, &nbPixels,T_HSV); //返回 质心坐标,nbPixels是目标像素的个数 // addObjectToVideo(image, objectNextPos, nbPixels); //质心移动处理函数 t = (double)cvGetTickCount();//用来计算算法执行时间 ditaldeal(image,objectNextPos,&nbPixels,HSV);//人物颜色质心跟踪更加精准 t = (double)cvGetTickCount() - t;//相减为算法执行的时间 printf( "detection time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) ); cvShowImage("GeckoGeek Color Tracking", image);//完整框,显示框不能重名 cvShowImage("GeckoGeek Color Track", im);//人物框 // We wait 10 ms key = cvWaitKey(10); } // Destroy the windows we have created cvDestroyWindow("GeckoGeek Color Tracking"); cvDestroyWindow("GeckoGeek Mask"); // Destroy the capture cvReleaseCapture(&capture); cvReleaseImage(&hsv); return 0; }


 

转载地址:http://xosws.baihongyu.com/

你可能感兴趣的文章
Objective-C Autorelease Pool 的实现原理
查看>>
编程语言大牛王垠:编程的智慧,带你少走弯路
查看>>
ios指令集以及基于指令集的app包压缩策略
查看>>
iOS开发者的福利 — — iOS9+Xcode7免越狱免证书直接调试
查看>>
3、JavaWeb学习之基础篇—JSP
查看>>
4、JavaWeb学习之基础篇—Session
查看>>
5、JavaWeb学习之基础篇—标签(自定义&JSTL)
查看>>
8、JavaWEB学习之基础篇—文件上传&下载
查看>>
reRender属性的使用
查看>>
href="javascript:void(0)"
查看>>
h:panelGrid、h:panelGroup标签学习
查看>>
f:facet标签 的用法
查看>>
<h:panelgroup>相当于span元素
查看>>
java中append()的方法
查看>>
必学高级SQL语句
查看>>
经典SQL语句大全
查看>>
Eclipse快捷键 10个最有用的快捷键
查看>>
log日志记录是什么
查看>>
<rich:modelPanel>标签的使用
查看>>
<h:commandLink>和<h:inputLink>的区别
查看>>