opencv学习之路(16)、膨胀腐蚀应用之走迷宫
一、分析
贴出应用图片以供直观了解
红色部分,因图而异(某些参数,根据图片的不同需要进行相应的修改)
二、代码
1 #include "opencv2/opencv.hpp" 2 #include<iostream> 3 using namespace cv; 4 using namespace std; 5 6 void main(){ 7 Mat img=imread("E://9.jpg"); 8 int thres_min=220; //二值化最小阈值 9 if(!img.empty()){ 10 //二值化 11 threshold(img, img, thres_min, 255, THRESH_BINARY); 12 imshow("img_thres",img); 13 //img备份 14 Mat copy=img.clone();//拷贝原图,且不会随着原图改变 15 cvtColor(copy,copy,CV_BGR2GRAY);//彩色图转灰度图 16 threshold(copy, copy, thres_min, 255, THRESH_BINARY_INV);//反转:白色变黑色,黑色变白色 17 imshow("copy", copy); 18 //查找copy的轮廓 19 vector<vector<Point>>contours; 20 findContours(copy, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); 21 //将轮廓画在全黑图像上 22 Mat draw; 23 draw = Mat::zeros(img.size(), CV_32FC1);//定义一个img大小的全黑图像 24 drawContours(draw, contours, 0, Scalar(255), -2); 25 imshow("img2", draw); 26 //进行膨胀腐蚀操作 27 Mat dilated, eroded; 28 Mat kernel=getStructuringElement(MORPH_RECT,Size(19,19));//定义结构元素 29 dilate(draw, dilated, kernel, Point(-1,-1), 2);//膨胀两次 30 imshow("dilate", dilated); 31 erode(dilated, eroded, kernel, Point(-1,-1), 2); 32 imshow("erode", eroded); 33 //膨胀腐蚀相减 34 Mat diff; 35 absdiff(dilated, eroded, diff); 36 diff.convertTo(diff, CV_8UC1);//转换为单通道图(即灰度图) 37 imshow("diff", diff); 38 //在差异图diff中查找轮廓,然后在原图中绘制轮廓 39 vector<vector<Point>>contours2; 40 findContours(diff, contours2, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); 41 drawContours(img, contours2, 0, Scalar(0,255,0),-1);//-1表示绘制轮廓内部,正数表示轮廓线条粗细 42 imshow("result", img); 43 } 44 waitKey(0); 45 destroyAllWindows(); 46 }
轮廓的相关知识,后面会学到。
三、效果图
二值图如下
原图备份后反二值化阈值图copy,如下
copy的轮廓画在全黑图像上,如下
膨胀腐蚀如下
膨胀腐蚀相减(diff)如下
diff轮廓绘制在原图上,如下
其他效果图
绘制轮廓时,若继续选择-1(即绘制轮廓内部),会出现异常情况
将-1更改为轮廓线条粗细程度,则可以正确走出迷宫