14

这个问题与我之前的帖子有关Stackoverflow中 Matlab中的图像处理算法,我已经得到了我想要的结果。

但是现在我面临另一个问题,并且在过程图像中得到了一些人工制品。在我的原始图像(600 张图像的堆栈)中,我看不到任何人工制品,请查看指甲的原始图像:

在此处输入图像描述

但在我的 10 个处理结果中,我可以看到以下几行:

在此处输入图像描述

我真的不知道他们从哪里来?

另外,如果它们属于相机的传感器,为什么我在原始图像中看不到它们?任何想法?

编辑:

我添加了@Jonas 建议的以下代码。它减少了伪影,但并没有完全去除它们。

%averaging of images
im = D{1}(:,:);
for i = 2:100
 im = imadd(im,D{i}(:,:));
end
im = im/100;
imshow(im,[]);

for i=1:100
SD{i}(:,:)=imsubtract(D{i}(:,:),im(:,:))
end

@belisarius 要求提供更多图片,因此我将上传 4 张带有散斑图案的手指图片和 4 张黑色背景尺寸(1280x1024)的图片:

图像1 图2 图3 图像4

这是黑色背景:

黑色背景1 黑色背景2 黑色背景3

4

7 回答 7

13

您的工件实际上存在于您的原始图像中,尽管不可见。Mathematica 中的代码:

i = Import@"http://i.stack.imgur.com/5hM3u.png"

在此处输入图像描述

EntropyFilter[i, 1]

在此处输入图像描述

线条很微弱,但您可以通过非常低级别阈值的二值化看到它们:

Binarize[i, .001] 

在此处输入图像描述

至于是什么原因造成的,我只能推测。我将从相机输出本身开始追踪。此外,您可以发布两到三张“直接来自相机的图像”,让我们进行一些实验。

于 2012-06-13T13:43:44.513 回答
7

您使用的相机很可能有一个 CMOS 芯片。由于它们具有独立的列(可能还有行)放大器,其电子特性可能略有不同,因此您可以从一列获得比另一列放大得多的信号。

根据相机的不同,色谱柱强度的这些变化可能是稳定的。在这种情况下,你很幸运:拍摄大约 100 张暗图像(在镜头上粘贴一些东西),对它们进行平均,然后在运行分析之前从每张图像中减去它们。这应该使线条消失。如果线条没有消失(或者如果有额外的线条),则使用Amro 提出的后处理方案将二值化后的线条去除。

编辑

D假设您拍摄了 100 张深色图像并将它们存储在具有 100 个元素的元胞数组中,以下是您进行背景减法的方法:

% take the mean; convert to double for safety reasons
meanImg = mean( double( cat(3,D{:}) ), 3); 

% then you cans subtract the mean from the original (non-dark-frame) image
correctedImage = rawImage - meanImg; %(maybe you need to re-cast the meanImg first)
于 2012-06-13T14:25:55.130 回答
5

这是一个答案,认为会比上述方法更温和地删除线条:

im = imread('image.png');   % Original image
imFiltered = im;            % The filtered image will end up here
imChanged = false(size(im));% To document the filter performance 

% 1)
% Compute the histgrams for each column in the lower part of the image
% (where the columns are most clear) and compute the mean and std each
% bin in the histogram.
histograms = hist(double(im(501:520,:)),0:255);
colMean = mean(histograms,2);
colStd = std(histograms,0,2);

% 2)
% Now loop though each gray level above zero and...
for grayLevel = 1:255

    % Find the columns where the number of 'graylevel' pixels is larger than
    % mean_n_graylevel + 3*std_n_graylevel). - That is columns that contains
    % statistically 'many' pixel with the current 'graylevel'. 
    lineColumns = find(histograms(grayLevel+1,:)>colMean(grayLevel+1)+3*colStd(grayLevel+1));

    % Now remove all graylevel pixels in lineColumns in the original image
    if(~isempty(lineColumns))
        for col = lineColumns 
            imFiltered(:,col) = im(:,col).*uint8(~(im(:,col)==grayLevel));
            imChanged(:,col) = im(:,col)==grayLevel;
        end
    end 
end

imshow(imChanged)
figure,imshow(imFiltered)

这是过滤后的图像

过滤后的图像

这显示了受过滤器影响的像素

受滤镜影响的像素

于 2012-06-15T19:42:50.980 回答
5

您可以使用某种形态 开口来删除细垂直线:

img = imread('image.png');
SE = strel('line',2,0);
img2 = imdilate(imerode(img,SE),SE);

