用opencv做图像识别。检测金属表面的缺陷检测算法 opencv。

没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!利用OpenCV检测图像中的长方形画布或纸张并提取图像内容_Linux编程_Linux公社-Linux系统门户网站
你好,游客
利用OpenCV检测图像中的长方形画布或纸张并提取图像内容
来源:Linux社区&
作者:frombeijingwithlove
问题如下:
也就是在一张照片里,已知有个长方形的物体,但是经过了透视投影,已经不再是规则的长方形,那么如何提取这个图形里的内容呢?这是个很常见的场景,比如在博物馆里看到一幅很喜欢的画,用手机找了下来,可是回家一看歪歪斜斜,脑补原画内容又觉得不对,那么就需要算法辅助来从原图里提取原来的内容了。不妨把应用的场景分为以下:
纸张四角的坐标(图中红点)已知的情况
也就是上面的左图中4个红点是可以准确获取,比如手动标注,那么就简单了:用OpenCV的Perspective Transform就可以。具体步骤如下:
1) 将标注好的四个点坐标存入一个叫corner的变量里,比如上面的例子中,原图的分辨率是300x400,定义x和y的方向如下:
那么纸张的四角对应的坐标分别是:
左上:157.6, 71.5
右上:295.6, 118.4
右下:172.4, 311.3
左下:2.4, 202.4
把这四个坐标按如上顺序放到一个叫corner的变量里。如果我们打算把这幅图案恢复到一个300x400的图像里,那么按照对应的顺序把下面四个坐标放到一个叫canvas的变量里:
左上:0, 0
右上:300, 0
右下:300, 400
左下:0, 400
假设原图已经用OpenCV读取到一个叫image的变量里,那么提取纸张图案的代码如下:
1 M = cv2.getPerspectiveTransform(corners, canvas)
2 result = cv2.warpPerspective(image, M, (0, 0))
把左图剪裁出来,去掉红点后试了试,结果如下:
当然,其实这一步用Photoshop就可以了。。
纸张四角的坐标未知或难以准确标注的情况
这种场景可能是小屏幕应用,或是原始图像就很小,比如我这里用的这个300x400例子,点坐标很难精确标注。这种情况下一个思路是,用边缘检测提取纸张四边,然后求出四角坐标,再做Perspective Transform。
1) 图像预处理
一般而言即使做普通的边缘检测也需要提前对图像进行降噪避免误测,比如最常见的办法是先对图像进行高斯滤波,然而这样也会导致图像变得模糊,当待检测图形边缘不明显,或是图像本身分辨率不高的情况下(比如本文用的例子),会在降噪的同时把待检测的边缘强度也给牺牲了。具体到本文的例子,纸张是白色,背景是浅黄带纹路,如果进行高斯滤波是显然不行的,这时候一个替代方案是可以考虑使用Mean Shift,Mean Shift的优点就在于如果是像背景桌面的浅色纹理,图像分割的过程中相当于将这些小的浮动过滤掉,并且保留相对明显的纸张边缘,结果如下:
Meanshift的代码:
1 image = cv2.pyrMeanShiftFiltering(image, 25, 10)
因为主要目的是预处理降噪,windows size和color distance都不用太大,避免浪费计算时间还有过度降噪。降噪后可以看到桌面上的纹理都被抹去了,纸张边缘附近干净了很多。然而这还远远不够,图案本身,和图像里的其他物体都有很多明显的边缘,而且都是直线边缘。
2) 纸张边缘检测
虽然降噪了,可是图像里还是有很多边缘明显的元素。怎么尽量只保留纸张的边缘呢,这时候可以考虑用分割算法,把图像分为纸张部分和其他部分,这样分割的mask边缘就和纸张边缘应该是差不多重合的。在这里可以考虑用GrabCut,这样对于简单的情况,比如纸张或画布和背景对比强烈的,直接把图像边缘的像素作为bounding box就可以实现自动分割。当自动分割不精确的情况下再引入手动辅助分割,具体到我这里用的例子,背景和画面接近,所以需要手动辅助:
结果如下:
可以看到,分割后的结果虽然能基本区分纸张形状了,可是边缘并不准确,另外键盘和部分桌面没能区分开来。这时可以继续用GrabCut+手动标注得到只有纸张的分割。或者为了用户友好的话,尽量少引入手动辅助,那么可以考虑先继续到下一步检测边缘,再做后期处理。假设我们考虑后者,那么我们得到的是如下的mask:
这个mask并不精确,所以不能直接用于边缘检测,但是它大致标出了图片里最明显的边缘位置所在,所以可以考虑下面的思路:保留降噪后位于mask边缘附近的信息用于真正的边缘检测,而把其他部分都模糊处理,也就是说基于上面得到的mask做出下面的mask用于模糊处理:
基于这个mask得到的用于边缘检测的图像如下:
用canny算子检测出边缘如下:
3) 直线检测
对检测到的边缘使用Hough变换检测直线,我例子里用的是cv2.HoughLinesP,分辨率1像素和1&,可以根据图像大小设置检测的阈值和minLineLength去除大部分误检测。特别提一下的是如果使用OpenCV的Python binding,OpenCV 2和OpenCV 3的结果结构是不一样的,如果进行代码移植需要相应的修改。检测到的结果如下:
可以看到,有些线几乎重合在一起了,这是难以避免的,上图中一共检测到9条线,其中两对(下、右边缘)重合。可以通过距离判断和直线相对角度来判断并把重合线段合为一条:
剩下的都是没有重合的线了。
4) 判断纸张边缘
那么如何选取纸张边缘的四条线呢(即使图像分割步骤非常好得分开了纸张和其他部分,这在有些情况下还是难以避免的,比如图案里有和边缘平行的线条),可以沿着提取线段的两边采样像素的灰度:
在线段的两个端点之间平均采样左右两边像素的值,因为一般来说如果是纸张或者画布,边缘和背景的颜色在四边上应该都是类似的。然而这样做的话引入另外一个问题是需要区分线段的&左&和&右&,对于线段本身而言就是要区分前后。所以需要对画面里所有的线段端点进行排序,而这个排序的基准就是相对画布。
具体到本文的例子就是把图像中心定义为所有线段的&左&边,如上图。而决定线段端点&前&和&后&可以用如下办法:
先假设线段的前后端点,将两个端点坐标分别减去中心点(红点)的坐标,然后将得到的两个向量a和b求叉积,如果叉积大于0则说明假设正确,如果&0则交换假设的前后端点。线段端点的顺序确定后就可以进行采样了,简单起见可以分别采样左右两侧的像素灰度值,如果希望更准确可以采样RGB通道的值进行综合比较,下面是7条线段对应的两侧像素灰度的中值分布:
可以看到其中有4个点距离非常近(红色),说明他们的像素灰度分布也很接近,把这4条选出来,结果如下:
正是要的结果。
5) 计算四角的坐标
接下来计算四条线的交点,方法点。因为有4条线,会得到6个结果,因为在这种应用场景中,方形的物体在透视变换下不会出现凹角,所以直接舍弃离纸张中心最远的两个交点就得到了四个角的坐标,结果如下:
这样就回到了一开始四角坐标已经得到的情况,直接进行透视变换就行了。
Camera Calibration?
写了这么多,其实有一条至关重要的假设,甚至可以说是最关键的步骤之一我一直没提,那就是Camera Calibration,如果有相机的情况下,meta data都知道,那么需要先坐Camera Calibration才能知道纸张或者画布的原始尺寸。我这里试的例子当然是没有的,也可以有,相应的算法OpenCV里也有现成的,不过即便如此还是非常麻烦,所以我的所有流程都是默认原始尺寸已经获得了。再说了,就算没有,变换回方形之后使用者凭感觉进行简单轴缩放都比Camera Calibration方便得多。。
--------------------------------------分割线 --------------------------------------
Linux下安装OpenCV2.4.1所需包
Ubuntu 12.04 安装 OpenCV2.4.2
下OpenCV无法读取视频文件
Ubuntu 12.04下安装OpenCV 2.4.5总结
Ubuntu 10.04中安装OpenCv2.1九步曲
基于QT和OpenCV的人脸识别系统
[翻译]Ubuntu 14.04, 13.10 下安装 OpenCV 2.4.9&
--------------------------------------分割线 --------------------------------------
更多详情见请继续阅读下一页的精彩内容:
相关资讯 & & &
& (03月27日)
& (01月12日)
& (11月04日)
& (03月12日)
& (12/31/:28)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款
匿名 发表于 能给一个联系方式吗?基于OpenCV的钢轨裂纹检测_唐曼玲_百度文库
赠送免券下载特权
10W篇文档免费专享
部分付费文档8折起
每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
基于OpenCV的钢轨裂纹检测_唐曼玲
&&挺好的资料哦
阅读已结束,下载本文需要
想免费下载本文?
定制HR最喜欢的简历
你可能喜欢基于OpenCv的金属表面划痕检测_机器视觉专业论坛-慢钱头条
该文章内容可能包含未经证实信息,如您已证实,请点击举报,了解更多内容请查看
基于OpenCv的金属表面划痕检测
在实际应用中,得到的图像的阈值不太理想时通过固定阈值分割很难得到所要提取的特征,因此Halcon中&
含有动态阈值分割法,即首先对图像进行均值滤波,然后与现有图像最差后进行阈值分割。该方法适合比较&
小的特征提取,例如金属表面的划痕、丝网的漏洞等。
本例划痕长度和数量,主要步骤如下:&
1.对读入的图像进行动态阈值分割,分割出Blob区域。&
2.利用面积对Blob区域进行选择。&
3.显示检测结果。
对下图的长短划痕进行检测,结果如图所示&
Opencv检测代码
#include &iostream& & &&
#include &opencv2/opencv.hpp& &
#include &opencv2/highgui/highgui.hpp&
#include &opencv2/core/core.hpp&
#include &opencv2/imgproc/imgproc.hpp&
#include "opencv2/features2d.hpp"
int main(int argc, char** argv)
cv::Mat image, imagemean, diff, M
image = imread("../data/surface_scratch.png");
blur(image, imagemean, Size(13, 13));
subtract(imagemean, image, diff);
threshold(diff, Mask, 5, 255, THRESH_BINARY_INV);//同动态阈值分割dyn_threshold
imshow("imagemean", imagemean);
imshow("diff", diff);
imshow("Mask", Mask);
cvtColor(Mask, imagegray, CV_RGB2GRAY);
vector&vector&Point& &
vector&Vec4i&
findContours(imagegray, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
Mat drawing = Mat::zeros(Mask.size(), CV_8U);
int j = 0;
for (int i = 0; i & contours.size(); i++)
Moments moms = moments(Mat(contours[i]));
double area = moms.m00; & &//零阶矩即为二值图像的面积 &double area = moms.m00; &
//如果面积超出了设定的范围,则不再考虑该斑点 &
if (area & 20 && area & 1000)
drawContours(drawing, contours, i, Scalar(255), FILLED, 8, hierarchy, 0, Point());
j = j + 1;
cv::Mat element15(3, 3, CV_8U, cv::Scalar(1));
cv::morphologyEx(drawing, close, cv::MORPH_CLOSE, element15);
imshow("drawing", drawing);
vector&vector&Point& & contours1;
vector&Vec4i& hierarchy1;
findContours(close, contours1, hierarchy1, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
imshow("close", close);
int m = 0;
for (int i = 0; i & contours1.size(); i++)
Moments moms = moments(Mat(contours1[i]));
double area = moms.m00; & &//零阶矩即为二值图像的面积 &double area = moms.m00; &
//如果面积超出了设定的范围,则不再考虑该斑点 &
double area1 = contourArea(contours1[i]);
if (area & 50 && area & 100000)
drawContours(image, contours1, i, Scalar(0, 0, 255), FILLED, 8, hierarchy1, 0, Point());
j = j + 1;
else if (area &= 0 && area &= 50)
drawContours(image, contours1, i, Scalar(255, 0, 0), FILLED, 8, hierarchy1, 0, Point());
m = m + 1;
char t[256];
sprintf_s(t, "%01d", j);
string s =
string txt = "Long NG : " +
putText(image, txt, Point(20, 30), CV_FONT_HERSHEY_COMPLEX, 1,
Scalar(0, 0, 255), 2, 8);
sprintf_s(t, "%01d", m);
txt = "Short NG : " +
putText(image, txt, Point(20, 60), CV_FONT_HERSHEY_COMPLEX, 1,
Scalar(255, 0, 0), 2, 8);
imshow("漏洞", image);
waitKey();
&tp://toutiao.manqian.cn/tag_57ff3d22e4b0e03f81f56b13.html'target='_blank'>金属表面镀锡厂家【苏州长青电镀厂sell】/电镀金属的镀层及效果在我们的日常生活中,电镀加工的工艺品,生活用品随处见。很多常见的工艺品上有镀铜的,镀镍的,镀金的,镀钯镍的,还有镀锡铅的。这样在机械制品上的装饰不仅起到了保护和形成功能性的表层,还起到了修...&ing:border-box!word-wrap:break-word!background-color:rgb(255,255,255);">案例介绍网友随手拍摄了金属表面的图片如下图所示,金属表面有白色的划痕和黑色的裂缝,要求同时识别出划痕和裂缝的具体位置。pe="png"src="/img?url=http://mmbiz.qpic.cn/mmbiz_...&随着微电子技术、计算机技术、自动化技术和光电子技术的飞速发展,金属表面缺陷检测方法的研究越来越多,以下是常见的表面检测方法1磁粉法检测原理:在基体材料中实现磁场、根据缺陷处的漏磁场与磁粉的相互作用,当表面和近表面有不连续或缺陷时,则在不连续出或缺陷处磁力线发生局部畸变产生磁极。?优点:1)设备投资少、结果可靠性高、2)测量结果易见?不足:1)操作成本高、不能对缺陷准确分类2)检测速度较低2着色检测...&金属表面防锈问题,可以说是一个世界性的难题。如今我们看到的,接触到的产品很多都是经过表面处理的,大到飞机,小到钥匙。最熟悉不过的就是我们的手机了,在这其中运用到了很多表面处理技术。那么,对于金属的表面如何做防锈处理?是怎么做到的?我们今天就来说说。首先我们要知道涂装是表面制造工艺中的一个重要环节。它具有防锈、防蚀的作用,因此涂装表面处理的质量就是产品全面质量的重要环节之一了。其次表面处理是防锈涂装...&微小的刮痕急救产品:细蜡、粗蜡。轻微刮花的漆面损伤部位是在面漆的表层,可以通过打蜡完全修复。用混合剂处理,擦拭方法为直线擦拭,然后再打上蜡,可以先用粗蜡,再上细蜡,由内往外同样的方向,这样,细微刮痕就几乎都去掉了。当然,还有一个更省钱的方法是用牙膏修复,轻轻涂在浅度划痕处,然后用柔软的棉布逆时针抹,几次下来,不仅减轻划痕,还能避免空气对车漆伤处的侵蚀。未掉底漆的刮伤急救产品:细蜡、补漆笔。面积稍大...&
公众号推荐
巩义市河洛镇鑫悦机械厂专业制造:撕碎机系
腾果控股与杭州日报社联合出品,点评楼市百
把握行业趋势,寻找有长期投资价值的公司是
NABF(North American
每日帮您选到涨停板的财经自媒体。最新消息
乘上仟舟,驶向财富自由的彼岸
湘财证券固定收益业务交流。
徐州百房网,提供新鲜的徐州楼市房产资讯,
关注东方成安公众平台,了解我们的产品和公
违规或不良信息
广告、钓鱼诈骗
内容不完整
手机号(选填)
如有疑问请致电 8

我要回帖

更多关于 opencv 检测圆缺陷 的文章

 

随机推荐