2012-04-23 11 views
5

मैं ब्लॉब पहचान के लिए findContours का उपयोग करता हूं। अब मैं एक साथ करीबी और समान ब्लॉब्स विलय कर दूंगा।मैं ब्लॉब्स/समोच्चों को कैसे विलय कर सकता हूं

enter image description hereenter image description hereenter image description here

कि सामान्य OpenCV के साथ संभव है:

यहां कुछ ऐसे नमूना छवियों कर रहे हैं?

+0

आप पोस्ट कर सकते हैं एक नमूना छवि? – karlphillip

+0

बेहतर अगर आप एक छवि जोड़ते हैं। Imageshack.us में अपलोड करें और यहां लिंक दें। यह भी निर्दिष्ट करें कि आप इसी तरह से क्या मतलब है। क्या यह आकार में समान है? या समान क्षेत्र है? आदि –

+0

ठीक है, मैं एक दूसरे के बगल में समान आकार मर्ज करना चाहता हूं। यहां तीन उदाहरण हैं (पीले रंग के रूप में चिह्नित करें) सहायता के लिए धन्यवाद! [छवि 1] (http://img713.imageshack.us/img713/2152/image1xg.png) [छवि 2] (http://img32.imageshack.us/img32/2149/image2kl.png) [छवि 3] (http://img256.imageshack.us/img256/1000/image3jg.png) – rouge

उत्तर

3

इनपुट छवियों को आप दे दी हमें सुंदर के साथ काम करने के लिए आसान कर रहे हैं:

enter image description hereenter image description hereenter image description here

पहला कदम सब कुछ से पीले धब्बे को अलग और एक सरल रंग विभाजन तकनीक यह पूरा कर सकते हैं कार्य। आप इसे कैसे करना है इस पर विचार करने के लिए Segmentation & Object Detection by color या Tracking colored objects in OpenCV पर एक नज़र डालें।

enter image description hereenter image description hereenter image description here

फिर, यह धब्बे विलय करने के लिए समय है। विशेष रूप से एक तकनीक जो उपयोगी हो सकती है bounding box, पर सभी ब्लॉब्स को आयताकार के अंदर रखें। नीचे दी गई छवियों में सूचना, एक हरे रंग धब्बे आसपास आयत है कि वहाँ:

enter image description hereenter image description hereenter image description here

उसके बाद, तुम सब करने की जरूरत है अपनी पसंद के रंग के साथ आयत को भरने, इस प्रकार जोड़ने सभी blobs। मैं इसे आपके लिए होमवर्क के रूप में छोड़ रहा हूं।

यह सबसे तेज़ और सबसे आसान तरीका है जिसे मैं सोच सकता हूं। कैसे प्राप्त करने के लिए निम्न कोड को दर्शाया है जिसे मैं सिर्फ वर्णित:

#include <cv.h> 
#include <highgui.h> 

#include <iostream> 
#include <vector> 

int main(int argc, char* argv[]) 
{ 
    cv::Mat img = cv::imread(argv[1]); 
    if (!img.data) 
    { 
     std::cout "!!! Failed to open file: " << argv[1] << std::endl; 
     return 0; 
    } 

    // Convert RGB Mat into HSV color space 
    cv::Mat hsv; 
    cv::cvtColor(img, hsv, CV_BGR2HSV); 

    // Split HSV Mat into HSV components 
    std::vector<cv::Mat> v; 
    cv::split(hsv,v); 

    // Erase pixels with low saturation 
    int min_sat = 70; 
    cv::threshold(v[1], v[1], min_sat, 255, cv::THRESH_BINARY); 

    /* Work with the saturated image from now on */ 

// Erode could provide some enhancement, but I'm not sure. 
// cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)); 
// cv::erode(v[1], v[1], element); 

    // Store the set of points in the image before assembling the bounding box 
    std::vector<cv::Point> points; 
    cv::Mat_<uchar>::iterator it = v[1].begin<uchar>(); 
    cv::Mat_<uchar>::iterator end = v[1].end<uchar>(); 
    for (; it != end; ++it) 
    { 
     if (*it) points.push_back(it.pos()); 
    } 

    // Compute minimal bounding box 
    cv::RotatedRect box = cv::minAreaRect(cv::Mat(points)); 

    // Display bounding box on the original image 
    cv::Point2f vertices[4]; 
    box.points(vertices); 
    for (int i = 0; i < 4; ++i) 
    { 
      cv::line(img, vertices[i], vertices[(i + 1) % 4], cv::Scalar(0, 255, 0), 1, CV_AA); 
    } 

    cv::imshow("box", img); 
    //cv::imwrite(argv[2], img); 

    cvWaitKey(0); 

    return 0; 
} 
+0

thx ... लेकिन आपने मुझे थोड़ा सा गलत समझा। पीले रंग के blobs वास्तव में पीले रंग नहीं हैं।मैंने उन्हें आपको चुड़ैल ब्लब्स दिखाने के लिए रंग दिया है, मैं विलय करने की कोशिश करूंगा। इसलिए मैं अन्य ब्लॉब्स को अलग करने के लिए रंग विभाजन का उपयोग करने में सक्षम नहीं हूं। क्षेत्र की तरह जानकारी भी काम नहीं करेगी क्योंकि शायद कुछ अन्य बड़े ब्लॉब्स चुड़ैल हैं जो मैं विलय करना पसंद नहीं करता ... – rouge

+0

बह! = \ बाद में कुछ और के बारे में सोचना होगा। – karlphillip

+0

आप सबसे बड़े ब्लॉब्स में रुचि रखते हैं, है ना? – karlphillip

2

मुझे लगता है कि मैं यह किया, धन्यवाद अपने कार्यक्रम विवरण के लिए मैं इस समाधान पाया: (टिप्पणियों का स्वागत है)

vector<vector<Point> > contours; 
    vector<vector<Point> > tmp_contours; 
    findContours(detectedImg, tmp_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); 

    vector<vector<Point> >::iterator it1; 
    it1 = tmp_contours.begin(); 

    Mat test; 
    test = Mat(FImage.size(), CV_32FC3); 

    while (it1 != tmp_contours.end()) { 
     vector<Point> approx1; 
     approxPolyDP(Mat(*it1), approx1, 3, true); 
     Rect box1 = boundingRect(approx1); 
     float area1 = contourArea(approx1); 



     if ((area1 > 50) && (area1 < 13000) && (box1.width < 100) && (box1.height < 120)) { 

      vector<vector<Point> >::iterator it2; 
      it2 = tmp_contours.begin(); 

      while (it2 != tmp_contours.end()) { 
       vector<Point> approx2; 
       approxPolyDP(Mat(*it2), approx2, 3, true); 

       Moments m1 = moments(Mat(approx1), false); 
       Moments m2 = moments(Mat(approx2), false); 
       float x1 = m1.m10/m1.m00; 
       float y1 = m1.m01/m1.m00; 
       float x2 = m2.m10/m2.m00; 
       float y2 = m2.m01/m2.m00; 

       vector<Point> dist; 
       dist.push_back(Point(x1, y1)); 
       dist.push_back(Point(x2, y2)); 
       float d = arcLength(dist, false); 

       Rect box2 = boundingRect(approx2); 
       if (box1 != box2) { 

        if (d < 25) { 
         //Method to merge the vectors 
         approx1 = mergePoints(approx1, approx2); 
        } 

       } 
       ++it2; 

      } 
      Rect b = boundingRect(approx1); 
      rectangle(test, b, CV_RGB(125, 255, 0), 2); 
      contours.push_back(approx1); 
     } 
     ++it1; 
    } 
संबंधित मुद्दे