⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 humanmotion.cpp

📁 基于OpenCV的计算机视觉技术实现.rar
💻 CPP
字号:
// HumanMotion.cpp: implementation of the HumanMotion class.
//
//////////////////////////////////////////////////////////////////////



#ifdef _CH_
#pragma package <opencv>
#endif

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <ctype.h>
#include "HumanMotion.h"



IplImage *image = 0, *grey = 0, *prev_grey = 0;
int add_remove_pt = 0;
int pause = 0;
int exit_flag = 0; 
CvPoint pt;
CvMemStorage* storage = 0; // temporary storage

IplImage* abs_image = 0;
IplImage* add_abs_image = 0;
IplImage* add_abs_image2 = 0;

CvSeq* contour = 0;
IplConvKernel* element = 0;
int frame_count =0;


void on_mouse( int event, int x, int y, int flags, void *param )
{
	
	if( !image )
        return;

    if( image->origin )
        y = image->height - y;

    if( event == CV_EVENT_LBUTTONDOWN )
    {
        pt = cvPoint(x,y);
        add_remove_pt = 1;
    } 
}

HumanMotion::HumanMotion()
{

}

HumanMotion::~HumanMotion()
{

}

int HumanMotion::Start()
{

	main_loop(1);
	return 0;
}

int HumanMotion::main_loop( int useCAM)
{
	
	CvCapture* capture = 0;
    
    if( useCAM == 1)
		capture = cvCaptureFromFile("lux_camsub_animation.avi");
		//halfbody2.avi
	    //capture4.avi
	
    else if( useCAM == 2 )
        capture = cvCaptureFromCAM(-1);

    if( !capture )
    {
        fprintf(stderr,"Could not initialize capturing...\n");
        return -1;
    }

    printf( "Hot keys: \n"
            "\tESC - quit the program\n"
            "\tp - pause on/off\n"
            "\n" );

    cvNamedWindow( "LkDemo", 1 );
	cvNamedWindow( "Contour", 1 );
    cvSetMouseCallback( "LkDemo", on_mouse, 0 );

    for(;;)
    {
        IplImage* frame = 0;
		
        if(pause)
			frame = image ;		
		else 
			frame = cvQueryFrame( capture );

        if( !frame ) break;

        if( !image )
        {
            /* allocate all the buffers */
			CvSize image_sz;
			image_sz = cvGetSize(frame) ;
            image = cvCreateImage(image_sz , 8, 3 );
			grey = cvCreateImage( image_sz, 8, 1 );			
            prev_grey = cvCreateImage( image_sz, 8, 1 );
			image->origin = grey->origin = prev_grey->origin = frame->origin;	
			storage = cvCreateMemStorage(0);

        }

        cvCopy( frame, image, 0 );
        cvCvtColor( image, grey, CV_BGR2GRAY );

		analyze_contour(grey);
        
        //记录前一帧的图像,方便差分
		if(frame_count%2==0) 
		cvCopy(grey,prev_grey,0);        
		frame_count++;
		
		//设置键盘控制
		KeyControl();
		if(exit_flag) break;

    }

    cvReleaseCapture( &capture );
    cvDestroyWindow("LkDemo");
	cvDestroyWindow("Contour");
	
    return 0;
}

//分析轮廓
int HumanMotion::analyze_contour(IplImage* grey_image)
{	

	getContour(grey,prev_grey);
	return 0;
}


CvPoint2D32f HumanMotion::Point_to_32f(CvPoint pt)
{
	CvPoint2D32f pt32;
	float zoom = 1.0f;
	pt32.x = pt.x * zoom;
	pt32.y = pt.y * zoom;
	return pt32;
}


//得到轮廓信息
int HumanMotion::getContour(IplImage *imggrey, IplImage *pre_grey)
{

	
	

	//执行透视变换
	if(!pause) WarpPerspective(image);
	
	//转换灰度模式
	cvCvtColor( image, grey, CV_BGR2GRAY );

	//阈值分割,这个阈值可用直方图自动调整
	cvThreshold( grey, grey, 50, 255, CV_THRESH_BINARY_INV );	

	
	//寻找轮廓
	cvFindContours( grey, storage, &contour, sizeof(CvContour),
		CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );

	int ApproxCount = 1; //轮廓优化等级	
	contour = cvApproxPoly( contour, sizeof(CvContour), storage, CV_POLY_APPROX_DP,ApproxCount, 1 );
	
	//cvDrawContours( image, contour, CV_RGB(255,0,0), CV_RGB(0,255,0), 7, 3, CV_AA, cvPoint(0,0) );

	//绘制轮廓
	drawContours(image);
	

	cvShowImage( "Contour", image );
	cvShowImage( "LkDemo", grey );	
	return 0;

	cvAbsDiff( grey,pre_grey,abs_image );
	cvThreshold( abs_image, abs_image, 10, 255, CV_THRESH_BINARY );	

	CvPoint top_pt,bottom_pt;
	getActivityArea(abs_image,top_pt,bottom_pt);

	cvRectangle( image, top_pt, bottom_pt, CV_RGB(155,151,255),1, CV_AA, 0 );

	cvShowImage( "Contour", image );
	cvShowImage( "LkDemo", abs_image );
	//cvWaitKey(30); 
	return 0;

}

