2015-05-05 115 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