2012-04-23 19 views
5

Tôi sử dụng findContours để phát hiện đốm màu. Bây giờ tôi sẽ hợp nhất các khối màu gần và giống nhau lại với nhau.Làm cách nào để hợp nhất các đốm màu/đường viền

Dưới đây là một số hình ảnh mẫu:

enter image description hereenter image description hereenter image description here

Là có thể với OpenCV bình thường không?

+0

Bạn có thể gửi một hình ảnh minh họa? – karlphillip

+0

Tốt hơn nếu bạn thêm hình ảnh. Tải lên trong imageshack.us và cung cấp liên kết tại đây. Đồng thời xác định ý bạn là gì. Nó có hình dạng tương tự không? Hoặc có khu vực tương tự? vv –

+0

ok tôi muốn kết hợp hình dạng tương tự bên cạnh nhau. Dưới đây là ba ví dụ (đánh dấu là màu vàng) nhờ giúp đỡ! [Hình 1] (http://img713.imageshack.us/img713/2152/image1xg.png) [Hình 2] (http://img32.imageshack.us/img32/2149/image2kl.png) [Hình 3] (http://img256.imageshack.us/img256/1000/image3jg.png) – rouge

Trả lời

3

Những hình ảnh đầu vào bạn đã cho chúng tôi là khá dễ dàng để làm việc với:

enter image description hereenter image description hereenter image description here

Bước đầu tiên là cô lập các đốm màu vàng từ mọi thứ khác và một kỹ thuật phân chia nhỏ màu đơn giản có thể thực hiện điều này bài tập. Bạn có thể xem Segmentation & Object Detection by color hoặc Tracking colored objects in OpenCV để có ý tưởng về cách thực hiện.

enter image description hereenter image description hereenter image description here

Sau đó, nó là thời gian để hợp nhất các đốm màu. Một kỹ thuật đặc biệt có thể hữu ích là bounding box, để đặt tất cả các đốm màu bên trong một hình chữ nhật. Chú ý trong hình ảnh dưới đây, rằng có một hình chữ nhật màu xanh lá cây xung quanh các đốm màu:

enter image description hereenter image description hereenter image description here

Sau đó, tất cả các bạn cần làm là điền hình chữ nhật với màu sắc của sự lựa chọn của bạn, do đó kết nối tất cả các đốm màu. Tôi sẽ để bài này làm bài tập về nhà cuối cùng cho bạn.

Đây là cách tiếp cận nhanh nhất và đơn giản nhất mà tôi có thể nghĩ đến. Các mã sau minh họa cách để đạt được những gì tôi vừa mô tả:

#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 cho câu trả lời của bạn ... nhưng bạn hiểu lầm tôi một chút. Các đốm màu vàng không thực sự màu vàng.Tôi chỉ tô màu chúng để cho bạn thấy những đốm màu phù thủy mà tôi sẽ cố gắng hợp nhất. vì vậy tôi không thể sử dụng phân đoạn màu để cô lập các đốm màu khác. Ngoài ra thông tin như khu vực sẽ không hoạt động bởi vì có lẽ có một số phù thủy blobs lớn hơn tôi không thích hợp nhất ... – rouge

+0

Bah! = \ sẽ nghĩ về điều gì đó khác sau này. – karlphillip

+0

Bạn quan tâm đến các đốm màu lớn nhất, phải không? – karlphillip

2

tôi nghĩ rằng tôi đã làm điều đó, nhờ vào chi tiết chương trình của bạn tôi tìm thấy giải pháp này: (bình luận được hoan nghênh)

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; 
    } 
Các vấn đề liên quan