David Markovič
David Markovič

Reputation: 55

C++ OpenCV How to eliminate small edges or small area of contours

I am working on project which should work as horizon detection. I am using canny edge and contours for horizon detection. It works quite fine, but I have problem with small area of edges>contours which werent eliminated by high cannythreshold and morfolocigal operation. If I use higher threshold on canny I start to loose some of the horizon edges.

So question is, how to get rid of small area of edges/contours? Or how do I display only one biggest contour?

This pictures shows how it should look like:

https://i.sstatic.net/f4USX.png

This picture is taken with small area on contours which i need to eliminate:

https://i.sstatic.net/TQi0v.jpg

And here is my code:

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include <sstream>
#include <string>
#include <iostream>
#include <opencv\highgui.h>
#include <opencv\cv.h>
#include <opencv\ml.h>

using namespace cv;
using namespace std;

vector<Vec4i> lines;
vector<vector<Point> > contours0;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

int MAX_KERNEL_LENGTH = 31;


int main(int argc, char** argv)
{

    string filename = "test.avi";
    VideoCapture cap(filename); 
    if(!cap.isOpened())  
        return -1;

    Mat edges,grey;
    namedWindow("edges",1);
    for(;;)
    {
        Mat frame;
        cap >> frame; 
        cvtColor(frame, grey, CV_BGR2GRAY);


        GaussianBlur(grey, grey, Size(5,5),0);


        Mat erodeElement = getStructuringElement( MORPH_RECT,Size(10,10));
        Mat dilateElement = getStructuringElement( MORPH_RECT,Size(10,10));


        erode(grey,grey,erodeElement);
        dilate(grey,grey,dilateElement);
        Canny(grey, edges, 150,300, 3);


    findContours( edges, contours0, hierarchy,
        CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );

    contours.resize(contours0.size());
    for( size_t k = 0; k < contours0.size(); k++ ){
         approxPolyDP(Mat(contours0[k]), contours[k], 5, true);
    }

    int idx = 0;
    for( ; idx >= 0; idx = hierarchy[idx][0] )
    {
        drawContours( frame, contours, idx, Scalar(128,255,255), 5, 8, hierarchy );
    }

        imshow("frame", frame);
        imshow("grey", grey);
        imshow("edges", edges);
        if(waitKey(30) >= 0) break;
    }

    return 0;
}

Upvotes: 2

Views: 2540

Answers (1)

Dennis
Dennis

Reputation: 521

You can filter your contours depending on their length using arcLength-function (http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#arclength).
Either you can check, if the contours are longer than a certain threshold or you only filter the longest contour.

Upvotes: 4

Related Questions