mode的值决定把找到的轮廓如何挂到轮廓树节点变量(h_prev, h_next, v_prev, v_next)上。下图展示了四种可能的mode值所得到的结果的拓扑结构。
(a) (b)
图1 (a)原图示意图,(b)mode不同类型的拓扑结构
Mat CreateTestImage();
int main(int argc, _TCHAR* argv[])
{
Mat src = CreateTestImage();
Mat gray;
cvtColor(src, gray, CV_BGR2GRAY);
Mat bw;
cv::threshold(gray, bw, 128, 255,THRESH_BINARY);
vector
vector
cv::findContours(gray, contours, hierarchy,
CV_RETR_EXTERNAL
, CV_CHAIN_APPROX_NONE );
Mat dst = Mat ::zeros(src.size(),CV_8UC3);
drawContours(dst, contours, -1, Scalar(255,255, 255));
cv::namedWindow("src",0);
cv::imshow("src",src);
cv::namedWindow("dst",0);
cv::imshow("dst",dst);
cv::waitKey();
system("pause");
return 0;
}
Mat CreateTestImage()
{
//第一层,绘制一个黑色背景的图像
int nWidth = 557;
int nHeight = 291;
Mat dst = Mat::zeros(nHeight,nWidth,CV_8UC3);
//第二层,绘制一个白色矩形,上下左右各有等距边框
int nBorder = 20;
int nX2 = nBorder;
int nY2 = nBorder;
int nWidth2 = nWidth -nBorder*2 ;
int nHeight2 = nHeight - nBorder*2;
cv::rectangle(dst,cv::Rect(nX2,nY2,nWidth2,nHeight2),cv::Scalar(255,255,255),-1);
//第三层,在第二层中间绘制两个黑色矩形,上下左右各有等距边框,两个黑色矩形间距一个边框距离
int nX3 = nX2 + nBorder;
int nY3 = nY2 + nBorder;
int nWidth3 = (nWidth2-nBorder*3)*0.5 ;
int nHeight3 =(nHeight2-nBorder*2) ;
int nX3_1 = nX3+nWidth3+nBorder;
cv::rectangle(dst,cv::Rect(nX3,nY3,nWidth3,nHeight3),cv::Scalar(0,0,0),-1);
cv::rectangle(dst,cv::Rect(nX3_1,nY3,nWidth3,nHeight3),cv::Scalar(0,0,0),-1);
//第四层,在第三层两个黑色矩形中再分别绘制两个白色矩形,上下左右各有等距边框
int nX4 = nX3 + nBorder;
int nY4 = nY3 + nBorder;
int nWidth4 = (nWidth3-nBorder*2);
int nHeight4 =(nHeight3-nBorder*2) ;
int nX4_1 = nX3_1+nBorder;
cv::rectangle(dst,cv::Rect(nX4,nY4,nWidth4,nHeight4),cv::Scalar(255,255,255),-1);
cv::rectangle(dst,cv::Rect(nX4_1,nY4,nWidth4,nHeight4),cv::Scalar(255,255,255),-1);
//第五层,在第四层两个白色矩形中再分别绘制两个黑色矩形,上下左右各有等距边框
int nX5 = nX4 + nBorder;
int nY5 = nY4 + nBorder;
int nWidth5 = (nWidth4-nBorder*2);
int nHeight5 =(nHeight4-nBorder*2) ;
int nX5_1 = nX4_1+nBorder;
cv::rectangle(dst,cv::Rect(nX5,nY5,nWidth5,nHeight5),cv::Scalar(0,0,0),-1);
cv::rectangle(dst,cv::Rect(nX5_1,nY5,nWidth5,nHeight5),cv::Scalar(0,0,0),-1);
//第六层,在第⑤层第二个矩形绘制四个白色矩形,上下左右各有等距边框,四个白色矩形间距一个边框距离,只绘制下方两个矩形
int nWidth6 = (nWidth5-nBorder*3)*0.5 ;
int nHeight6 =(nHeight5-nBorder*3)*0.5 ;
int nX6 = nX5_1 + nBorder;
int nY6 = nY5 + nBorder + nHeight6 + nBorder;
int nX6_1 = nX6 + nWidth6 + nBorder;
cv::rectangle(dst,cv::Rect(nX6,nY6,nWidth6,nHeight6),cv::Scalar(255,255,255),-1);
cv::rectangle(dst,cv::Rect(nX6_1,nY6,nWidth6,nHeight6),cv::Scalar(255,255,255),-1);
return dst;
}
|
Mat CreateTestImage();
int main(int argc, _TCHAR* argv[])
{
Mat src = CreateTestImage();
Mat gray;
cvtColor(src, gray, CV_BGR2GRAY);
Mat bw;
cv::threshold(gray, bw, 128, 255,THRESH_BINARY);
vector
vector
cv::findContours(gray, contours, hierarchy, CV_RETR_LIST, CV_LINK_RUNS);
Mat dst = Mat ::zeros(src.size(),CV_8UC3);
drawContours(dst, contours, -1, Scalar(255,255, 255));
for each(vector
{
for each(Point pt in contour)
{
cv::circle(dst,pt,1,Scalar(0,0, 255),-1);
}
}
cv::namedWindow("src",0);
cv::imshow("src",src);
cv::namedWindow("dst",0);
cv::imshow("dst",dst);
cv::waitKey();
system("pause");
return 0;
}
|
thickness=CV_FILLED
), the contour interiors are drawn”