2012-08-24 14 views
9

वर्तमान में मैं छवि प्रसंस्करण प्रोजेक्ट विकसित कर रहा हूं और मैं छवि प्रसंस्करण घटकों को विकसित करने के लिए जावैक का उपयोग कर रहा हूं। मैं एक छवि के कुछ दिलचस्प हिस्सों को निकालने में सक्षम था और अब मुझे उन वस्तुओं के एक्स और वाई निर्देशांक पढ़ने की जरूरत है। यह छवि है कि मैंjavacv में निकाले गए ऑब्जेक्ट्स के x, y निर्देशांक कैसे प्राप्त करें?

enter image description here

haveextracted है और मैं उन वस्तुओं की पहचान करने और उन वस्तुओं के आसपास वर्ग आकर्षित करने के लिए की जरूरत है। मैं कुछ ट्यूटोरियल के माध्यम से चला गया और निम्नलिखित कोड का उपयोग कर वस्तुओं की पहचान करने की कोशिश की।

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

@ माहादे मुझे यह जानने की जरूरत है कि इन वस्तुओं के चारों ओर आयताकार कैसे खींचा जाए। –

उत्तर

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 में लपेट लिया है। इसके अलावा मैं ऑब्जेक्ट cvFindContours का पता लगाने के लिए class called vBlob का उपयोग करता हूं। जो मैं आपके जावा कोड से देखता हूं, जावा संस्करण एपीआई सी/सी ++ संस्करण के समान ही है। तो इसे फिर से लिखना मुश्किल नहीं होगा।

ps। एस्टोर ने सही जवाब दिया।

4

आप जानते हैं कि findContours समारोह काला पृष्ठभूमि पर सफेद आकृति पाता था?

बस अपनी छवि में bitwise_not (या जावासीवी में एनालॉग) करें और इसके बाद findContours लागू करें। यह वास्तव में आपकी समस्या के लिए ठीक है।

4

तीसरे पक्ष के पुस्तकालयों की कोई ज़रूरत नहीं है! आप के लिए एक तकनीक bounding box रूप में जाना जाता का उपयोग कर OpenCV में प्राप्त किया जा सकता देख रहे हैं क्या:

enter image description here

चाल cvFindContours() उपयोग करने के लिए आकृति को पुनः प्राप्त करने के लिए और फिर cvApproxPoly() परिणाम में सुधार है। ध्यान दें कि आपको cvNot() का उपयोग करके इनपुट छवि के रंगों को उलटा करना होगा क्योंकि सफेद समोच्चों की खोज करें।

  • this post में समोच्चों के लिए एक अच्छा परिचय है।
  • Java demo है जो कार नंबर प्लेटों का पता लगाने के लिए बाउंडिंग बॉक्स के संस्करण को लागू करता है।

cvMinEnclosingCircle()CvPoint2D32f के रूप में सर्कल का केंद्र लौटाता है।

+0

क्या आपने प्रश्न से एक कोड पढ़ा था और वास्तव में सवाल ही था? वह पहले से ही जानता है कि बाध्यकारी बॉक्स कैसे ढूंढें। और इस स्थिति में 'लगभग पोली' का परिणाम कैसे सुधारता है? समस्या यह है कि विषय-वस्तु को समझ में नहीं आता कि उसे 4 आयत 4 क्यों मिलता है। और मैंने पहले से ही समझाया क्यों। – ArtemStorozhuk

+1

@ एस्टोर, आपको बेहतर कारण के लिए कम से कम सौजन्य से, कार्लफिलिप के साथ बहस नहीं करनी चाहिए। आप जानते हैं, आपको हमेशा अपने बुजुर्गों का सम्मान करना चाहिए। और वह ओपनसीवी टैग पर यहां बड़ा है;) यह जॉन स्कीट को बता रहा है कि उसका कोड – Sam

2

मैं C++ api का उपयोग कर रहा हूं लेकिन मुझे लगता है कि javacv में drawContours या cvDrawContours नामक कुछ फ़ंक्शन भी होना चाहिए जो findContours के आउटपुट का उपयोग करता है।

+0

संकलित नहीं करता है लेकिन findContours का आउटपुट पूरी छवि है। – ArtemStorozhuk