2014-09-04 5 views
5

के साथ ओवरलैपिंग/जटिल सर्कल खोजें I लाल रेड सर्कल त्रिज्या (अंजीर 2) की गणना करना चाहते हैं। मुझे OpenCV से HoughCircles का उपयोग करके इन मंडलियों को ढूंढने में परेशानी है। जैसा कि आप अंजीर में देख सकते हैं। 2 मैं केवल केंद्र में छोटी सर्कल पा सकता हूं जो हौकक्रिकल का उपयोग करके काले रंग में दिखाए जाते हैं।ओपनसीवी

मूल pic1 अंजीर 2. red

जब से मैं लाल मंडलियां (जिसमें लाल के समान होती हैं) के केंद्र में पता है, वहाँ बस लाल हलकों की त्रिज्या की गणना करने के लिए एक रास्ता है?

यह भी एक अधिक जटिल छवि पर हलकों की त्रिज्या की गणना इस तरह के रूप में एक के एक सामान्य तरीके करना संभव है:

example 2

संपादित करें: अंजीर 2 प्राप्त करने के बाद यहाँ मेरी कोड के दिलचस्प हिस्सा :

threshold(maskedImage, maskedImage, thresh, 255, THRESH_BINARY_INV | THRESH_OTSU); 
    std::vector<Vec3f> circles; 
// Canny(maskedImage, maskedImage, thresh, thresh * 2, 3); 

HoughCircles(maskedImage, circles, CV_HOUGH_GRADIENT, 1, src_gray.rows/4, cannyThreshold, accumulatorThreshold, 0, 0); 

Mat display = src_display.clone(); 
for (size_t i = 0; i < circles.size(); i++) 
{ 
    Point center(cvRound(circles[i][0]), cvRound(circles[i][1])); 
    int radius = cvRound(circles[i][2]); 
    // circle center 
    circle(display, center, 3, Scalar(0, 255, 0), -1, 8, 0); 
    // circle outline 
    circle(display, center, radius, Scalar(0, 0, 255), 3, 8, 0); 
} 

मैंने परिणामों के बिना CannyTreshold और accumulator के साथ खेलने का उपयोग करने का प्रयास किया है। वास्तविक छवियां 5x बड़ी हैं। यहां a link उदाहरण के लिए थ्रेसहोल्ड के बाद 1।

धन्यवाद

+0

क्या आप अपना HoughCircles कोड दिखा सकते हैं? ओवरलैपिंग/आधा चक्र आदि सामान्य रूप से HoughCircles afaik के लिए एक समस्या नहीं हैं। – Micka

+0

धन्यवाद मिका मैंने अभी कुछ कोड – coincoin

+1

जोड़ा है क्या आप एक फ़ाइल में मास्क किए गए इमेज को सहेज सकते हैं ('imwrite (" maskedImage.jpg ", maskedImage)') और एक लिंक पोस्ट करें? –

उत्तर

5

आप पहले से ही छवि में छोटे मंडलियां (जिसमें आप काले रंग में तैयार की है) पता है।

  • इन सर्किलों का उपयोग करके एक मुखौटा छवि तैयार करें ताकि छोटे मंडल वाले क्षेत्रों में गैर-शून्य पिक्सल हों। हम फोन करता हूँ यह मुखौटा: मूल छवि में

enter image description here

  • , एक काले रंग में इन वृत्त भरण क्षेत्रों (काला कहते हैं)। इसके परिणामस्वरूप आपकी अंजीर 2 जैसी छवि होगी। हम इसे भरे
  • थ्रेसहोल्ड अंधेरे क्षेत्रों को प्राप्त करने के लिए छवि भरें। हम इसे बाइनरी पर कॉल करेंगे। आप इसके लिए ओत्सु थ्रेसहोल्डिंग का उपयोग कर सकते हैं। परिणाम कुछ इस तरह दिखेगा:

enter image description here

  • लो दूरी इस द्विआधारी छवि के बदलने। इसके लिए एक सटीक दूरी अनुमान विधि का प्रयोग करें। हम इसे dist पर कॉल करेंगे। यह ऐसा कुछ दिखाई देगा।

enter image description hereenter image description here

  • उपयोग मुखौटाजिले से शिखर क्षेत्रों प्राप्त करने के लिए: रंग का एक और स्पष्टता के लिए सिर्फ एक हीट मैप है। इस तरह के प्रत्येक क्षेत्र के अधिकतम मूल्य को आपको बड़े सर्कल का त्रिज्या देना चाहिए। आप अधिकतम क्षेत्रों को चुनने के बजाए त्रिज्या के लिए अधिक उचित मूल्य पर पहुंचने के लिए इन क्षेत्रों पर कुछ प्रसंस्करण भी कर सकते हैं।
  • क्षेत्रों का चयन करने के लिए, आप या तो मुखौटा की रूपरेखा पा सकते हैं और उसके बाद जिले छवि से उस क्षेत्र को निकालने, या, क्योंकि आप पहले से ही hough सर्कल बदलने लागू करने से छोटे हलकों पता है, से एक मुखौटा तैयार उन मंडलियों में से प्रत्येक और dist छवि से उस क्षेत्र को निकालें। मुझे यकीन नहीं है कि क्या आप मुखौटा देकर अधिकतम या अन्य आंकड़ों की गणना कर सकते हैं। मैक्स निश्चित रूप से काम करेगा क्योंकि बाकी पिक्सेल 0 हैं। यदि आप उन पिक्सेल को किसी अन्य सरणी में निकालते हैं तो आप क्षेत्र के आंकड़ों की गणना कर सकते हैं।

