4

我已经实现了光流来跟踪道路上的车辆,结果非常慢。

我的代码使用以下功能:

  • cvGoodFeaturesToTrack
  • cvFindCornerSubPix
  • cvCalcOpticalFlowPyrLK

如何使这种跟踪快速有效?

我的代码是:

#include "highgui.h"
#include "cv.h"
#include "cxcore.h"
#include <iostream>
using namespace std;


const int MAX_CORNERS = 500;

int main()
{
CvCapture* capture=cvCreateFileCapture("E:\cam1.avi");
IplImage* img_A;// = cvLoadImage("image0.png", CV_LOAD_IMAGE_GRAYSCALE);
IplImage* img_B;// = cvLoadImage("image1.png", CV_LOAD_IMAGE_GRAYSCALE);
img_A=cvQueryFrame(capture);

IplImage* imgA = cvCreateImage( cvGetSize(img_A), 8, 1 );
IplImage* imgB = cvCreateImage( cvGetSize(img_A), 8, 1 );
cvNamedWindow( "ImageA", CV_WINDOW_AUTOSIZE );
cvNamedWindow( "ImageB", CV_WINDOW_AUTOSIZE );
cvNamedWindow( "LKpyr_OpticalFlow", CV_WINDOW_AUTOSIZE );

while(1)
{
    int couter=0;
    for(int k=0;k<20;k++)
    {
        img_B=cvQueryFrame(capture);
    }


    //cvCvtColor(imgA,imgA,CV_BGR2GRAY);
    //cvCvtColor(imgB,imgB,CV_BGR2GRAY);
    // Load two images and allocate other structures
    /*IplImage* imgA = cvLoadImage("image0.png", CV_LOAD_IMAGE_GRAYSCALE);
    IplImage* imgB = cvLoadImage("image1.png", CV_LOAD_IMAGE_GRAYSCALE);*/

    CvSize img_sz = cvGetSize( img_A );
    int win_size = 10;



    IplImage* imgC = cvCreateImage( cvGetSize(img_A), 8, 1 );
    cvZero(imgC);
    // Get the features for tracking
    IplImage* eig_image = cvCreateImage( img_sz, IPL_DEPTH_32F, 1 );
    IplImage* tmp_image = cvCreateImage( img_sz, IPL_DEPTH_32F, 1 );

    int corner_count = MAX_CORNERS;

    CvPoint2D32f* cornersA = new CvPoint2D32f[ MAX_CORNERS ];


    cvCvtColor(img_A,imgA,CV_BGR2GRAY);

    cvCvtColor(img_B,imgB,CV_BGR2GRAY);


    cvGoodFeaturesToTrack( imgA, eig_image, tmp_image, cornersA, &corner_count ,0.05, 5.0, 0, 3, 0, 0.04 );

    cvFindCornerSubPix( imgA, cornersA, corner_count, cvSize( win_size, win_size ) ,cvSize( -1, -1 ), cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03 ) );

    // Call Lucas Kanade algorithm
    char features_found[ MAX_CORNERS ];
    float feature_errors[ MAX_CORNERS ];

    CvSize pyr_sz = cvSize( imgA->width+8, imgB->height/3 );

    IplImage* pyrA = cvCreateImage( pyr_sz, IPL_DEPTH_32F, 1 );
    IplImage* pyrB = cvCreateImage( pyr_sz, IPL_DEPTH_32F, 1 );

    CvPoint2D32f* cornersB = new CvPoint2D32f[ MAX_CORNERS ];

    /*int jk=0;
    for(int i=0;i<imgA->width;i+=10)
    {
        for(int j=0;j<imgA->height;j+=10)
        {
            cornersA[jk].x=i;
            cornersA[jk].y=j;
            ++jk;
        }
    }
  */
    cvCalcOpticalFlowPyrLK( imgA, imgB, pyrA, pyrB, cornersA, cornersB, corner_count,
        cvSize( win_size, win_size ), 5, features_found, feature_errors,
         cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.3 ), 0 );

    // Make an image of the results


    for( int i=0; i < corner_count; i++ ) 
    {
        if( features_found[i]==0|| feature_errors[i]>550 ) 
        {
            //printf("Error is %f/n",feature_errors[i]);
            continue;
        }
        //printf("Got it/n");
        CvPoint p0 = cvPoint( cvRound( cornersA[i].x ), cvRound( cornersA[i].y ) );
        CvPoint p1 = cvPoint( cvRound( cornersB[i].x ), cvRound( cornersB[i].y ) );
        cvLine( imgC, p0, p1, CV_RGB(255,0,0), 2 );
        cout<<p0.x<<" "<<p0.y<<endl;
    }




    cvShowImage( "LKpyr_OpticalFlow", imgC );
    cvShowImage( "ImageA", imgA );
    cvShowImage( "ImageB", imgB );
    //cvCopyImage(imgB,imgA);
    delete[] cornersA;
    delete[] cornersB;
    cvWaitKey(33);
}


return 0;
}
4

2 回答 2

12

我在这里可能有点过分了,但我建议你去看看OpenTLD。OpenTLD(又名 Predator)是最有效的跟踪算法之一。Zdenek Kalal 在 MATLAB 中实现了 OpenTLD。乔治·内贝海(George Nebehay)取得了非常有效率的表现C++ OpenCV port of OpenTLD

它非常易于安装,并且跟踪非常有效。

OpenTLD 使用 Median Flow Tracker 来跟踪和实现 PN 学习算法。在这个YouTube 视频中,Zdenek Kalal 展示了 OpenTLD 的使用。

如果您只想实现中值流跟踪器,请点击此链接https://github.com/gnebehay/OpenTLD/tree/master/src/mftracker

如果你想在 Python 中使用它,我已经制作了一个Median Flow Tracker并且还制作了OpenTLD 的 Python 端口。但是python端口效率不高。

于 2012-06-23T17:58:03.370 回答
5

首先要跟踪汽车,您必须以某种方式检测它(例如使用颜色分割/背景减法)。当检测到汽车时,您必须使用cvCalcOpticalFlowPyrLK. 我没有找到响应汽车检测的代码。

看看这个这篇文章。你的想法应该是一样的。

你的代码也有点错误。例如,为什么要cvGoodFeaturesToTrack在主循环中调用?您必须调用它一次 - 在循环之前检测要跟踪的良好功能。但这也会检测到非汽车。

看一下默认的 OpenCV 示例:OpenCV/samples/cpp/lkdemo.cpp

于 2012-06-23T14:02:04.350 回答