文章目录
前言
今天看了篇微信公众号,是使用python opencv 检测出低对比度图像中所有的圆,感觉挺有意思的,这里用C++实现出来,对原始的参数做了改动(发现原始参数检测出的圆有漏检的情况,主要是由于形态学开闭操作结果和预期结果不一致导致的)。
1. 低对比度图像中圆的检测步骤
- 读取彩色图像;
- 转换灰度图像;
- 模糊图像(ksize=50);
- 计算灰度图像与模糊图像的差值图像;
- 对差值图像进行二值化操作(阈值为15);
- 对二值化图像进行闭操作,连接不连续区域;(核大小为11x11)
- 对闭操作后的图像进行形态学开运算,分割出不同圆;(核大小为9x9)
- 查找轮廓;
- 过滤轮廓并绘制圆,主要针对图像上的水印;
2. C++ OpenCV实现
#include <iostream>
#include <opencv2\imgcodecs.hpp>
#include <opencv2\imgproc.hpp>
#include <opencv2\core.hpp>
#include <opencv2\highgui.hpp>
#include <vector>
int main()
{
using namespace std;
using namespace cv;
string strImgFile = "C:\\Temp\\common\\Workspace\\Opencv\\images\\low_contrast_circle.jpg";
Mat src = imread(strImgFile);
CV_Assert(src.empty() == false);
imshow("Src", src);
Mat grayImg;
cvtColor(src, grayImg, COLOR_BGR2GRAY);
CV_Assert(grayImg.empty() == false);
Mat blurImg;
blur(grayImg, blurImg, Size(50, 50));
CV_Assert(blurImg.empty() == false);
imshow("Mean Blur", blurImg);
waitKey(0);
Mat diffImg;
absdiff(grayImg, blurImg, diffImg);
CV_Assert(diffImg.empty() == false);
imshow("Diff", diffImg);
waitKey(0);
Mat binaryImg;
threshold(diffImg, binaryImg, 15, 255, THRESH_BINARY);
CV_Assert(binaryImg.empty() == false);
imshow("Threshold", binaryImg);
waitKey(0);
Mat closeKernel = getStructuringElement(MORPH_ELLIPSE, Size(11, 11));
Mat closeImg;
morphologyEx(binaryImg, closeImg, MORPH_CLOSE, closeKernel);
CV_Assert(closeImg.empty() == false);
imshow("Close", closeImg);
waitKey(0);
Mat openKernel = getStructuringElement(MORPH_ELLIPSE, Size(9, 9));
Mat openImg;
morphologyEx(closeImg, openImg, MORPH_OPEN, openKernel);
CV_Assert(openImg.empty() == false);
imshow("Open", openImg);
waitKey(0);
vector<vector<Point>> contours;
Mat src_copy = src.clone();
findContours(openImg, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
for (int i = 0; i < contours.size(); i++)
{
Point2f center;
float radius = 0;
minEnclosingCircle(contours[i], center, radius);
if (radius < 30)
circle(src_copy, Point((int)center.x, (int)center.y), (int)radius, Scalar(0, 0, 255));
}
imshow("Circles", src_copy);
waitKey(0);
system("pause");
return 0;
}
3. 结果展示:
原图:
检测结果:
总结
传统图像处理技术就是要针对具体问题具体分析,然后调整参数,同一张图像由于某些改变(水印,图像大小)都有可能导致之前的参数失效。所以一般检测时都会选择一些尺度、旋转、光照等不变的特征进行检测。
参考
https://blog.csdn.net/stq054188/article/details/120322770