2011-11-17 210 views
3

我正在製作一個android應用程序,它能夠拍攝正在進行的檯球遊戲的圖像並檢測各種球的位置。圖片是從某人的手機拍攝的,所以當然我沒有桌面的完美俯視圖。現在我正在用houghcircles來找球,而且它做得很好,但它似乎錯過了幾個球,然後就有誤報。用OpenCV檢測檯球

我現在最大的問題是,我該如何減少在表格外發現的誤報?我使用ROI來切斷圖像的頂部,因爲它主要是浪費空間,但我無法將它縮小,或者我可能會切掉桌子的一部分,因爲它是梯形形狀。我目前的想法是覆蓋用戶在圖像頂部拍攝圖片時看到的指南,但問題是我不知道他們的相機的分辨率會是什麼,因此覆蓋層可能會覆蓋出錯點。理想情況下,我想我會想使用houghlines,但是當我嘗試它時,我的應用程序因我認爲內存不足而崩潰。有任何想法嗎?

下面是我得到的結果中的鏈接:

http://graphiquest.com/cvhoughcircles.html

這裏是我的代碼:

IplImage img = cvLoadImage("/sdcard/DCIM/test/picture"+i+".jpg",1); 
    IplImage gray = opencv_core.cvCreateImage(opencv_core.cvSize(img.width(), img.height()), opencv_core.IPL_DEPTH_8U, 1); 

    cvCvtColor(img, gray, opencv_imgproc.CV_RGB2GRAY); 
    cvSetImageROI(gray, cvRect(0, (int)(img.height()*.15), (int)img.width(), (int)(img.height()-(img.height()*.20)))); 


    cvSmooth(gray,gray,opencv_imgproc.CV_GAUSSIAN,9,9,2,2); 

    Pointer circles = CvMemStorage.create();   
    CvSeq seq = cvHoughCircles(gray, circles, CV_HOUGH_GRADIENT, 2.5d, (double)gray.height()/30, 70d, 100d, 0, 80); 

    for(int j=0; j<seq.total(); j++){ 
     CvPoint3D32f point = new CvPoint3D32f(cvGetSeqElem(seq, j)); 

     float xyr[] = {point.x(),point.y(),point.z()}; 
     CvPoint center = new CvPoint(Math.round(xyr[0]), Math.round(xyr[1])); 

     int radius = Math.round(xyr[2]); 
     cvCircle(gray, center, 3, CvScalar.GREEN, -1, 8, 0); 
     cvCircle(gray, center, radius, CvScalar.BLUE, 3, 8, 0); 
    } 
    String path = "/sdcard/DCIM/test/"; 
    File photo=new File(path, "picture"+i+"_2.jpg"); 

    if (photo.exists()) 
    { 
     photo.delete(); 
    } 
    cvSaveImage("/sdcard/DCIM/test/picture"+i+"_2.jpg", gray); 
+1

嘿vince88。你有沒有完成這個項目?你是否開源代碼?我只是自己開始做類似的事情。 – m1ket

回答

4

有一些你可以申請非常有幫助的約束。除了做一個感興趣的矩形區域之外,還應該使用檯面的實際梯形形狀來掩蓋結果。使用圖像的顏色信息來查找池表區域。你知道檯球桌是純色的。它不一定是綠色的 - 你可以在HSV顏色空間中使用一些histogram技術來找到圖像中最流行的顏色,也許有利於像素朝向中心。它很可能檢測到池表的顏色。選擇與此顏色匹配的像素,執行形態學操作以去除噪點,然後可以將蒙版作爲輪廓對待,並找到其convexHull。填充船體去除由水池球產生的孔。

我到目前爲止所說的應該會提出一個比霍夫圈子更好的方法。由於檯球沒有均勻地照亮,所以Hough圈可能不太好。所以,另一種查找檯球的方法是從其凸凸圖中減去檯球桌顏色掩模。你會留下桌子被球遮擋的區域。

