织梦CMS - 轻松建站从此开始!

罗索

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

落鹤生 发布于 2010-04-25 16:34 点击:次 
利用光流法计算人体运动的速度与方向 1.方向的计算 首先计算图像各个象素的光流(opencv LK),然后建立4*4窗口对X,Y方向分别做统计求和, 然后求得 atan(yy/xx)作为光流方向,即为运动的方向. 2.速度的计算 利用帧差分得到运动图像,然后建立4*4窗口对图像进行统计求和,求和
TAG:

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

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

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


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

4.代码:

 

  1. WW_RETURN HumanMotion::ImgOpticalFlow(IplImage *pre_grey,IplImage *grey) 
  2. /************************************************* 
  3.   Function: 
  4.   Description:  光流法计算运动速度与方向       
  5.   Date:   2006-6-14 
  6.   Author:   
  7.   Input:                        
  8.   Output:         
  9.   Return:         
  10.   Others:          
  11. *************************************************/ 
  12.  
  13.  IplImage *velx = cvCreateImage( cvSize(grey->width ,grey->height),IPL_DEPTH_32F, 1 ); 
  14.  IplImage *vely = cvCreateImage( cvSize(grey->width ,grey->height),IPL_DEPTH_32F, 1 ); 
  15.  
  16.  velx->origin =  vely->origin = grey->origin; 
  17.  CvSize winSize = cvSize(5,5); 
  18.  cvCalcOpticalFlowLK( prev_grey, grey, winSize, velx, vely ); 
  19.   
  20.  cvAbsDiff( grey,prev_grey, abs_img ); 
  21.  cvThreshold( abs_img, abs_img, 29, 255, CV_THRESH_BINARY);  
  22.  
  23.  CvScalar xc,yc;  
  24.  for(int y =0 ;y<velx->height; y++) 
  25.   for(int x =0;x<velx->width;x++ ) 
  26.   { 
  27.    xc = cvGetAt(velx,y,x); 
  28.    yc = cvGetAt(vely,y,x); 
  29.  
  30.     
  31.    float x_shift= (float)xc.val[0]; 
  32.    float y_shift= (float)yc.val[0]; 
  33.    const int winsize=5;  //计算光流的窗口大小 
  34.  
  35.  
  36.    if((x%(winsize*2)==0) && (y%(winsize*2)==0) ) 
  37.    { 
  38.  
  39.     if(x_shift!=0 || y_shift!=0) 
  40.     { 
  41.       
  42.      if(x>winsize && y>winsize && x <(velx->width-winsize) && y<(velx->height-winsize) ) 
  43.      { 
  44.  
  45.       cvSetImageROI( velx, cvRect( x-winsize, y-winsize, 2*winsize, 2*winsize)); 
  46.       CvScalar total_x = cvSum(velx); 
  47.       float xx = (float)total_x.val[0]; 
  48.       cvResetImageROI(velx); 
  49.  
  50.       cvSetImageROI( vely, cvRect( x-winsize, y-winsize, 2*winsize, 2*winsize)); 
  51.       CvScalar total_y = cvSum(vely); 
  52.       float yy = (float)total_y.val[0]; 
  53.       cvResetImageROI(vely); 
  54.        
  55.       cvSetImageROI( abs_img, cvRect( x-winsize, y-winsize, 2*winsize, 2*winsize)); 
  56.       CvScalar total_speed = cvSum(abs_img); 
  57.       float ss = (float)total_speed.val[0]/(4*winsize*winsize)/255; 
  58.       cvResetImageROI(abs_img); 
  59.  
  60.       const double ZERO = 0.000001; 
  61.       const double pi = 3.1415926; 
  62.       double alpha_angle; 
  63.  
  64.       if(xx<ZERO && xx>-ZERO) 
  65.        alpha_angle = pi/2; 
  66.       else 
  67.        alpha_angle = abs(atan(yy/xx)); 
  68.        
  69.       if(xx<0 && yy>0) alpha_angle = pi - alpha_angle ; 
  70.       if(xx<0 && yy<0) alpha_angle = pi + alpha_angle ; 
  71.       if(xx>0 && yy<0) alpha_angle = 2*pi - alpha_angle ; 
  72.  
  73.  
  74.        
  75.       CvScalar line_color; 
  76.       float scale_factor = ss*100; 
  77.       line_color = CV_RGB(255,0,0); 
  78.       CvPoint pt1,pt2; 
  79.       pt1.x = x; 
  80.       pt1.y = y; 
  81.       pt2.x = static_cast<int>(x + scale_factor*cos(alpha_angle)); 
  82.       pt2.y = static_cast<int>(y + scale_factor*sin(alpha_angle)); 
  83.  
  84.       cvLine( image, pt1, pt2 , line_color, 1, CV_AA, 0 ); 
  85.       CvPoint p; 
  86.       p.x = (int) (pt2.x + 6 * cos(alpha_angle - pi / 4*3)); 
  87.       p.y = (int) (pt2.y + 6 * sin(alpha_angle - pi / 4*3)); 
  88.       cvLine( image, p, pt2, line_color, 1, CV_AA, 0 ); 
  89.       p.x = (int) (pt2.x + 6 * cos(alpha_angle + pi / 4*3)); 
  90.       p.y = (int) (pt2.y + 6 * sin(alpha_angle + pi / 4*3)); 
  91.       cvLine( image, p, pt2, line_color, 1, CV_AA, 0 ); 
  92.  
  93.       /* 
  94.       line_color = CV_RGB(255,255,0); 
  95.       pt1.x = x-winsize; 
  96.       pt1.y = y-winsize; 
  97.       pt2.x = x+winsize; 
  98.       pt2.y = y+winsize; 
  99.       cvRectangle(image, pt1,pt2,line_color,1,CV_AA,0); 
  100.       */ 
  101.  
  102.      } 
  103.     } 
  104.    } 
  105.   } 
  106.  
  107.  
  108.  cvShowImage( "Contour", abs_img); 
  109.  cvShowImage( "Contour2", vely); 
  110.  
  111.  cvReleaseImage(&velx); 
  112.  cvReleaseImage(&vely); 
  113.  cvWaitKey(20); 
  114.   
  115.  return WW_OK; 

 

(hardVB)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201004/9256.html]
本文出处:CSDN博客 作者:hardVB
顶一下
(10)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容