//根据输入图像活动区域得到最大的方形区域
inline int HumanMotion::getActivityArea(IplImage *grey, CvPoint &top_pt,CvPoint &bottom_pt)
{
	CvMat mat;
	CvMat *temp = cvGetMat(grey , &mat,0 ,2);
	top_pt.x = mat.rows;
	top_pt.y = mat.step;
	bottom_pt.x = 0;
	bottom_pt.y = 0;
		
	//行遍历,寻找top pt
	for(int x=0;x<mat.rows;x++)
	{		
		int start_index = 0;
		int end_index = 0;
	
		//正向列遍历,寻找最左边的点
		for(int y=0;y<mat.step;y++)
		{		
			int index =mat.step*x + y;	
			int value = mat.data.ptr[index];
			if(value==255) 
			{
				start_index = y;
				if (start_index < top_pt.x) top_pt.x =  start_index;
				break;
			}
		}
		//反向列遍历,寻找最右边的点
		for(int y=mat.step-1;y>0;y--)
		{
			int index =mat.step*x + y;	
			int value = mat.data.ptr[index];
			if(value==255)
			{
				end_index = y;
				if (end_index > bottom_pt.x) bottom_pt.x =  end_index;
				break;
			}
		}
	}
	
	//列行遍历
	for(int y=0;y<mat.step;y++)
	{		
		int start_index = 0;
		int end_index = 0;
		
		//行遍历,寻找最上边的点
		for(int x=0;x<mat.rows;x++)
		{		
			int index =mat.step*x + y;	
			int value = mat.data.ptr[index];
			if(value==255) 
			{
				start_index = x;
				if (start_index < top_pt.y) top_pt.y =  start_index;
				break;
			}
		}
		//寻找最下边的点
		for(int x=mat.rows-1;x>0;x--)
		{
			int index =mat.step*x + y;	
			int value = mat.data.ptr[index];
			if(value==255)
			{
				end_index = x;
				if (end_index > bottom_pt.y) bottom_pt.y =  end_index;
				break;
			}
		}
	}
	
	return 0;

	
}

int HumanMotion::Test_cvMUL2(IplImage *grey)
{
	/*
	double bound;
	double mean =0;
	CvRNG rng_state = cvRNG(0xffffffff);	
	IplImage *image_noise = 0;
	image_noise = cvCreateImage(cvGetSize(grey), grey->depth, 1);
	bound = sqrt(3*1);
	//cvRandArr(&rng_state, image_noise, CV_RAND_UNI, cvRealScalar(-bound + mean), cvRealScalar(bound + mean));
	cvMul(grey, image_noise, grey);
	*/

	IplImage* src = cvCloneImage( grey );
	
	float m[6];
	int angle = frame_count%60 - 30;
	
	CvMat M = cvMat( 2, 3, CV_32F, m );
	int w = src->width;
	int h = src->height;
	
	m[0] = (float)(cos(angle*CV_PI/180.));
	m[1] = (float)(sin(angle*CV_PI/180.));
	m[2] = w*0.5f;
	m[3] = -m[1];
	m[4] = m[0];
	m[5] = h*0.5f;
	
	cvGetQuadrangleSubPix( src, grey, &M);
	
	return 0;
	
}

//透视变换 
//auto get points to do list
int HumanMotion::WarpPerspective(IplImage *grey)
{
	IplImage* Img_old = cvCloneImage( grey );
	
	int fix = 4.0f; 
	int w = Img_old->width + fix;
	int h = Img_old->height + fix;
	
	CvPoint2D32f src_point[4];
	CvPoint2D32f dst_point[4];
	
	/* //for small movie
	src_point[0].x=4;             
	src_point[0].y=142;

	src_point[1].x=238;                    
	src_point[1].y=134; 

	src_point[2].x=25; 
	src_point[2].y=55;

	src_point[3].x=209; 
	src_point[3].y=50;
	*/

	
	src_point[0].x=17;             
	src_point[0].y=475;
	
	src_point[1].x=952;                    
	src_point[1].y=449; 
	
	src_point[2].x=100; 
	src_point[2].y=128;
	
	src_point[3].x=840; 
	src_point[3].y=110;

	
		
	dst_point[0].x=-fix;               
	dst_point[0].y=h;
	
	dst_point[1].x=w;              
	dst_point[1].y=h;
    
	dst_point[2].x=-fix;
	dst_point[2].y=-fix;
	
	dst_point[3].x=w;
	dst_point[3].y=-fix;
    
	
	float newm[9];            
	CvMat newM = cvMat( 3, 3, CV_32F, newm );
	//获得透视转换矩阵
	cvWarpPerspectiveQMatrix(src_point,dst_point,&newM);
	//透视转换
	cvWarpPerspective(Img_old,grey,&newM,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0) );
	cvReleaseImage(&Img_old);

	return 0;
	
}

int HumanMotion::KeyControl()
{
	char c;
	c = cvWaitKey(10);
	//c = 'd';
	//printf("%c,%d",c,c);
	if( c == 27 )
		exit_flag = 1;
	switch( c )
	{

	case 'p':
		pause ^= 1;
		break;
	default:
		;
	}
	return c;
}


//绘制轮廓
int HumanMotion::drawContours(IplImage *dst)
{
	
	CvSeqReader reader;			
	int i;
	CvPoint pt,pt_pre;	
	
	
	for (; contour != NULL; contour = contour->h_next)
	{
		cvStartReadSeq(contour, &reader);	
		int N = contour->total;
		
		for (i = 0; i < N+1; i++)
		{				
			CV_READ_SEQ_ELEM(pt, reader);
			if(i!=0) cvLine(dst,pt,pt_pre,CV_RGB(0,255,0),2,CV_AA, 0 );	
			pt_pre = pt;
		}		
	}	
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -