利用光流法计算人体运动的速度与方向

利用光流法计算人体运动的速度与方向

1.方向的计算
首先计算图像各个象素的光流(opencv LK),然后建立4*4窗口对X,Y方向分别做统计求和,
然后求得 atan(yy/xx)作为光流方向,即为运动的方向.
 

2.速度的计算
利用帧差分得到运动图像,然后建立4*4窗口对图像进行统计求和,求和值作为权重,表示速度的比例.
即运动区域白色(255)面积越大,速度越大.


3.结果
大部分运动方向计算正确,少部分有错误,还需要改进算法.(利用统计?)

 

4.代码:

WW_RETURN HumanMotion::ImgOpticalFlow(IplImage *pre_grey,IplImage *grey)
/*************************************************
  Function:
  Description:  光流法计算运动速度与方向      
  Date:   2006-6-14
  Author:  
  Input:                       
  Output:        
  Return:        
  Others:         
*************************************************/
{

 IplImage *velx = cvCreateImage( cvSize(grey->width ,grey->height),IPL_DEPTH_32F, 1 );
 IplImage *vely = cvCreateImage( cvSize(grey->width ,grey->height),IPL_DEPTH_32F, 1 );

 velx->origin =  vely->origin = grey->origin;
 CvSize winSize = cvSize(5,5);
 cvCalcOpticalFlowLK( prev_grey, grey, winSize, velx, vely );
 
 cvAbsDiff( grey,prev_grey, abs_img );
 cvThreshold( abs_img, abs_img, 29, 255, CV_THRESH_BINARY); 

 CvScalar xc,yc; 
 for(int y =0 ;y<velx->height; y++)
  for(int x =0;x<velx->width;x++ )
  {
   xc = cvGetAt(velx,y,x);
   yc = cvGetAt(vely,y,x);

   
   float x_shift= (float)xc.val[0];
   float y_shift= (float)yc.val[0];
   const int winsize=5;  //计算光流的窗口大小


   if((x%(winsize*2)==0) && (y%(winsize*2)==0) )
   {

    if(x_shift!=0 || y_shift!=0)
    {
     
     if(x>winsize && y>winsize && x <(velx->width-winsize) && y<(velx->height-winsize) )
     {

      cvSetImageROI( velx, cvRect( x-winsize, y-winsize, 2*winsize, 2*winsize));
      CvScalar total_x = cvSum(velx);
      float xx = (float)total_x.val[0];
      cvResetImageROI(velx);

      cvSetImageROI( vely, cvRect( x-winsize, y-winsize, 2*winsize, 2*winsize));
      CvScalar total_y = cvSum(vely);
      float yy = (float)total_y.val[0];
      cvResetImageROI(vely);
      
      cvSetImageROI( abs_img, cvRect( x-winsize, y-winsize, 2*winsize, 2*winsize));
      CvScalar total_speed = cvSum(abs_img);
      float ss = (float)total_speed.val[0]/(4*winsize*winsize)/255;
      cvResetImageROI(abs_img);

      const double ZERO = 0.000001;
      const double pi = 3.1415926;
      double alpha_angle;

      if(xx<ZERO && xx>-ZERO)
       alpha_angle = pi/2;
      else
       alpha_angle = abs(atan(yy/xx));
      
      if(xx<0 && yy>0) alpha_angle = pi - alpha_angle ;
      if(xx<0 && yy<0) alpha_angle = pi + alpha_angle ;
      if(xx>0 && yy<0) alpha_angle = 2*pi - alpha_angle ;


      
      CvScalar line_color;
      float scale_factor = ss*100;
      line_color = CV_RGB(255,0,0);
      CvPoint pt1,pt2;
      pt1.x = x;
      pt1.y = y;
      pt2.x = static_cast<int>(x + scale_factor*cos(alpha_angle));
      pt2.y = static_cast<int>(y + scale_factor*sin(alpha_angle));

      cvLine( image, pt1, pt2 , line_color, 1, CV_AA, 0 );
      CvPoint p;
      p.x = (int) (pt2.x + 6 * cos(alpha_angle - pi / 4*3));
      p.y = (int) (pt2.y + 6 * sin(alpha_angle - pi / 4*3));
      cvLine( image, p, pt2, line_color, 1, CV_AA, 0 );
      p.x = (int) (pt2.x + 6 * cos(alpha_angle + pi / 4*3));
      p.y = (int) (pt2.y + 6 * sin(alpha_angle + pi / 4*3));
      cvLine( image, p, pt2, line_color, 1, CV_AA, 0 );

      /*
      line_color = CV_RGB(255,255,0);
      pt1.x = x-winsize;
      pt1.y = y-winsize;
      pt2.x = x+winsize;
      pt2.y = y+winsize;
      cvRectangle(image, pt1,pt2,line_color,1,CV_AA,0);
      */

     }
    }
   }
  }


 cvShowImage( "Contour", abs_img);
 cvShowImage( "Contour2", vely);

 cvReleaseImage(&velx);
 cvReleaseImage(&vely);
 cvWaitKey(20);
 
 return WW_OK;

}

 

  • 0
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
vc++全版本组件大全 VC++运行时(Visual C++ Runtime)是VC++开发环境中用于支持C和C++程序运行的基础库集合。这些库包含了执行C/C++程序所必需的基本函数和数据结构,例如内存管理、字符串操作、输入输出处理、异常处理等。VC++运行时库分为静态库和动态库两种形式,以适应不同类型的项目需求。 静态链接库 vs 动态链接库 静态链接库(Static Linking Libraries):在编译时,静态库的代码会被直接嵌入到最终生成的可执行文件中。这意味着每个使用静态库的程序都会包含库代码的一个副本,导致最终程序的体积较大,但不需要外部库文件支持即可独立运行。在VC++中,静态链接库的例子有LIBC.lib(用于单线程程序)和LIBCMT.lib(用于多线程程序)。 动态链接库(Dynamic Link Libraries):与静态链接相反,动态库的代码并不直接加入到应用程序中,而是在程序运行时被加载。这使得多个程序可以共享同一份库代码,节省了系统资源。VC++的动态运行时库主要通过msvcrt.dll(或其变体,如MSVCRTD.dll用于调试版本)实现,与之配套的导入库(Import Library)如CRTDLL.lib用于链接阶段。 运行时库的版本 VC++运行时库随着Visual Studio版本的更新而发展,每个版本都可能引入新的特性和优化,同时保持向后兼容性。例如,有VC++ 2005、2008、2010直至2019等多个版本的运行时库,每个版本都对应着特定的开发环境和Windows操作系统。 重要性 VC++运行时对于确保程序正确运行至关重要。当程序在没有安装相应运行时库的计算机上执行时,可能会遇到因缺失DLL文件(如MSVCP*.dll, VCRUNTIME*.dll等)而导致的错误。因此,开发完成后,通常需要分发相应的VC++ Redistributable Packages给最终用户安装,以确保程序能够在目标系统上顺利运行。 安装与部署 安装VC++运行时库通常是通过Microsoft提供的Redistributable Packages完成的,这是一个简单的过程,用户只需运行安装程序即可自动安装所需组件。对于开发者而言,了解和管理不同版本的运行时库对于确保应用程序的广泛兼容性和可靠性是必要的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值