虽然书上说与Canny的区别是,Canny没有将边缘看成整体,这里将边缘看成一个整体的轮廓,但还是没有看出来区别……
程序一:基础的轮廓检测和绘制,基于二值化
int main()
{Mat src=imread("renti2.jpg",0);
Mat dst,result;
threshold(src,dst,160,255,THRESH_BINARY);
//blur(src,src,Size(3,3));
//Canny(src,dst,100,200,3);
result.create(src.size(),CV_8UC3);
imshow("a",dst);
//waitKey(0);
vector<vector<Point>> coutours;
vector<Vec4i> hierarchy;
findContours(dst,coutours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE);
//第一个参数,输入的二值图像
//第二个参数轮廓存储的点向量
//第三个参数,输出向量,hierarchyp[i][0~4]分别代表第i个轮廓的后一个轮廓0,前一个轮廓1,父轮廓2,内嵌轮廓3;
//第四个参数,轮廓检索模式
//第五个参数,轮廓近似办法
{
drawContours(result,coutours,i,Scalar(255,0,0),1,8);
//第一个参数,Mat型输入图像
//第二个参数,所有输入轮廓的点向量
//第三个参数,轮廓的int型指示变量,用于指示画哪一个轮廓
//第四个参数,颜色
//第五个参数,线条粗度,FILLED为填充,默认值1,当值为-1或者FILLED时,就填充内部;
//第六个参数,线条类型,默认为8
}
imshow("b",result);
waitKey(0);
}
程序二:利用滑动条来控制的轮廓检测
int main()
{
src=imread("kele.jpg",0);
//threshold(src,dst,160,255,THRESH_BINARY);
namedWindow("结果");
createTrackbar("阈值","结果",&thres,125,onThresbar);
onThresbar(thres,0);
waitKey(0);
}
void static onThresbar(int,void*)
{
blur(src,src,Size(3,3));
Canny(src,dst,2*thres,thres,3);
//waitKey(0);
vector<vector<Point>> coutours;
vector<Vec4i> hierarchy;
result=Mat::zeros(src.size(),CV_8UC3);
findContours(dst,coutours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE);
//第一个参数,输入的二值图像
//第二个参数轮廓存储的点向量
//第三个参数,输出向量,hierarchyp[i][0~4]分别代表第i个轮廓的后一个轮廓0,前一个轮廓1,父轮廓2,内嵌轮廓3;
//第四个参数,轮廓检索模式
//第五个参数,轮廓近似办法
for(int i=0;i>=0;i=hierarchy[i][0])
{
drawContours(result,coutours,i,Scalar(255,0,0),1,8);
//第一个参数,Mat型输入图像
//第二个参数,所有输入轮廓的点向量
//第三个参数,轮廓的int型指示变量,用于指示画哪一个轮廓
//第四个参数,颜色
//第五个参数,线条粗度,FILLED为填充,默认值1,当值为-1或者FILLED时,就填充内部;
//第六个参数,线条类型,默认为8
}
imshow("结果",result);
}