检测具有大量噪声的图像上的划痕
Detecting scratch on image with much noise
我无法检测这些图像上的划痕。其实,人眼是很容易看到的。但是,在应用某些算法时,噪音很大,我无法仅提取划痕。
以下是这些图片:
目前,我尝试了一些滤波器(平滑、平均、中值、高斯滤波器或 Sobel 边缘检测器)来消除噪声和检测划痕,但它们没有太大帮助。
你能提出一些想法吗?
我应该考虑的一些工具或算法?
我尝试了以下程序进行检测。输出看起来一般,但我还是想到分享。
- 对彩色图像进行下采样。
应用不同 window 大小的中值模糊,然后取绝对差:我这样做是为了增强划痕,同时实现照明平坦化。下面显示的是通过这种方式获得的差异图像。
使用基于高斯混合的background/foreground分割来分割差异图像中的划痕。这里的想法是,我们可以从此图像中提取 m x n windows 并进行训练。由于划痕在差异图像中并没有占据很大的面积,我们可以认为学习到的背景应该近似于划痕之外的区域。与对差异图像应用阈值相比,该方法对两个差异图像的效果更好。当我直接输入下采样图像时,这种方法效果不佳。我认为这是由于区域中像素颜色值的不均匀性造成的。所以我使用了照明扁平化差异图像。下面是分割后的图像。这个过程很慢,因为它会检查图像中所有可能的 m x n window。
使用概率霍夫变换检测分割图像中的线条。使用区域中的线密度或对线使用形态学过滤,我认为可以对划痕的位置做出合理的猜测。
这是代码
背景分割代码:
Mat threshold_mog(Mat& im, Size window)
{
BackgroundSubtractorMOG2 bgModel;
Mat fgMask;
Mat output = Mat::ones(im.rows, im.cols, CV_8U);
for (int r = 0; r < im.rows - window.height; r++)
{
for (int c = 0; c < im.cols - window.width; c++)
{
bgModel.operator()(im(Rect(c, r, window.width, window.height)), fgMask);
}
}
for (int r = 0; r < im.rows - window.height; r++)
{
for (int c = 0; c < im.cols - window.width; c++)
{
Mat region = im(Rect(c, r, window.width, window.height));
bgModel.operator()(region, fgMask, 0);
fgMask.copyTo(output(Rect(c, r, window.width, window.height)));
}
}
return output;
}
主要内容:
Mat rgb = imread("scratch_2.png.jpg");
pyrDown(rgb, rgb);
Mat med, med2, dif, bw;
medianBlur(rgb, med, 3);
medianBlur(rgb, med2, 21);
absdiff(med2, med, dif);
bw = threshold_mog(dif, Size(15, 15));
Mat dst = bw.clone();
vector<Vec4i> lines;
HoughLinesP(dst, lines, 1, CV_PI/180, 8, 10, 20);
for( size_t i = 0; i < lines.size(); i++ )
{
Vec4i l = lines[i];
line(rgb, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 1, CV_AA);
}
这是我对缺陷检测的实现,它是一种非常简单但有效的方法,我已经在 MATLAB 中实现了这段代码,但是将它移植到任何语言上都没有任何困难,因为它使用了基本的图像处理操作。
clc
clear all
close all
- 读取两个图像并按 2 倍对它们进行下采样(以便快速计算)。
im1 = imresize(imread('scratch.jpg'),0.5);
- 将它们转换为灰度。
gray = rgb2gray(im);
- 应用大小为 15 X 15 的高斯滤波器。
gSize = 15;
gray = imfilter(gray,fspecial('gaussian',[gSize,gSize],gSize/2),'replicate');
- 使用 Sobel 掩码找出图像的梯度幅度。
[~,~,mg,~] = ImageFeatures.Gradients(gray);
- 阈值为最大值的 30 个百分点的阈值梯度幅度。
`mgBw = mg > 0.3*max(mg(:));
- 通过 3 X 3 的磁盘掩码应用形态学运算关闭二值图像。
mgBw = imclose(mgBw,strel('disk',1));
- 应用粒子分析 (CCL)。
mgBw = bwareaopen(mgBw,500);
- 再次关闭图像以将线条连接在一起。
mgBw = imclose(mgBw,strel('disk',2));
- 填充图像中的孔。
mgBw = imfill(mgBw,'holes');
- 最终注释:
在你的图片上尝试上面的程序希望它能工作
谢谢
高斯蒙版的值在下面给出,我只是按原样复制,您只能使用小数点后 4 位的值,并且在卷积缩放图像值之前还有一件事在 0 和 1 之间:
0.00253790859361804,0.00284879446220838,0.00314141610419987,0.00340305543986557,0.00362152753952273,0.00378611472031542,0.00388843599983945,0.00392315394879368,0.00388843599983945,0.00378611472031542,0.00362152753952273,0.00340305543986557,0.00314141610419987,0.00284879446220838,0.00253790859361804;
0.00284879446220838,0.00319776287779517,0.00352622975612324,0.00381991909245893,0.00406515334132644,0.00424990193722614,0.00436475725361032,0.00440372804277458,0.00436475725361032,0.00424990193722614,0.00406515334132644,0.00381991909245893,0.00352622975612324,0.00319776287779517,0.00284879446220838;
0.00314141610419987,0.00352622975612324,0.00388843599983945,0.00421229243210782,0.00448271658130972,0.00468644212981339,0.00481309512122034,0.00485606890058492,0.00481309512122034,0.00468644212981339,0.00448271658130972,0.00421229243210782,0.00388843599983945,0.00352622975612324,0.00314141610419987;
0.00340305543986557,0.00381991909245893,0.00421229243210782,0.00456312191696750,0.00485606890058492,0.00507676215263394,0.00521396370030743,0.00526051663974220,0.00521396370030743,0.00507676215263394,0.00485606890058492,0.00456312191696750,0.00421229243210782,0.00381991909245893,0.00340305543986557;
0.00362152753952273,0.00406515334132644,0.00448271658130972,0.00485606890058492,0.00516782273108746,0.00540268422664802,0.00554869395001131,0.00559823553262373,0.00554869395001131,0.00540268422664802,0.00516782273108746,0.00485606890058492,0.00448271658130972,0.00406515334132644,0.00362152753952273;
0.00378611472031542,0.00424990193722614,0.00468644212981339,0.00507676215263394,0.00540268422664802,0.00564821944786971,0.00580086485975791,0.00585265795345929,0.00580086485975791,0.00564821944786971,0.00540268422664802,0.00507676215263394,0.00468644212981339,0.00424990193722614,0.00378611472031542;
0.00388843599983945,0.00436475725361032,0.00481309512122034,0.00521396370030743,0.00554869395001131,0.00580086485975791,0.00595763557555571,0.00601082839853353,0.00595763557555571,0.00580086485975791,0.00554869395001131,0.00521396370030743,0.00481309512122034,0.00436475725361032,0.00388843599983945;
0.00392315394879368,0.00440372804277458,0.00485606890058492,0.00526051663974220,0.00559823553262373,0.00585265795345929,0.00601082839853353,0.00606449615428972,0.00601082839853353,0.00585265795345929,0.00559823553262373,0.00526051663974220,0.00485606890058492,0.00440372804277458,0.00392315394879368;
0.00388843599983945,0.00436475725361032,0.00481309512122034,0.00521396370030743,0.00554869395001131,0.00580086485975791,0.00595763557555571,0.00601082839853353,0.00595763557555571,0.00580086485975791,0.00554869395001131,0.00521396370030743,0.00481309512122034,0.00436475725361032,0.00388843599983945;
0.00378611472031542,0.00424990193722614,0.00468644212981339,0.00507676215263394,0.00540268422664802,0.00564821944786971,0.00580086485975791,0.00585265795345929,0.00580086485975791,0.00564821944786971,0.00540268422664802,0.00507676215263394,0.00468644212981339,0.00424990193722614,0.00378611472031542;
0.00362152753952273,0.00406515334132644,0.00448271658130972,0.00485606890058492,0.00516782273108746,0.00540268422664802,0.00554869395001131,0.00559823553262373,0.00554869395001131,0.00540268422664802,0.00516782273108746,0.00485606890058492,0.00448271658130972,0.00406515334132644,0.00362152753952273;
0.00340305543986557,0.00381991909245893,0.00421229243210782,0.00456312191696750,0.00485606890058492,0.00507676215263394,0.00521396370030743,0.00526051663974220,0.00521396370030743,0.00507676215263394,0.00485606890058492,0.00456312191696750,0.00421229243210782,0.00381991909245893,0.00340305543986557;
0.00314141610419987,0.00352622975612324,0.00388843599983945,0.00421229243210782,0.00448271658130972,0.00468644212981339,0.00481309512122034,0.00485606890058492,0.00481309512122034,0.00468644212981339,0.00448271658130972,0.00421229243210782,0.00388843599983945,0.00352622975612324,0.00314141610419987;
0.00284879446220838,0.00319776287779517,0.00352622975612324,0.00381991909245893,0.00406515334132644,0.00424990193722614,0.00436475725361032,0.00440372804277458,0.00436475725361032,0.00424990193722614,0.00406515334132644,0.00381991909245893,0.00352622975612324,0.00319776287779517,0.00284879446220838;
0.00253790859361804,0.00284879446220838,0.00314141610419987,0.00340305543986557,0.00362152753952273,0.00378611472031542,0.00388843599983945,0.00392315394879368,0.00388843599983945,0.00378611472031542,0.00362152753952273,0.00340305543986557,0.00314141610419987,0.00284879446220838,0.00253790859361804;
索贝尔面具:
1, 2, 1;
0, 0, 0;
-1,-2, 1;
和
1, 0,-1;
2, 0,-2;
1, 0,-1;
索贝尔梯度幅值代码(ImageFeatures.Gradient):
function [gx,gy,mag,phi] = Gradients(gray)
gray = double(gray);
horzmask = fspecial('sobel');
% vertmask = horzmask';
gx = imfilter(gray,horzmask,'replicate');
gy = imfilter(gray,horzmask','replicate');
phi = (atan2((gy),(gx)));
mag = mat2gray(sqrt(gx.^2+gy.^2));
end
我无法检测这些图像上的划痕。其实,人眼是很容易看到的。但是,在应用某些算法时,噪音很大,我无法仅提取划痕。
以下是这些图片:
目前,我尝试了一些滤波器(平滑、平均、中值、高斯滤波器或 Sobel 边缘检测器)来消除噪声和检测划痕,但它们没有太大帮助。 你能提出一些想法吗? 我应该考虑的一些工具或算法?
我尝试了以下程序进行检测。输出看起来一般,但我还是想到分享。
- 对彩色图像进行下采样。
应用不同 window 大小的中值模糊,然后取绝对差:我这样做是为了增强划痕,同时实现照明平坦化。下面显示的是通过这种方式获得的差异图像。
使用基于高斯混合的background/foreground分割来分割差异图像中的划痕。这里的想法是,我们可以从此图像中提取 m x n windows 并进行训练。由于划痕在差异图像中并没有占据很大的面积,我们可以认为学习到的背景应该近似于划痕之外的区域。与对差异图像应用阈值相比,该方法对两个差异图像的效果更好。当我直接输入下采样图像时,这种方法效果不佳。我认为这是由于区域中像素颜色值的不均匀性造成的。所以我使用了照明扁平化差异图像。下面是分割后的图像。这个过程很慢,因为它会检查图像中所有可能的 m x n window。
使用概率霍夫变换检测分割图像中的线条。使用区域中的线密度或对线使用形态学过滤,我认为可以对划痕的位置做出合理的猜测。
这是代码
背景分割代码:
Mat threshold_mog(Mat& im, Size window)
{
BackgroundSubtractorMOG2 bgModel;
Mat fgMask;
Mat output = Mat::ones(im.rows, im.cols, CV_8U);
for (int r = 0; r < im.rows - window.height; r++)
{
for (int c = 0; c < im.cols - window.width; c++)
{
bgModel.operator()(im(Rect(c, r, window.width, window.height)), fgMask);
}
}
for (int r = 0; r < im.rows - window.height; r++)
{
for (int c = 0; c < im.cols - window.width; c++)
{
Mat region = im(Rect(c, r, window.width, window.height));
bgModel.operator()(region, fgMask, 0);
fgMask.copyTo(output(Rect(c, r, window.width, window.height)));
}
}
return output;
}
主要内容:
Mat rgb = imread("scratch_2.png.jpg");
pyrDown(rgb, rgb);
Mat med, med2, dif, bw;
medianBlur(rgb, med, 3);
medianBlur(rgb, med2, 21);
absdiff(med2, med, dif);
bw = threshold_mog(dif, Size(15, 15));
Mat dst = bw.clone();
vector<Vec4i> lines;
HoughLinesP(dst, lines, 1, CV_PI/180, 8, 10, 20);
for( size_t i = 0; i < lines.size(); i++ )
{
Vec4i l = lines[i];
line(rgb, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 1, CV_AA);
}
这是我对缺陷检测的实现,它是一种非常简单但有效的方法,我已经在 MATLAB 中实现了这段代码,但是将它移植到任何语言上都没有任何困难,因为它使用了基本的图像处理操作。
clc
clear all
close all
- 读取两个图像并按 2 倍对它们进行下采样(以便快速计算)。
im1 = imresize(imread('scratch.jpg'),0.5);
- 将它们转换为灰度。
gray = rgb2gray(im);
- 应用大小为 15 X 15 的高斯滤波器。
gSize = 15;
gray = imfilter(gray,fspecial('gaussian',[gSize,gSize],gSize/2),'replicate');
- 使用 Sobel 掩码找出图像的梯度幅度。
[~,~,mg,~] = ImageFeatures.Gradients(gray);
- 阈值为最大值的 30 个百分点的阈值梯度幅度。
`mgBw = mg > 0.3*max(mg(:));
- 通过 3 X 3 的磁盘掩码应用形态学运算关闭二值图像。
mgBw = imclose(mgBw,strel('disk',1));
- 应用粒子分析 (CCL)。
mgBw = bwareaopen(mgBw,500);
- 再次关闭图像以将线条连接在一起。
mgBw = imclose(mgBw,strel('disk',2));
- 填充图像中的孔。
mgBw = imfill(mgBw,'holes');
- 最终注释:
在你的图片上尝试上面的程序希望它能工作
谢谢
高斯蒙版的值在下面给出,我只是按原样复制,您只能使用小数点后 4 位的值,并且在卷积缩放图像值之前还有一件事在 0 和 1 之间:
0.00253790859361804,0.00284879446220838,0.00314141610419987,0.00340305543986557,0.00362152753952273,0.00378611472031542,0.00388843599983945,0.00392315394879368,0.00388843599983945,0.00378611472031542,0.00362152753952273,0.00340305543986557,0.00314141610419987,0.00284879446220838,0.00253790859361804;
0.00284879446220838,0.00319776287779517,0.00352622975612324,0.00381991909245893,0.00406515334132644,0.00424990193722614,0.00436475725361032,0.00440372804277458,0.00436475725361032,0.00424990193722614,0.00406515334132644,0.00381991909245893,0.00352622975612324,0.00319776287779517,0.00284879446220838;
0.00314141610419987,0.00352622975612324,0.00388843599983945,0.00421229243210782,0.00448271658130972,0.00468644212981339,0.00481309512122034,0.00485606890058492,0.00481309512122034,0.00468644212981339,0.00448271658130972,0.00421229243210782,0.00388843599983945,0.00352622975612324,0.00314141610419987;
0.00340305543986557,0.00381991909245893,0.00421229243210782,0.00456312191696750,0.00485606890058492,0.00507676215263394,0.00521396370030743,0.00526051663974220,0.00521396370030743,0.00507676215263394,0.00485606890058492,0.00456312191696750,0.00421229243210782,0.00381991909245893,0.00340305543986557;
0.00362152753952273,0.00406515334132644,0.00448271658130972,0.00485606890058492,0.00516782273108746,0.00540268422664802,0.00554869395001131,0.00559823553262373,0.00554869395001131,0.00540268422664802,0.00516782273108746,0.00485606890058492,0.00448271658130972,0.00406515334132644,0.00362152753952273;
0.00378611472031542,0.00424990193722614,0.00468644212981339,0.00507676215263394,0.00540268422664802,0.00564821944786971,0.00580086485975791,0.00585265795345929,0.00580086485975791,0.00564821944786971,0.00540268422664802,0.00507676215263394,0.00468644212981339,0.00424990193722614,0.00378611472031542;
0.00388843599983945,0.00436475725361032,0.00481309512122034,0.00521396370030743,0.00554869395001131,0.00580086485975791,0.00595763557555571,0.00601082839853353,0.00595763557555571,0.00580086485975791,0.00554869395001131,0.00521396370030743,0.00481309512122034,0.00436475725361032,0.00388843599983945;
0.00392315394879368,0.00440372804277458,0.00485606890058492,0.00526051663974220,0.00559823553262373,0.00585265795345929,0.00601082839853353,0.00606449615428972,0.00601082839853353,0.00585265795345929,0.00559823553262373,0.00526051663974220,0.00485606890058492,0.00440372804277458,0.00392315394879368;
0.00388843599983945,0.00436475725361032,0.00481309512122034,0.00521396370030743,0.00554869395001131,0.00580086485975791,0.00595763557555571,0.00601082839853353,0.00595763557555571,0.00580086485975791,0.00554869395001131,0.00521396370030743,0.00481309512122034,0.00436475725361032,0.00388843599983945;
0.00378611472031542,0.00424990193722614,0.00468644212981339,0.00507676215263394,0.00540268422664802,0.00564821944786971,0.00580086485975791,0.00585265795345929,0.00580086485975791,0.00564821944786971,0.00540268422664802,0.00507676215263394,0.00468644212981339,0.00424990193722614,0.00378611472031542;
0.00362152753952273,0.00406515334132644,0.00448271658130972,0.00485606890058492,0.00516782273108746,0.00540268422664802,0.00554869395001131,0.00559823553262373,0.00554869395001131,0.00540268422664802,0.00516782273108746,0.00485606890058492,0.00448271658130972,0.00406515334132644,0.00362152753952273;
0.00340305543986557,0.00381991909245893,0.00421229243210782,0.00456312191696750,0.00485606890058492,0.00507676215263394,0.00521396370030743,0.00526051663974220,0.00521396370030743,0.00507676215263394,0.00485606890058492,0.00456312191696750,0.00421229243210782,0.00381991909245893,0.00340305543986557;
0.00314141610419987,0.00352622975612324,0.00388843599983945,0.00421229243210782,0.00448271658130972,0.00468644212981339,0.00481309512122034,0.00485606890058492,0.00481309512122034,0.00468644212981339,0.00448271658130972,0.00421229243210782,0.00388843599983945,0.00352622975612324,0.00314141610419987;
0.00284879446220838,0.00319776287779517,0.00352622975612324,0.00381991909245893,0.00406515334132644,0.00424990193722614,0.00436475725361032,0.00440372804277458,0.00436475725361032,0.00424990193722614,0.00406515334132644,0.00381991909245893,0.00352622975612324,0.00319776287779517,0.00284879446220838;
0.00253790859361804,0.00284879446220838,0.00314141610419987,0.00340305543986557,0.00362152753952273,0.00378611472031542,0.00388843599983945,0.00392315394879368,0.00388843599983945,0.00378611472031542,0.00362152753952273,0.00340305543986557,0.00314141610419987,0.00284879446220838,0.00253790859361804;
索贝尔面具:
1, 2, 1;
0, 0, 0;
-1,-2, 1;
和
1, 0,-1;
2, 0,-2;
1, 0,-1;
索贝尔梯度幅值代码(ImageFeatures.Gradient):
function [gx,gy,mag,phi] = Gradients(gray)
gray = double(gray);
horzmask = fspecial('sobel');
% vertmask = horzmask';
gx = imfilter(gray,horzmask,'replicate');
gy = imfilter(gray,horzmask','replicate');
phi = (atan2((gy),(gx)));
mag = mat2gray(sqrt(gx.^2+gy.^2));
end