我正在研究应该作为地平线检测的项目。我使用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;
}
答案 0 :(得分:4)
您可以使用arcLength
- 函数(http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#arclength)根据长度过滤轮廓。
如果轮廓长度超过某个阈值,或者只过滤最长轮廓,则可以检查。