2015-05-05 116 views
1

我正在开发一个游戏机器人并使用opencv,我试图让它检测到尖峰。FastFeatureDetector opencv C++筛选结果

尖峰是这样的: With no keypoints

我试图用一个FastFeatureDetector突出关键点,将得到以下结果: With keypoint highlighted

的尖峰水平和变化colors.the操作是在一个完整的1920x1080屏幕

所以我的想法是采取其中一个点和比较对所有其他点X,因为我没有办法筛选结果和6094 KeyPoints操作花费太长时间。 (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 
} 

我知道用C的realloc和printf的用法++我只是不喜欢cout和新

+3

我们不喜欢'new',但我们已向前进步了'std :: vector <>' – MSalters

+0

感谢您的回复,当我重新编码时,会考虑到这一点。 – Keddy1201

回答

0

实际上尖峰实际上是不同的大小和不规则间隔?在你的图像中,它们有规律的间隔和相同的大小,所以一旦你知道了一个点的坐标,你可以通过简单地在X坐标上添加一个固定的增量来计算所有的坐标。

如果尖峰间隔不规则,并可能不同的高度,我建议你可以试试:

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

考虑您的尖峰的形式,我建议template pattern mathcing。看来关键点是一个相当间接的方法。

+0

模板匹配只会产生一个结果,而有许多其他结果并产生错误的结果... – Keddy1201