利用vector迭代器(iterator)遍历内容,利用erase()函数删除轮廓,实验设计为小于20的轮廓被删除,为了效果更明显,在阈值分割前不做平滑和滤波的处理,代码如下:
代码语言:javascript复制#include<iostream>
#include <cv.h>
#include <highgui.h>
#include <cvaux.h>
#include <tchar.h>
using namespace std;
using namespace cv;
int main()
{
Mat srcImage;
Mat thresholdImage;
Mat grayImage;
srcImage = imread("1.png");
cvtColor(srcImage,grayImage,CV_BGR2GRAY);
threshold(grayImage, thresholdImage, 0, 255, CV_THRESH_OTSU CV_THRESH_BINARY);
Mat resultImage;
thresholdImage.copyTo(resultImage);
vector< vector< Point> > contours;
findContours(resultImage,contours,CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
vector<vector<Point> >::iterator itc= contours.begin();
while (itc!=contours.end())
{
if( itc->size()<20)
{
itc= contours.erase(itc);
}
else
{
itc;
}
}
drawContours(resultImage, contours, -1, Scalar(255), CV_FILLED);
imshow("原图",srcImage);
imshow("灰度",grayImage);
imshow("二值图",thresholdImage);
imshow("结果图",resultImage);
waitKey(0);
return 0;
}
实验结果:
可以看到,轮廓面积小于20个像素的被删除了。
补充一下drawContours()函数:主要用于画出图像的轮廓
代码语言:javascript复制CV_EXPORTS_W void drawContours( InputOutputArray image,
InputArrayOfArrays contours,
int contourIdx,
const Scalar& color,
int lineType=8,
InputArray hierarchy=noArray(),
int maxLevel=INT_MAX,
Point offset=Point() );
其中第一个参数image表示目标图像, 第二个参数contours表示输入的轮廓组,每一组轮廓由点vector构成, 第三个参数contourIdx指明画第几个轮廓,如果该参数为负值,则画全部轮廓, 第四个参数color为轮廓的颜色, 第五个参数thickness为轮廓的线宽,如果为负值或CV_FILLED表示填充轮廓内部, 第六个参数lineType为线型, 第七个参数为轮廓结构信息, 第八个参数为maxLevel