opencv contours 遇到边界
来源:互联网 发布:智尚网络 培训 编辑:程序博客网 时间:2024/05/21 01:54
问题:目标物和图像边界相连,怎么填充内部孔洞?
上一篇 opencv contours 的问题 提到 如果先通过 findContours() 找到轮廓,再通过 drawContours() 画出该轮廓,两者的形状不会发生改变。
就像这样:
Mat src = imread("test2.bmp", 1);Mat gray;cvtColor(src, gray, CV_BGR2GRAY);Mat thre = gray > 1;imshow("thre", thre);int area1 = countNonZero(thre);cout<<"area1="<<area1<<endl;vector< vector<Point> > contours;vector< Vec4i> hierarchy;findContours(thre, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);Mat mask1 = Mat::zeros(src.size(), CV_8UC1);for(int i=0; i<contours.size(); ++i) {drawContours(mask1, contours, i, 255, CV_FILLED, 8, hierarchy);}int area2 = countNonZero(mask1);cout<<"area2="<<area2<<endl;imshow("mask1", mask1); imwrite("mask1.bmp", mask1);原图和结果图:
处理前后计算面积:
两者是一样的。
但是今天发现一个问题,当目标物和边界相连的时候,以上规律就不对了。结果变成这样:
计算结果:
处理后的图片左边界向右移了一个像素,计算出的面积小了 1550-1500=50. 也就是左边界的边长:76-27+1=50(通过四个顶点计算出)。
把method 由CV_CHAIN_APPROX_SIMPLE 改成 CV_CHAIN_APPROX_NONE 结果是一样的。
从contours里面每个像素点的坐标看,是从左上角(x=1,y=27)开始,往下沿着左边界到左下角的点(x=1,y=76),接着下边界,逆时针绕一圈,最后是点(x=2,y=27)。看来是忽略掉边界上的点了。
恰好我需要把孔洞填充,结果变成这样:
左边界上的目标物如图:
经过findContours() 函数提取过后,这个被保存为一个轮廓,一个完整的外轮廓,且没有内轮廓。
而我想要填充黑色部分,怎么办呢?
我曲折的进行了以下处理:
Mat src = imread("mask4.bmp", 1);Mat gray;cvtColor(src, gray, CV_BGR2GRAY);Mat mask4 = gray > 1;imshow("mask4", mask4);//--提取轮廓填充,得到磨粒区域mask-------vector< vector<Point> > contours1;vector< Vec4i> hierarchy1;Mat mask5 = Mat::zeros(mask4.size(), mask4.type());findContours(mask4, contours1, hierarchy1, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);for(int i=0; i<contours1.size(); ++i) {drawContours(mask5, contours1, i, 255, CV_FILLED, 8, hierarchy1);}imshow("mask5", mask5); imwrite("mask5.bmp", mask5);//----以上处理后,边界处的轮廓无法填充-------//----反色,提取靠近边界的目标物-------Mat mask5_inv;bitwise_not(mask5, mask5_inv); imwrite("mask5_inv.bmp", mask5_inv);vector< vector<Point> > contours2;findContours(mask5_inv, contours2, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);Mat mask5_border = Mat::zeros(mask4.size(), CV_8UC1);for(int i=0; i<contours2.size(); ++i){int area = contourArea(contours2[i]);if(area<2000)drawContours(mask5_border, contours2, i, 255, CV_FILLED, 8);}imshow("mask5_border", mask5_border);//----把靠近边界的磨粒区域合并---Mat mask6;addWeighted(mask5, 1.0, mask5_border, 1.0, 0.0, mask6);imshow("mask6", mask6); imwrite("mask6.bmp", mask6);把 mask5 反色后提取所有外轮廓,通过面积大小排除大片背景区域,取得靠近边界线的目标物区域mask5_border,再叠加到mask5上面。
中间图及结果图:
问题暂时解决。
0 0
- opencv contours 遇到边界
- opencv contours的问题
- Opencv moment contours PointTest
- opencv 边缘检测 Contours 算法
- OpenCV边界处理类型
- [OpenCV]拓展图像边界
- [OpenCV]拓展图像边界
- [OpenCV]拓展图像边界
- [OpenCV]拓展图像边界
- [OpenCV]拓展图像边界
- opencv approxPolyDP 简化边界
- [OpenCV]拓展图像边界
- 图像边界填充OpenCV
- OpenCV学习笔记-卷积边界
- opencv图像边界的填充
- Opencv 给图像添加边界
- opencv之边界扩展copyMakeBorder
- opencv 的几种边界
- POJ 1995 Raising Modulo Numbers(快速幂)
- 编译PC版vlc
- 用Messenger实现Activity与Service的信息交互
- MySQL详解--锁
- 西蒙iphone-OpenGL ES 教程-07 : 对物体进行独立的转换
- opencv contours 遇到边界
- 在Windows环境下学习Linux命令行的几种方法
- StringUtil
- JavaScript应该被放在什么位置
- 无法解析的外部符号 _main解决办法
- [libevent]event_add()
- 配置gulpfile文件,实现文件更改后浏览器即时刷新
- <JAVA与模式>之动态代理
- rapidxml 写数字节点的问题