FastFeatureDetector opencv C++ 过滤结果

FastFeatureDetector opencv C++ filtering results

我正在开发一个游戏机器人并使用 opencv,我正试图让它检测尖峰。

尖峰看起来像这样:

我尝试使用 FastFeatureDetector 来突出关键点,结果如下:

The spikes are horizontal and change colors.the operation is on a full 1920x1080 screen

所以我的想法是取其中一个点并与所有其他点 X 进行比较,因为我无法过滤结果并且 6094 个关键点操作花费的时间太长。 (37136836 次迭代)。

有没有办法过滤 FastFeatureDetector 结果,或者我应该用另一种方法来处理这个问题?

我的代码:

Point * findSpikes( Mat frame , int * num_spikes )
{
    Point * ret = NULL;
    int spikes_counter = 0;
    Mat frame2;
    cvtColor( frame , frame2 , CV_BGR2GRAY );
    Ptr<FastFeatureDetector> myBlobDetector = FastFeatureDetector::create( );
    vector<KeyPoint> myBlobs;
    myBlobDetector->detect( frame2 , myBlobs );

    HWND wnd = FindWindow( NULL , TEXT( "Andy" ) );
    RECT andyRect;
    GetWindowRect( wnd , &andyRect );

    /*Mat blobimg;
    drawKeypoints( frame2 , myBlobs , blobimg );*/

    //imshow( "Blobs" , blobimg );
    //waitKey( 1 );

    printf( "Size of vectors : %d\n" , myBlobs.size( ) );

    for ( vector<KeyPoint>::iterator blobIterator = myBlobs.begin( ); blobIterator != myBlobs.end( ); blobIterator++ )
    {
#pragma region FilteringArea
        //filtering keypoints
        if ( blobIterator->pt.x > andyRect.right || blobIterator->pt.x  < andyRect.left
             || blobIterator->pt.y > andyRect.bottom || blobIterator->pt.y < andyRect.top )
        {
            printf( "Filtered\n" );
            continue;
        }
#pragma endregion

        for ( vector<KeyPoint>::iterator comparsion = myBlobs.begin( ); comparsion != myBlobs.end( ); comparsion++ )
        {
            //filtering keypoints
#pragma region FilteringRegion
            if ( comparsion->pt.x > andyRect.right || comparsion->pt.x  < andyRect.left
                 || comparsion->pt.y > andyRect.bottom || comparsion->pt.y < andyRect.top )
            {
                printf( "Filtered\n" );
                continue;
            }

            printf( "Processing\n" );
            double diffX = abs( blobIterator->pt.x - comparsion->pt.x );
            if ( diffX <= 5 )
            {
                spikes_counter++;
                printf( "Spike added\n" );
                ret = ( Point * ) realloc( ret , sizeof( Point ) * spikes_counter );
                if ( !ret )
                {
                    printf( "Memory error\n" );
                    ret = NULL;
                }

                ret[spikes_counter - 1].y = ( ( blobIterator->pt.y + comparsion->pt.y ) / 2 );
                ret[spikes_counter - 1].x = blobIterator->pt.x;
                break;
            }

#pragma endregion

        }
    }

    ( *( num_spikes ) ) = spikes_counter;
    return ret;//Modify later  
}

I'm aware of the usage of realloc and printf in C++ I just don't like cout and new

考虑到尖峰的形式,我建议 template pattern mathcing。似乎关键点是一种相当间接的方法。

在现实生活中,尖刺实际上大小不一且间距不规则吗?在您的图像中,它们有规律地间隔且大小相同,因此一旦您知道一个点的坐标,您就可以通过简单地向 X 坐标添加一个固定增量来计算其余所有点。

如果尖峰间距不规则且高度可能不同,我建议您可以尝试:

  1. 使用 Canny 边缘检测器找到尖峰和背景之间的边界
  2. 对于此边缘图像中的每个 X 坐标,使用 minMaxIdx 搜索边缘图像的单个列以找到该列中的最亮点
  3. 如果该点的 Y 坐标在屏幕上方高于前一列中最亮点的 Y 坐标,则前一列是尖峰,保存 (X,Y) 坐标。
  4. 如果在第 3 步中发现尖峰,则继续跳过列,直到列中最亮的 Y 坐标与上一列中的坐标相同。然后重复尖峰检测,否则继续搜索下一个尖峰