摘要
纸盒表面可能存在脏污烟渣等,如果超过一定面积,需检测为不良品。
一、待检测图像
检测如红框所示的异常点,异常原因传送带脏污,有烟渣覆盖在烟盒表面。
二、斑点检测原理
如下所示的成像, 上部是二次求导, 下部是图像的灰度值。
1.LOG算子
log算子即高斯拉普拉斯, 先进行Laplace再与图像进行平滑处理。
2.DOG算子
dog算子即高斯查分
。
3. 曲线响应
Log曲线其实是两条边界上产生的LoG函数的叠加,当两条边界足够小时,在该尺度脉冲下就被作为了blob,这时候LoG曲线的极值就对应着blob的中心。着尺度的不断增大,LoG曲线由双波谷逐渐融合成单波谷,但是响应的幅值越来越弱,因为随着尺度的增加, log算子的最大幅度逐渐的减少,稳定的信号,相应的幅度与方差成正比,可以消除尺度的影响。
使用Log算子进行Blob检测时,首先在不同尺寸上对图像进行Log,然后检测在尺度空间和图像空间都是极值的点,就是blob区域的中心点。
4. Dog进行Blob检测流程
A: 首先使用不同尺度的高斯算子对图像进行平滑
B: 其次计算相邻尺度下平滑图像的差分图像(DoG空间)
C: 最后在DoG空间寻找极值点
// 参考 https://www.cnblogs.com/YiXiaoZhou/p/5891645.html
Mat create_LOG(int size, double sigma)
{
Mat H(size, size, CV_64F);
int cx = (size-1)/2;
int cy = (size-1)/2;
double sum = 0;
for(int i = 0; i < H.rows; i++)
{
for(int j = 0; j < H.cols; j++)
{
int nx = i - cx;
int ny = j - cy;
double s = -1/(3.1415926 * sigma*sigma*sigma*sigma);
s = s* (1 - (nx*nx + ny*ny)/(2*sigma*sigma));
s = s*exp(-(nx*nx+ny*ny)/(2*sigma*sigma));
sum += s;
H.at<double>(i,j) = s;
}
}
double mean = sum/(size*size);
for(int i = 0; i < H.rows; i++)
{
for(int j = 0; j < H.cols; j++)
{
H.at<double>(i,j) -= mean;
}
}
return H;
}
5. Dog结果图
如下所示, 进行不同参数的调试, 无法有效的检测。
三、实际检测方法
1. 图像的锐化
构建不同方向的滤波, 强化灰度发生变化的位置。
//1. 单通道的grayImg
cv::Mat grayImg;
getGrayImg(srcImg, grayImg);
//2. 在顺45方向的filter2d
cv::Mat filterTlImg;
cv::filter2D(grayImg, filterTlImg, grayImg.depth(), KernelTl);
cv::convertScaleAbs(filterTlImg, filterTlImg);
//3. 在逆45方向的filter2d
cv::Mat filterTrImg;
cv::filter2D(grayImg, filterTrImg, grayImg.depth(), KernelTr);
cv::convertScaleAbs(filterTrImg, filterTrImg);
//4. 在顺45方向的filter2d
cv::Mat filterBlImg;
cv::filter2D(grayImg, filterBlImg, grayImg.depth(), KernelBl);
cv::convertScaleAbs(filterBlImg, filterBlImg);
//5. 在逆45方向的filter2d
cv::Mat filterBrImg;
cv::filter2D(grayImg, filterBrImg, grayImg.depth(), KernelBr);
cv::convertScaleAbs(filterBrImg, filterBrImg);
//6. 各个方向锐化的相加
cv::Mat filterImgTop, filterImgBottom;
cv::addWeighted(filterTlImg, 1.0, filterTrImg, 1.0, 0, filterImgTop);
cv::addWeighted(filterBlImg, 1.0, filterBrImg, 1.0, 0, filterImgBottom);
cv::addWeighted(filterImgTop, 1.0, filterImgBottom, 1.0, 0, resFilterImg);
2. 锐化成像结果图
3. 轮廓特征检测
/*roi的 highLight 的参数*/
message HightLightNPArea {
optional bool save_high_flag = 1;
required string check_name = 2;
required RoiBinMorph roi_bin_morph = 3;
required int32 black_length = 4;
required int32 black_area = 5;
}
总结
构建不同方向的滤波, 锐化灰度变化区域。如果有底纹, 需要进行底纹背景的弱化