2012-08-24 145 views
9

目前我正在開發圖像處理項目,我正在使用javacv開發圖像處理組件。我能夠提取圖像的一些有趣的部分,現在我需要讀取這些對象的x和y座標。 這是我haveextracted如何獲取javacv中提取的對象的x,y座標?

enter image description here

的形象,我需要確定這些對象和周圍的這些對象平方得出。我瀏覽了一些教程,並嘗試使用以下代碼來識別對象。

IplImage img="sourceimage"; 
    CvSize sz = cvSize(img.width(), img.height()); 
    IplImage gry=cvCreateImage(sz, img.depth(), 1); 
    cvCvtColor(img, gry, CV_BGR2GRAY); 
    cvThreshold(gry, gry, 200, 250, CV_THRESH_BINARY); 


    CvMemStorage mem = CvMemStorage.create(); 
    CvSeq contours = new CvSeq(); 
    CvSeq ptr = new CvSeq(); 
    cvFindContours(gry, mem, contours, Loader.sizeof(CvContour.class) , CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0)); 

    CvRect boundbox; 

    for (ptr = contours; ptr != null; ptr = ptr.h_next()) { 
     boundbox = cvBoundingRect(ptr, 0); 
     if(boundbox.height()>10||boundbox.height()>10){ 
      cvRectangle(gry, cvPoint(boundbox.x(), boundbox.y()), cvPoint(boundbox.x() + boundbox.width(), boundbox.y() + boundbox.height()),CvScalar.BLUE, 0, 0, 0); 
      System.out.println(boundbox.x()+", "+boundbox.y()); 
     } 
    } 
    cvShowImage("contures", gry); 
    cvWaitKey(0); 

但它並沒有繪製爲圍繞對象的矩形。我想知道我是否可以使用cvFindContours方法來識別這些對象?請解釋一下如何使用javacv/opencv存檔我的目標?

+0

因此,當你繪製這些矩形時,它們與你所擁有的物體有什麼關係? – MahdeTo

+0

爲什麼忽略你的問題的答案? – ArtemStorozhuk

+0

@MahdeTo我需要知道如何在這些對象周圍繪製矩形。 –

回答

11

試着通過下面的代碼,它會給你的問題的答案。

IplImage img=cvLoadImage("pathtosourceimage"); 
    CvSize cvSize = cvSize(img.width(), img.height()); 
    IplImage gry=cvCreateImage(cvSize, img.depth(), 1); 
    cvCvtColor(img, gry, CV_BGR2GRAY); 
    cvThreshold(gry, gry, 200, 255, CV_THRESH_BINARY); 
    cvAdaptiveThreshold(gry, gry, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 11, 5); 

    CvMemStorage storage = CvMemStorage.create(); 
    CvSeq contours = new CvContour(null); 

    int noOfContors = cvFindContours(gry, storage, contours, Loader.sizeof(CvContour.class), CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, new CvPoint(0,0)); 

    CvSeq ptr = new CvSeq(); 

    int count =1; 
    CvPoint p1 = new CvPoint(0,0),p2 = new CvPoint(0,0); 

    for (ptr = contours; ptr != null; ptr = ptr.h_next()) { 

     CvScalar color = CvScalar.BLUE; 
     CvRect sq = cvBoundingRect(ptr, 0); 

      System.out.println("Contour No ="+count); 
      System.out.println("X ="+ sq.x()+" Y="+ sq.y()); 
      System.out.println("Height ="+sq.height()+" Width ="+sq.width()); 
      System.out.println(""); 

      p1.x(sq.x()); 
      p2.x(sq.x()+sq.width()); 
      p1.y(sq.y()); 
      p2.y(sq.y()+sq.height()); 
      cvRectangle(img, p1,p2, CV_RGB(255, 0, 0), 2, 8, 0); 
      cvDrawContours(img, ptr, color, CV_RGB(0,0,0), -1, CV_FILLED, 8, cvPoint(0,0)); 
      count++; 

    } 

    cvShowImage("contures",img); 
    cvWaitKey(0); 

這是我爲你的圖像獲得的輸出。

enter image description here

4

cvFindContours是您的問題的正確解決方案。
我已經驗證它對您的圖像有效。
Here is my experiment

你有System.out.println裏面,輸出是什麼?

cvFindContours可能會很難使用,我已經將它包裝成一個more general C++ function。我還使用class called vBlob來描述cvFindContours檢測到的對象。從我從Java代碼中看到的,Java版本API與C/C++版本非常相似。所以重寫它並不難。

ps。阿斯特給出了正確的答案。

4

你知道findContours功能上找到黑色背景白色輪廓?

只要在您的圖片中使用bitwise_not(或JavaCV中的模擬)並在此之後應用findContours即可。這實際上解決了你的問題。

4

不需要第三方庫!什麼你正在尋找能在OpenCV中使用稱爲bounding box的技術來實現:

enter image description here

的技巧是使用cvFindContours()檢索輪廓,然後cvApproxPoly()改善的結果。請注意,您必須使用cvNot()反轉輸入圖像的顏色,因爲cvFindContours()搜索白色輪廓。

  • this post有一個很好的輪廓介紹。
  • 有一個Java demo,實現了檢測車牌號的邊界框版本。

順便說一句cvMinEnclosingCircle()返回圓的中心爲CvPoint2D32f

+0

您是否從問題中讀取了代碼,實際上是問題本身?他已經知道如何找到邊界框。在這種情況下'approxPoly'如何改善結果?問題是topicstarter不明白他爲什麼會得到1個矩形。而我已經解釋了原因。 – ArtemStorozhuk

+1

@Astor,如果不是更好的理由,你不應該與karlphillip爭論,至少是禮貌。你知道,你總是應該尊重你的長輩。而且他在這裏,在opencv標籤上;)這就像告訴Jon Skeet他的代碼不能編譯 – Sam

2

我使用C++ api,但我認爲應該在javacv中有一個名爲drawContours或cvDrawContours的函數,它使用findContours的輸出。

+0

但findContours的輸出是整個圖像。 – ArtemStorozhuk