2013-03-26 3 views
0

Я разрабатываю проект OpenCV.C++ OpenCV Устранение меньших контуров

В настоящее время я работаю над определением контуров определенной ROI (Regoin Interest Interest). То, что я хочу достичь, - это устранить все меньшие контуры, другими словами, я не хочу, чтобы эти более мелкие контуры были утоплены вообще.

So Far, если я закодирован этот алгоритм, чтобы сделать эту работу:

КОД:

vector<vector<Point> > contours; 
    vector<Vec4i> hierarchy; 
    findContours(mBlur, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); 
    //-----------------------------------------------------------------------------> 
    //Contours Vectors 
    vector<vector<Point> > contours_poly(contours.size()); 
    vector<Rect> boundRect (contours.size()); 
    vector<Point2f> ContArea(contours.size()); 
    Mat drawing = Mat::zeros(range_out.size(), CV_8UC3); 
    //-----------------------------------------------------------------------------> 
    //Detecting Contours 
    for(int i = 0; i < contours.size(); i++) 
    { 

     ContArea.clear(); 
     ContArea.push_back(Point2f(boundRect[i].x, boundRect[i].y)); 
     ContArea.push_back(Point2f(boundRect[i].x + boundRect[i].width, boundRect[i].y)); 
     ContArea.push_back(Point2f(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height)); 
     ContArea.push_back(Point2f(boundRect[i].x, boundRect[i].y + boundRect[i].height)); 

     double area = contourArea(ContArea); 

     if(area > 2000) 
     { 
      approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true); 
      boundRect[i] = boundingRect(Mat(contours_poly[i])); 


      cout<<"The area of Contour: "<<i<< " is: " <<area<<endl; 

     } 
    } 



    /// Draw polygonal contour + bonding rects 


    ////////////////////////////////////////////////////////////////////////////////// 

    for(int i = 0; i< contours.size(); i++) 
    { 

     Scalar color = Scalar(255,255,255); 
     drawContours(drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point()); 
     fillPoly(drawing, contours, Scalar(255,0,0)); 

    } 

Проблема здесь состоит в том, что это выглядит как если (область> 2000) заявление не выполняется даже я знаю, что некоторые из областей, присутствующих на изображении, намного больше, чем это.

Я пробовал много разных решений, но это выглядит наиболее подходящим для меня.

КЛЮЧЕВЫЕ ВОПРОСЫ:

Можно ли добиться того, что я хочу с данным кодом ....? Если да, то кто-нибудь может увидеть, где я ошибаюсь Else Может кто-нибудь предложить какое-то решение или хороший онлайн-источник ....?

+0

ОК немного обновить Я удалил оператор if, и я не вижу, что для каждого контура обнаружена область 0, поэтому она должна быть чем-то связана с вычислениями моей области – Tomazi

+0

'boundRect' пуст. Вы только устанавливаете его емкость с помощью 'contours.size()', поэтому я думаю, что они всегда пустые 'Rect'. И еще одно: вы хотите удалить небольшие контуры или небольшие ROI? – Safir

ответ

1

Если вы хотите удалить на основе размера трансформирования, вы можете сделать следующим образом (на основе примера bounding box of opencv):

vector< vector<Point> > contours_poly(contours.size()); 
vector<Rect> boundRect (contours.size()); 
vector<Point2f> centeres (contours.size()); 
vector<float> radiuses (contours.size()); 

// finding the approximate rectangle and circle of contours 
for(int i = 0; i < contours.size(); i++) 
    { 
    approxPolyDP(Mat (contours[i]), contours_poly[i], 3, true); 
    boundRect[i] = boundingRect(Mat (contours_poly[i])); 
    minEnclosingCircle((Mat) contours_poly[i], centeres[i], radiuses[i]); 
    } 

выше фрагмент кода дает приблизительные прямоугольники контуров (boundRect) и приблизительные кружки (centers, radiuses). После этого вы должны иметь возможность звонить contourArea();, и если он меньше определенного порога, вы можете его устранить.


Если вы просто хотите, чтобы удалить контуры, которые меньше определенной длины, вы можете вычислить ее длину, look at the answer to similar question, и кажется, что вы можете использовать arcLength() функцию. Я думаю, что-то вроде этого: double perimeter = arcLength (Mat (contours[i]), true);.

Смежные вопросы