我想把OPENCV 中的LKDEMO.C,改成在MFC下运行的程序,下面是我改的,虽然能显示视频,但其他功能都没有。
加的按键事件,也没起作用!高手指点指点!!!!!void CofprobeDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
Pt=cvPoint(point.x,point.y);
add_remove_pt=1;CDialog::OnLButtonDown(nFlags, point);
}
void CofprobeDlg::OnBnClickedLksamples()
{
// TODO: Fügen Sie hier Ihren Kontrollbehandlungscode für die Benachrichtigung ein.
IplImage *image = 0, 
         *grey = 0, 
         *prev_grey = 0, 
         *pyramid = 0, 
         *prev_pyramid = 0,
         *swap_temp;
IplImage* frame = 0;int win_size = 10;
const int MAX_COUNT = 500;
CvPoint2D32f* points[2] = {0,0}, *swap_points;
char* status = 0;
int count = 0;
int need_to_init=1;
int night_mode = 0;
int flags = 0;CvCapture* capture = 0;
capture = cvCaptureFromCAM(0);    
if( !capture )
    {
        MessageBox(_T("kann nicht capture  initialisieren ."));
        
    }   
    cvNamedWindow( "Myflow", 0 );    //two images for storing optical flow
   while(1)
    {
        int i, k;        frame = cvQueryFrame( capture );
        if( !frame )
            break;        if( !image )
        {
            /* allocate all the buffers */
            image = cvCreateImage( cvGetSize(frame), 8, 3 );
            image->origin = frame->origin;
            grey = cvCreateImage( cvGetSize(frame), 8, 1 );
            prev_grey = cvCreateImage( cvGetSize(frame), 8, 1 );
            //abs_img = cvCreateImage( cvGetSize(frame), 8, 1);
    points[0] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0]));
            points[1] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0]));
            status = (char*)cvAlloc(MAX_COUNT);
            flags = 0;
        }        cvCopy( frame, image, 0 );
        cvCvtColor( image, grey, CV_BGR2GRAY );  if( night_mode )
            cvZero( image );  if(need_to_init)
  { IplImage* eig = cvCreateImage( cvGetSize(grey), 32, 1 );
    IplImage* temp = cvCreateImage( cvGetSize(grey), 32, 1 );
    double quality = 0.01;
    double min_distance = 10;
    count = MAX_COUNT;
           
              cvGoodFeaturesToTrack( grey, eig, temp, points[1], &count,
                                   quality, min_distance, 0, 3, 0, 0.04 );
              cvFindCornerSubPix( grey, points[1], count,
                cvSize(win_size,win_size), cvSize(-1,-1),
                cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));
  
cvReleaseImage( &eig );
cvReleaseImage( &temp );
    
add_remove_pt = 0;
  }  else  
       if( count > 0 )
        {
            cvCalcOpticalFlowPyrLK( prev_grey, grey, prev_pyramid, pyramid,
                points[0], points[1], count, cvSize(win_size,win_size), 3, status, 0,
                cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03), flags );
            flags |= CV_LKFLOW_PYR_A_READY;
            for( i = k = 0; i < count; i++ )
            {
                if( add_remove_pt )
                {
                    double dx = pt.x - points[1][i].x;
                    double dy = pt.y - points[1][i].y;                    if( dx*dx + dy*dy <= 25 )
                    {
                        add_remove_pt = 0;
                        continue;
                    }
                }                if( !status[i] )
                    continue;                points[1][k++] = points[1][i];
                cvCircle( image, cvPointFrom32f(points[1][i]), 3, CV_RGB(0,255,0), -1, 8,0);
            }
            count = k;
        }        if( add_remove_pt && count < MAX_COUNT )
        {
            points[1][count++] = cvPointTo32f(pt);
            cvFindCornerSubPix( grey, points[1] + count - 1, 1,
                cvSize(win_size,win_size), cvSize(-1,-1),
                cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));
            add_remove_pt = 0;
        }        CV_SWAP( prev_grey, grey, swap_temp );
        CV_SWAP( prev_pyramid, pyramid, swap_temp );
        CV_SWAP( points[0], points[1], swap_points );
        
        cvShowImage( "Myflow", image );       char c = cvWaitKey(10);
        if( c == 27 )
            break;
       switch(  c )
        {
        case 114:   //r
            need_to_init = 1;
            break;
        case 99:    // c
            count = 0;
            break;
        case 110:  // n
            night_mode = 1;
            break;
        default:
            ;
        }
    }    cvReleaseCapture( &capture );
   
    cvReleaseImage(&image);
    cvReleaseImage(&grey);
cvReleaseImage(&prev_grey);
cvReleaseImage(&pyramid);
cvReleaseImage(&prev_pyramid);
    cvReleaseImage(&frame);    cvDestroyWindow("Myflow");  
}

解决方案 »

  1.   

    1. 建议把按键响应加载在MFC本身的键盘消息响应中
    2. char c = cvWaitKey(10);
    最好改成char c = cvWaitKey(0);
    设置默认时间的话你自己都来不及响应的,10ms,你的手速应该没这么快
      

  2.   

    1, cvWaitKey(),改成0后,摄像头就不能连续显示了。2,你说的MFC本身的键盘消息响应中, 指的是 ONKEYDOWN 吗?。
    谢谢
      

  3.   

    你显示视频的话,cvWaitKey(10)也可以
    然后加键盘响应的话,可以响应PreTranslateMessage消息,可以添加下面的代码
    if (WM_KEYDOWN == pMsg->message)
    {
    switch(pMsg->wParam)
    {
    case VK_SPACE://例如按下空格键
                      //添加消息处理
                    break;
                      default:
                      break;
                      }
             }