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 坐标添加一个固定增量来计算其余所有点。
如果尖峰间距不规则且高度可能不同,我建议您可以尝试:
- 使用 Canny 边缘检测器找到尖峰和背景之间的边界
- 对于此边缘图像中的每个 X 坐标,使用
minMaxIdx
搜索边缘图像的单个列以找到该列中的最亮点
- 如果该点的 Y 坐标在屏幕上方高于前一列中最亮点的 Y 坐标,则前一列是尖峰,保存 (X,Y) 坐标。
- 如果在第 3 步中发现尖峰,则继续跳过列,直到列中最亮的 Y 坐标与上一列中的坐标相同。然后重复尖峰检测,否则继续搜索下一个尖峰
我正在开发一个游戏机器人并使用 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 坐标添加一个固定增量来计算其余所有点。
如果尖峰间距不规则且高度可能不同,我建议您可以尝试:
- 使用 Canny 边缘检测器找到尖峰和背景之间的边界
- 对于此边缘图像中的每个 X 坐标,使用
minMaxIdx
搜索边缘图像的单个列以找到该列中的最亮点 - 如果该点的 Y 坐标在屏幕上方高于前一列中最亮点的 Y 坐标,则前一列是尖峰,保存 (X,Y) 坐标。
- 如果在第 3 步中发现尖峰,则继续跳过列,直到列中最亮的 Y 坐标与上一列中的坐标相同。然后重复尖峰检测,否则继续搜索下一个尖峰