नीचे दिए गए आंकड़े dist से ऐसे मुखौटा और निकाले गए क्षेत्र को दिखाते हैं। इसके लिए मुझे अधिकतम 2 9 मिलता है जो उस सर्कल के त्रिज्या के अनुरूप होता है। ध्यान दें कि छवियों को स्केल नहीं करना है।

जिले

enter image description hereenter image description here

यहाँ से एक चक्र के लिए मुखौटा, निकाले क्षेत्र (मैं का उपयोग नहीं hough-हलकों को बदलने) कोड है:

Mat im = imread(INPUT_FOLDER_PATH + string("ex1.jpg")); 

    Mat gray; 
    cvtColor(im, gray, CV_BGR2GRAY); 

    Mat bw; 
    threshold(gray, bw, 0, 255, CV_THRESH_BINARY|CV_THRESH_OTSU); 
    // filtering smaller circles: not using hough-circles transform here. 
    // you can replace this part with you hough-circles code. 
    vector<int> circles; 
    vector<vector<Point>> contours; 
    vector<Vec4i> hierarchy; 
    findContours(bw, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); 
    for(int idx = 0; idx >= 0; idx = hierarchy[idx][0]) 
    { 
     Rect rect = boundingRect(contours[idx]); 
     if (abs(1.0 - ((double)rect.width/rect.height) < .1)) 
     { 
      Mat mask = Mat::zeros(im.rows, im.cols, CV_8U); 
      drawContours(mask, contours, idx, Scalar(255, 255, 255), -1); 
      double area = sum(mask).val[0]/255; 
      double rad = (rect.width + rect.height)/4.0; 
      double circArea = CV_PI*rad*rad; 
      double dif = abs(1.0 - area/circArea); 
      if (dif < .5 && rad < 50 && rad > 30) // restrict the radius 
      { 
       circles.push_back(idx); // store smaller circle contours 
       drawContours(gray, contours, idx, Scalar(0, 0, 0), -1); // fill circles 
      } 
     } 
    } 

    threshold(gray, bw, 0, 255, CV_THRESH_BINARY_INV|CV_THRESH_OTSU); 

    Mat dist, distColor, color; 
    distanceTransform(bw, dist, CV_DIST_L2, 5); 
    double max; 
    Point maxLoc; 
    minMaxLoc(dist, NULL, &max); 
    dist.convertTo(distColor, CV_8U, 255.0/max); 
    applyColorMap(distColor, color, COLORMAP_JET); 
    imshow("", color); 
    waitKey(); 

    // extract dist region corresponding to each smaller circle and find max 
    for(int idx = 0; idx < (int)circles.size(); idx++) 
    { 
     Mat masked; 
     Mat mask = Mat::zeros(im.rows, im.cols, CV_8U); 
     drawContours(mask, contours, circles[idx], Scalar(255, 255, 255), -1); 
     dist.copyTo(masked, mask); 
     minMaxLoc(masked, NULL, &max, NULL, &maxLoc); 
     circle(im, maxLoc, 4, Scalar(0, 255, 0), -1); 
     circle(im, maxLoc, (int)max, Scalar(0, 0, 255), 2); 
     cout << "rad: " << max << endl; 
    } 
    imshow("", im); 
    waitKey(); 

परिणाम (बढ़ाया):

enter image description hereenter image description here

उम्मीद है कि इससे मदद मिलती है।

+0

धन्यवाद यह एक अच्छा विचार है। मैंने आपके द्वारा दूरस्थ ट्रान्सफॉर्म का उपयोग करके वही परिणाम प्राप्त किए हैं। (जिस तरह से आप दूरी मानचित्र लागू करते हैं, रंगरैप मेरे लिए काम नहीं कर रहा है)। हालांकि मुझे नहीं लगता कि मैं सर्कल त्रिज्या को कैसे अलग कर सकता हूं और इन अधिकतम मूल्यों को प्रभावी ढंग से गणना कर सकता हूं? – coincoin

+1

ओपनसीवी में, दूरी परिवर्तन परिणाम प्रकार फ्लोट होगा। इसे 0-255 रेंज तक स्केल करने और uint8 टाइप करने के लिए कनवर्ट करने का प्रयास करें। फिर लागू करें CollorMap काम करेगा। अधिकतम मूल्य प्राप्त करने के लिए, यह देखने के लिए कि मैंने आपके प्रश्न का उत्तर दिया है, मेरी संपादित पोस्ट देखें। – dhanushka

+0

आपके लिए मूल्यवान उत्तर के लिए धन्यवाद। मुझे नक्शा रंग मिला लेकिन मुझे समझ में कठिनाई है कि मैं मुखौटा छवियों और छोटे सर्किलों के केंद्र का उपयोग करके इस क्षेत्र को कैसे निकाला जा सकता हूं। क्या आप इस भाग को विस्तार से बता सकते हैं? – coincoin