摘要:第二种方法是本人根据提高图像对比度思路实现的,具体步骤如下对图像进行高斯模糊去噪使用局部直方图均衡化方法来提高图像对比度使用二值化阈值方法来粗略分割脏污区域对二值图像使用腐蚀的形态学操作过滤掉部分非脏污区域调用方法查找脏污区域轮廓。
今天看了一篇技术文档感觉挺有意思,是关于在低对比度图像中检测脏污区域(这里的脏污指的是比其他区域暗的部分,人眼都不一定能看出来)。
先上图:
第一张图如果不是标注结果,我都没有发现脏污区域在哪里,第二张图还清晰一些,基本可以看出来图像靠近左边缘的位置有偏暗的区域,这就是我们所说的脏污区域了,也是我们要检测的区域。
标注结果图(引用https://jishuin.proginn.com/p/763bfbd62291):
这里介绍两种实现方法,
第一种是用C++实现参考博文的方法,即利用梯度方法来检测,具体步骤如下:
第二种方法是本人根据提高图像对比度思路实现的,具体步骤如下:
8. 对图像进行高斯模糊去噪;
9. 使用局部直方图均衡化方法来提高图像对比度;
10. 使用OTSU二值化阈值方法来粗略分割脏污区域;
11. 对二值图像使用腐蚀的形态学操作过滤掉部分非脏污区域;
12. 调用findContours方法查找脏污区域轮廓。
#include #include #include #include #include #include int main(){ using namespace cv; std::string strImgFile = "C://Temp//common//Workspace//Opencv//images//led1.jpg"; Mat mSrc = imread(strImgFile); CV_Assert(mSrc.empty() == false); Mat mSrc2 = mSrc.clone(); CV_Assert(mSrc2.empty() == false); Mat mGray; cvtColor(mSrc, mGray, COLOR_BGR2GRAY); GaussianBlur(mGray, mGray, Size(5, 5), 1.0); Mat mGray2 = mGray.clone(); CV_Assert(mGray.empty() == false); imshow("gray", mGray.clone()); //方法1:利用梯度变化检测缺陷 Mat mSobelX, mSobelY; Sobel(mGray, mSobelX, CV_16S, 1, 0, 7); Sobel(mGray, mSobelY, CV_16S, 0, 1, 7); convertScaleAbs(mSobelX, mSobelX); convertScaleAbs(mSobelY, mSobelY); Mat mEdge; addWeighted(mSobelX, 1, mSobelY, 1, 0, mEdge); imshow("edge", mEdge); Mat mThresh; threshold(mEdge, mThresh, 0, 255, THRESH_BINARY | THRESH_OTSU); imshow("thresh", mThresh); Mat kernel1 = getStructuringElement(MORPH_RECT, Size(11, 11)); CV_Assert(kernel1.empty() == false); Mat mMorph; morphologyEx(mThresh, mMorph, MORPH_ERODE, kernel1); imshow("erode", mMorph); Mat kernel2 = getStructuringElement(MORPH_RECT, Size(5, 5)); morphologyEx(mMorph, mMorph, MORPH_DILATE, kernel2); imshow("dilate", mMorph); std::vector<std::vector<Point>> contours; findContours(mMorph, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); for (int i = 0; i < contours.size(); i++) { float area = contourArea(contours[i]); if (area > 200) { drawContours(mSrc, contours, i, Scalar(0, 0, 255)); } } imshow("result1", mSrc.clone()); //方法2: 利用局部直方图均衡化方法检测缺陷 Ptr<CLAHE> ptrCLAHE = createCLAHE(20, Size(30, 30)); ptrCLAHE->apply(mGray2, mGray2); imshow("equalizeHist", mGray2); Mat mThresh2; threshold(mGray2, mThresh2, 0, 255, THRESH_BINARY_INV | THRESH_OTSU); CV_Assert(mThresh2.empty() == false); imshow("thresh", mThresh2); Mat kernel2_1 = getStructuringElement(MORPH_RECT, Size(9, 9)); Mat mMorph2; morphologyEx(mThresh2, mMorph2, MORPH_ERODE, kernel2_1); CV_Assert(mMorph2.empty() == false); imshow("morph2", mMorph2); std::vector<std::vector<Point>> contours2; findContours(mMorph2, contours2, RETR_EXTERNAL, CHAIN_APPROX_NONE); for (int i = 0; i < contours2.size(); i++) { float area = contourArea(contours2[i]); if (area > 200) { drawContours(mSrc2, contours2, i, Scalar(0, 0, 255)); } } imshow("result2", mSrc2); waitKey(0); destroyAllWindows(); system("pause"); return 0;}
梯度方法检测结果:
局部直方图均衡化方法检测结果:
相对于梯度方法,局部直方图均衡化方法需要特别注意局部窗口大小参数以及阈限值参数的选择,本人也是尝试了多次才达到比较好的效果。再一次体会到传统图像处理的痛处,没有通用的参数适用于所有的应用实例,不同的场景要配置不同的参数才能达到想要的结果。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/121107.html
❤️欢迎订阅《从实战学python》专栏,用python实现爬虫、办公自动化、数据可视化、人工智能等各个方向的实战案例,有趣又有用!❤️ 更多精品专栏简介点这里 治愈生活的良方 就是保持对生活的热爱 前言 哈喽,大家好,我是一条。 每次和女朋友出去玩,拍照是必须的,天气好还行,天气要是不好,加上我这破手机,那拍的简直惨不忍睹,自己都不过去。 但是没什么能难倒程序员的,为了不挨骂,连夜写出去雾...
摘要:十开放模式识别项目开放模式识别项目,致力于开发出一套包含图像处理计算机视觉自然语言处理模式识别机器学习和相关领域算法的函数库。 一、开源生物特征识别库 OpenBROpenBR 是一个用来从照片中识别人脸的工具。还支持推算性别与年龄。使用方法:$ br -algorithm FaceRecognition -compare me.jpg you.jpg二、计算机视觉库 OpenCVOpenC...
摘要:然而,自然场景文本检测是不同的而且更具挑战性。深度学习文本检测器外链图片转存失败源站可能有防盗链机制建议将图片保存下来直接上传随着和的发布,我们现在可以使用名为的基于深度学习的文本检测器,该检测器基于等人年的论文。 ...
摘要:库使用了一种更接近魔杖和激光扫描仪使用的方法线性条形码设计为通过一个简单的光传感器在符号的明暗区域进行解码。利用这一点,实现对图像进行线性扫描,将每个像素视为单个光传感器的样本。 2021SC@SDUSC 目录 一、ZBar项目简介 1. ZBar是什么 2. ZBar的工作原理 3. Z...
摘要:如果将二者的处理的一些数据结合起来使用,则就是基于直方图统计进行图像增强。图中是通过直方图统计进行图像增强后的结果,可以看到另一个钨丝的比较明显的结构。 一、引...
阅读 2601·2021-09-26 09:55
阅读 2606·2021-09-10 10:51
阅读 2034·2021-09-02 15:21
阅读 3085·2019-08-30 15:44
阅读 703·2019-08-29 18:34
阅读 1551·2019-08-29 13:15
阅读 2344·2019-08-27 14:27
阅读 3185·2019-08-26 11:37