C ++ OpenCV如何消除小边缘或小面积轮廓

时间:2014-02-23 09:03:16

标签: c++ opencv

我正在研究应该作为地平线检测的项目。我使用canny edge和contours进行地平线检测。它工作得很好,但是我有小面积边缘的问题&>轮廓没有通过高cannythreshold和morfolocigal操作消除。如果我在canny上使用更高的阈值,我开始松开一些地平线边缘。

所以问题是,如何摆脱小面积的边缘/轮廓?或者我如何只显示一个最大轮廓?

这张照片显示了它应该是什么样子:

http://i.stack.imgur.com/f4USX.png

这张照片拍摄的是我需要消除的轮廓上的小区域:

http://i.stack.imgur.com/TQi0v.jpg

这是我的代码:

#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;
}

1 个答案:

答案 0 :(得分:4)

您可以使用arcLength - 函数(http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#arclength)根据长度过滤轮廓。
如果轮廓长度超过某个阈值,或者只过滤最长轮廓,则可以检查。