Image processing 如何有效地查找和删除图像强度变化的1像素波段?

Image processing 如何有效地查找和删除图像强度变化的1像素波段?,image-processing,edge-detection,distortion,sobel,Image Processing,Edge Detection,Distortion,Sobel,我们在着色器的法线贴图上有一些视觉瑕疵,因为一些单个像素带与其周围环境形成强烈对比。需要明确的是,边缘不是问题,只有这些单像素带 在这种情况下,使用类似于典型Sobel边缘检测的方法将不起作用,因为在这样的频带上,它将检测0。我可以考虑对内核进行其他修改,例如 -1 -2 -1 2 4 2 -1 -2 -1 但我认为可能有一种“正确”的数学方法来做这样的运算 最后,我想用周围的像素平滑这些线条(所以是选择性模糊)。这些行可以以任何方向出现,所以如果我使用上面的内核,我需要在两个方向上应用

我们在着色器的法线贴图上有一些视觉瑕疵,因为一些单个像素带与其周围环境形成强烈对比。需要明确的是,边缘不是问题,只有这些单像素带

在这种情况下,使用类似于典型Sobel边缘检测的方法将不起作用,因为在这样的频带上,它将检测0。我可以考虑对内核进行其他修改,例如

-1 -2 -1
 2  4  2
-1 -2 -1
但我认为可能有一种“正确”的数学方法来做这样的运算


最后,我想用周围的像素平滑这些线条(所以是选择性模糊)。这些行可以以任何方向出现,所以如果我使用上面的内核,我需要在两个方向上应用它,并添加它,以获得与应用Sobel内核时类似的线强度。

我假设图像中有1像素宽的线,它们比周围环境亮或暗,您希望找到它们并将其从图像中移除,并将移除的像素平均替换为当地的社区

我为此开发了一个算法,它适用于我的示例数据(因为您没有提供任何数据)。它包括两部分:

线路识别

我想不出一个简单但有效的过滤器来检测线路(线路是相连的,所以可能需要查看相关性)。因此,我使用了一个简单的单像素检测过滤器:

-1 -1 -1
-1  8 -1
-1 -1 -1
然后是一些合适的阈值

从掩码外部到掩码的数据外推

一个非常优雅的解决方案(仅使用卷积)是将数据从遮罩中取出并用高斯函数卷积,然后取负遮罩并用完全相同的高斯函数卷积,然后按像素划分。遮罩内的结果是所需的模糊

数学上是什么:数据的加权平均

这是我的幻影数据:

这是线路的标识

最终结果表明,失真被抑制了十倍:

最后是我的代码(在Matlab中):


你不会说乐队有什么问题,只会说他们反差太大,索贝尔不管用。是否要删除它们?增强它们?标记它们?它们看起来怎么样?它们是水平的还是垂直的?我不知道Sobel滤波器怎么能检测不到1像素的波段。如果我们有一个特殊的波段,它的对比度比上面或下面的波段要高(如果它是垂直波段,那么它的对比度就在左边和右边),那么你会发现沿着这个波段有很强的梯度。你能给我们看一个例子或者你写的任何代码来说明你的观点吗?我很难想象问题出在哪里。@rayryeng-在这种情况下,Sobel的问题是,如果你应用到一条亮度正好为一个像素宽的直线上,你会发现直线上没有直接的边,而是一条上面两个像素,下面两个像素的边。图片[-1,-2,-1,0,0,1,2,1]。该线将直接位于0上,而上部和下部将直接位于非线上(在本例中,它们是相同的)。实际的边缘将被检测到线的正上方和正下方。此外,我希望保留非单像素宽度的边缘。对单像素进行一些基本的纸上分析,无论是0还是1,使用两个内核,它们在水平线和垂直线上的对比度似乎相同,但我的版本在对角线上的对比度更好。仍然投票通过并被标记为答案,因为它在一次通过中起作用,是一个经过深思熟虑的答案。@David谢谢。你可以自由地把所有的东西结合起来,也许只用我的推断。不知道你使用的是Matlab、Python还是C++。Python是我一直使用的。我已经把它编码好了,现在正在我们的真实数据集上尝试我们的两个内核。看起来两个内核在真实数据集上的工作原理完全相同。再次感谢你的帮助!
%% create phantom data with lines (1pixel wide bands)
[x, y] = ndgrid(1:100, 1:100);
original = 3 * x - 2 * y + 100 * sin(x / 2) + 120 * cos(y / 3); % funny shapes
bw = original > mean(original(:)); % black and white
distortion = bwmorph(bw,'remove'); % some lines
data = original + max(original(:)) * distortion; % phantom

% show
figure();
subplot(1,3,1); imagesc(original); axis image; colormap(hot); title('original');
subplot(1,3,2); imagesc(distortion); axis image; title('distortion');
subplot(1,3,3); imagesc(data); axis image; title('image');

%% line detection
% filter by single pixel filter
pixel_filtered = filter2([-1,-1,-1;-1,8,-1;-1,-1,-1], data);

% create mask by simple thresholding
mask = pixel_filtered > 0.2 * max(pixel_filtered(:)); 

% show
figure();
subplot(1,2,1); imagesc(pixel_filtered); axis image; colormap(hot); title('filtered');
subplot(1,2,2); imagesc(mask); axis image; title('mask');

%% line removal and interpolation
% smoothing kernel: gaussian
smooth_kernel = fspecial('gaussian', [3, 3], 1);
smooth_kernel = smooth_kernel ./ sum(smooth_kernel(:)); % normalize to one

% smooth image outside mask and divide by smoothed negative mask 
smoothed = filter2(smooth_kernel, data .* ~mask) ./ filter2(smooth_kernel, ~mask);

% withing mask set data to smoothed
reconstruction = data .* ~mask + smoothed .* mask;

% show
figure();
subplot(1,3,1); imagesc(reconstruction); axis image; colormap(hot); title('reconstruction');
subplot(1,3,2); imagesc(original); axis image; title('original');
subplot(1,3,3); imagesc(reconstruction - original); axis image; title('difference');