subplot(121), imshow(img)
subplot(122), imshow(img2)

截屏

使用的结构元素是:

>> SE.getnhood
ans =
     1     1     1
于 2012-06-13T13:21:45.473 回答
2

在没有真正深入研究您的图像处理的情况下,我可以想到发生这种情况的两个原因:

  1. 处理引入了这些工件。这不太可能,但这是一种选择。检查您的算法和代码。

  2. 这是一个副作用,因为您的处理减少了图片的动态范围,就像量化一样。所以实际上,这些伪影可能在处理之前就已经存在于图片本身中,但由于它们的水平非常接近背景水平,因此无法被注意到。至于这些伪影的来源,甚至可能是相机本身。

于 2012-06-13T12:19:14.047 回答
1

这是一个非常有趣的问题。我曾经用实时红外成像仪(视频系统)来处理这类问题。实际上,在用户看到或拿到图像之前,我们在相机中内置了算法来处理这个问题。几个问题:

1)您是在处理 RAW 图像还是在处理已经预处理的灰度(或 RGB)图像?

2)这些图像的最终目标是什么。目标是简单地消除线条,而不管结果图像的其余部分的质量如何,或者是保持绝对最佳图像质量的关键。之后要进行其他处理吗?

我同意这些线条最有可能出现在您的所有图像中。这些线条出现在图像中的原因有两个,一个是在明亮的场景中,列的运算放大器饱和,从而导致图像的整个列获得相机可以输出的最亮值。另一个原因可能是糟糕的 OP AMP 或 ADC(模数转换器)本身(很可能不是 ADC,因为通常整个传感器基本上有 1 个 ADC,这会使整个图像变差,而不是你的情况)。饱和情况实际上更难处理(我不认为这是你的问题)。注意:传感器上过多的饱和度可能会导致传感器中出现坏像素和列(这就是为什么他们说永远不要将相机对准太阳)。可以处理坏柱问题。以上在另一个答案中,有人让你平均图像。虽然这可能有助于找出坏列(或坏的单个像素,或传感器的噪声矩阵)在哪里(并且您必须将相机平均指向黑色、白色,基本上是纯色),但它不是t 摆脱它们的正确答案。顺便说一句,我用黑白和平均,以及发现坏像素等来解释什么……称为校准传感器。

好的,所以说您能够获得此校准数据,那么您将能够找出哪些列是坏的,甚至是单个像素。

如果您有此数据,则可以擦除列的一种方法是:

for each bad column
    for each pixel (x, y) on the bad column
        pixel(x, y) = Average(pixel(x+1,y),pixel(x+1,y-1),pixel(x+1,y+1),
                              pixel(x-1,y),pixel(x-1,y-1),pixel(x-1,y+1))

这本质上是用一个新像素替换坏像素,这是它周围剩余的 6 个好像素的平均值。以上是算法的过度简化版本。在某些情况下,单个坏像素可能就在坏列旁边,不应该用于平均,或者两个或三个坏列彼此相邻。可以想象你会计算一个坏列的值,然后认为该列是好的,以便移动到下一个坏列,等等......

现在,我询问 RAW 与 B/W 或 RGB 的原因。如果您正在处理 RAW,则取决于传感器本身的构建,可能只有拜耳过滤图像传感器的一个子像素(如果您愿意)具有不良的 OP AMP。如果你能检测到这一点,那么你就不必丢弃其他好的子像素数据。其次,如果您使用 RGB 传感器拍摄灰度照片,并以 RAW 格式拍摄,那么您可以计算自己的灰度像素。许多传感器在使用 RGB 传感器返回灰度图像时,只会将绿色像素作为整体像素传回。这是因为它确实起到了图像发光的作用。这就是为什么大多数图像传感器为每个 r 或 g 子像素实现 2 个绿色子像素。

gray = (0.299*r + 0.587*g + 0.114*b)

为冗长的回答道歉,但我希望这对某人来说仍然是信息性的:-)

于 2012-06-16T06:06:38.457 回答
0

由于您看不到原始图像中的线条,它们要么与原始图像范围相比强度差异较小,要么是由您的处理算法添加的。

干扰的形状暗示了第一个选项......(除非你有一个单独处理每一行的算法。)

似乎您的传感器的列不均匀,请尝试使用相同的曝光(和其他)设置在没有手指(仅背景)的情况下拍照,然后从手指的照片中减去它(在其他处理之前)。(在拍摄两张图像之前,请确保背景是统一的。)

于 2012-06-17T13:08:28.077 回答