处理过的图像中的工件

时间:2012-06-13 11:17:14

标签: matlab image-processing filter noise-reduction

这个问题与我之前在stackoverflow中的帖子Image Processing Algorithm in Matlab有关,我已经得到了我想要的结果。

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

enter image description here

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

enter image description here

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

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

修改

我添加了@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):

image1 image2 image3 iamge4

这是黑色背景:

blackbackground1 blackbackground2 blackbackground3

7 个答案:

答案 0 :(得分:13)

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

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

enter image description here

EntropyFilter[i, 1]

enter image description here

这些线很微弱,但你可以通过二进制化来看到它们的阈值非常低:

Binarize[i, .001] 

enter image description here

至于导致他们的原因,我只能推测。我会从相机输出本身开始追踪。此外,您可以“直接从相机中”发布两到三张图像,以便我们进行一些实验。

答案 1 :(得分:7)

您正在使用的相机很可能有一个CMOS芯片。由于它们具有可能具有稍微不同的电子特性的独立列(可能是行)放大器,因此可以使来自一列的信号比另一列更放大。

根据相机的不同,色谱柱强度的这些变化可以保持稳定。在这种情况下,你很幸运:拍摄~100张暗影(在镜头上贴一些东西),平均它们,然后在运行分析之前从每张图像中减去它们。这应该使线条消失。如果线条没有消失(或者有其他线条),请使用post-processing scheme proposed by Amro删除二值化后的线条。

修改

以下是你如何进行背景减法,假设你拍摄了100张暗影,并将它们存储在一个包含100个元素的单元格数组D中:

% 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)

答案 2 :(得分:5)

您可以使用某种morphological opening来删除细线:

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

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

screenshot

使用的结构元素是:

>> SE.getnhood
ans =
     1     1     1

答案 3 :(得分: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)

这是过滤后的图像

Filtered Image

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

Pixels affected by filter

答案 4 :(得分:2)

如果没有真正深入研究图像处理,我可以想到两个原因:

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

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

答案 5 :(得分:1)

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

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

2)这些图像的最终目标是什么。目标是简单地摆脱线条,无论图像其余部分的质量如何,或者是保持绝对最佳图像质量的重点。你之后是否要进行其他处理?

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

好的,所以说你能够得到这个校准数据,那么你就能找出哪些列是坏的,甚至是单个像素。

如果您有这些数据,可以删除列的一种方法是:

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)

为冗长的回答道歉,但我希望这仍然对某人有用: - )

答案 6 :(得分:0)

由于您无法在原始图像中看到线条,因此与原始图像范围相比,它们的强度差异较小,或者由处理算法添加。

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

看起来您的传感器列不均匀,尝试使用相同的曝光(和其他)设置拍摄没有手指的照片(仅限背景),然后从手指的照片中减去它(在其他处理之前)。 (在拍摄两张照片之前,请确保背景均匀。)