+0

感謝您的建議,這很有意義。儘管我一般對OpenCV和圖像處理都很陌生,但我必須做更多的研究。你建議什麼樣的形態學操作?像高斯模糊的東西? 另外,如果桌子沒有均勻照明,是否重要? – vince88

+0

我剛剛意識到這種方法會使檢測聚集在一起的球的位置更加困難。他們只會成爲一個大塊頭,對吧? – vince88

+0

是的,這就是爲什麼我不建議完全放棄Hough圈子。也許你可以結合使用這些方法。你可以嘗試一些基本的分割技術來分離簇。 –

0

我也考慮過關於這個問題的工作,因爲我打檯球和斯諾克。

的幾點:

  1. 從霍夫圓擬合來看,它看起來像你不過濾邊緣點,或您對邊緣強度門檻還不夠高。你是簡單地使用邊緣點的二進制指示符,還是基於邊緣強度選擇邊緣點?
  2. 你能在RGB空間工作嗎?這有助於檢測臺牀,導軌以及識別球。桌子上的一個藍色斑點可能是2球,10球或白堊。
  3. 在您的參數空間中,您應該能夠限制搜索非常有限半徑的圓圈。如果...
  4. 檢測工作臺表面和導軌,部分幫助。行程寬度轉換可以幫助您找到導軌,尤其是在軌道具有高對比度的顏色平面(綠色)中搜索時。您還可以使用六個口袋(或至少三個口袋)來幫助識別桌子的姿勢(位置和方向)。
  5. 一旦檢測到導軌,您可以使用仿射變換來校正透視失真。無論如何,您都需要這樣做,以便以任何準確的方式放置球,特別是如果您希望放置球來滿足一名嚴重的水池球員,例如玩一個口袋或直接水池的人。一旦你有仿射變換,你可以在你的Hough參數空間中爲半徑設置相當嚴格的公差。
  6. 一旦檢測到牀臺,您可以執行初始分段(即區域標記或blob查找),並僅搜索特定區域和圓度的斑點。
  7. 強烈,均勻,漫射的頭燈可以幫助消除陰影。
  8. 您可以通過接受(或至少偏袒)具有梯度的邊緣點來幫助過濾邊緣點,這些邊緣點具有指向具有平行梯度的其他邊緣點的梯度。如果邊緣點對的局部集合通過它們的邊緣梯度彼此「指向」,則它們是檢測的良好候選者。
  9. 一旦你發現了一個候選球,進行進一步處理接受/拒絕。一個球應該是一個相對均勻的色調(母球,1 - 8,或從正確的角度來看一個條紋),或者它應該有一個可檢測的彩色條紋和白色。球表面不會像桌子的木紋那樣具有高度紋理。
  10. 有一個選項,用戶可以從稍微不同的角度拍攝兩張圖片。然後你有兩次找到球的機會,並且可以想象地解決兩個圖像中匹配桌子和球的通信問題,以幫助將球定位在桌子牀的2D空間中。
  11. 考慮使用第二種算法,如標準化互相關(簡單模板匹配)來幫助識別球或至少可能的球位置。
  12. 堅持圖像的中心點位於牀臺內的某個位置。這可以幫助您識別導軌的位置,因爲您可以徑向向外搜索導軌的邊緣,一旦找到四個(甚至是三個)導軌,您可以拒絕超出它們的徑向距離的邊緣點。

祝你好運!這是一個有趣的問題。

編輯: 我正在閱讀另一個StackOverflow帖子和閱讀有關本文。這篇論文將給你一個更徹底的介紹,我介紹了我建議過濾邊緣點的技巧(第8項)。

「快速圓檢測採用梯度對矢量」由RAD,Faez和Qaragozlou http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.121.9956

我還沒有實現他們的算法自己還,但它看起來很有希望。以下是論文提及的帖子:

Three Dimensional Hough Space