第一个问题:
问题:假如我有如下一张图,我要把边上两个小点去除,又要保留大轮廓内部的空洞,怎么办?
Fig 1.1
函数原型:
C++: void findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point())
C++: void findContours(InputOutputArray image, OutputArrayOfArrays contours, int mode, int method, Point offset=Point())
这两个重载函数只有一个hierarchy的差别。说明如下:
测试: 用以下代码测试一下 contours 和 hierarchy 是怎么对轮廓进行标号的?选择mode = CV_RETR_CCOMP 双层结构。
#include <opencv2\opencv.hpp>
#include <time.h>
using namespace std;
using namespace cv;
//测试findContours,drawContours函数用法
bool verify(vector<Point> input, int min, int max);
int main()
{
Mat src = imread("test.bmp", 1);
Mat dst = Mat::zeros(src.size(), src.type());
//cout<<src.channels(); //画图软件生成3通道图
Mat gray;
cvtColor(src, gray, CV_BGR2GRAY);
Mat thre;
threshold(gray, thre, 127, 255, CV_THRESH_BINARY );
//thre = gray > 1; //这种写法可以替代上面那一句
imshow("thre", thre);
imwrite("thre.bmp", thre);
vector< vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(thre, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
//计算每个轮廓的面积
float temp = 0;
for(int i=0; i<contours.size(); ++i) {
temp = fabs(contourArea(contours[i]));
cout<<"i="<<i<<" area="<<temp<<endl;
}
//我要把单独的小轮廓去掉,而保留大轮廓内部的孔洞
int idx = 0;
for( ; idx >=0; idx = hierarchy[idx][0])
{
if(verify(contours[idx], 200, 90000)) {
Scalar color( rand()&255, rand()&255, rand()&255);
drawContours(dst