图像标准化,图像范围和图像缩放不同的图像堆栈

时间:2012-06-24 16:02:55

标签: matlab image-processing normalization

我对图像标准化,图像范围和图像缩放非常困惑。 我正在使用算法(我已在我的Previous Question中上传了算法),在应用算法后,我使用wikipedia中的公式来规范化图像:

enter image description here

使用MATLAB中的getrangefromclass(filtImag1{i}),应用算法前的矩阵范围为[0 255],应用算法后,范围为[0 1]。

问题是我需要找一个参考来找出规范化公式是否正确?我还有5叠图像,每张图像包含600张图像。我已经为每个堆栈应用了算法,并且由于算法的结果是每个堆栈有10个图像,我最终会得到50个我需要分析的图像并将它们进行比较。我找到了50张图像的最大值和最小值,然后将每张图像传递到公式中以对图像进行标准化。

虽然图像的范围是[0 1],但图像的最大值是: max = 3.6714e + 004

为什么呢?不应该是1吗? 这是正常化的正确方法吗? 我该如何应用缩放?我需要这样做吗?

这是规范化代码:

%%%%%%%%%%%%%%Find Min and Max between the results%%%%%%%%%%%%%%%%%%%%%%% 
pre_max = max(filtImag1{1}(:));
for i=1:10
   new_max = max(filtImag1{i}(:));
    if (pre_max<new_max)
        pre_max=max(filtImag1{i}(:));
    end
end
new_max = pre_max;

pre_min = min(filtImag1{1}(:));
for i=1:10
   new_min = min(filtImag1{i}(:));
    if (pre_min>new_min)
        pre_min = min(filtImag1{i}(:));
    end
end
new_min = pre_min;

%%%%%%%%%%%%%%normalization %%%%%%%%%%%%%%%%%%%%%%%
 for i=1:10
 temp_imag = filtImag1{i}(:,:);
 x=isnan(temp_imag);
 temp_imag(x)=0;
 t_max = max(max(temp_imag));
 t_min = min(min(temp_imag));
 temp_imag = (double(temp_imag-t_min)).*((double(new_max)-double(new_min))/double(t_max-t_min))+(double(new_min));
 imag_test2{i}(:,:) = temp_imag;
 end

修改 我已根据建议的答案更改了代码,但结果是黑色图像

%找到它们之间的最大值和最小值 pre_max = max(sTStack {1}(:)); 因为我= 1:40    newMax = max(sTStack {i}(:));     if(pre_max

pre_min = min(sTStack {1}(:)); 因为我= 1:40    newMin = min(sTStack {i}(:));     if(pre_min&gt; newMin)         pre_min = min(sTStack {i}(:));     结束 结束 t_min = pre_min;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%

表示i = 1:40 NTstack {i} =(sTStack {i} - t_min)/(t_max-t_min); 端

表示i = 10:10:40     图中,imshow(NTstack {I});     彩条     colormap jet 端

3 个答案:

答案 0 :(得分:7)

您提供的Wikipedia代码段是正确的,可以使用以下MATLAB代码对图像进行规范化:

%% Create an Example Image:
rand('seed', 1982);
n = 16;
myImg= rand(n,n)*.2 + .5;

%% Normalize the Image:
myRange = getrangefromclass(myImg(1));
newMax = myRange(2);
newMin = myRange(1);

myImgNorm = (myImg - min(myImg(:)))*(newMax - newMin)/(max(myImg(:)) - min(myImg(:))) + newMin;

一些图像的问题在于它们虽然只占用一小部分可能的值。如果你的值可以在0和1之间,那么黑色将是0而白色将是1.但是,如果图像中最暗的点是.5而你的最亮点是.7那么它可能看起来已经被淘汰到你的处理或者用户何时被可视化(请注意,由于这个原因,MATLAB的imagesc会在显示之前自动对图像进行规范化)。

如果使用hist(myImg(:))查看图像的直方图,您可以了解图像实际使用的允许值的必须性。在标准化图像中,最小值为0,最大值为1(或者您使用的任何范围)。

实现此等式时常见的错误是没有正确放置括号,在缩放之前不减去图像的最小值,或者不在“newMin”中添加回来。

您可以在以下代码和图像中一起查看所有内容。请注意原始图像(1)如何仅使用空间(2)的一小部分,因此当我们不让imagesc自动缩放攀爬参数时,它看起来会褪色。然而,一旦我们归一化(3),图像具有非常暗和非常轻的值,并且直方图从0到1(4)一直延伸。虽然不清楚你的代码是做什么或不做什么,但将它与这个例子进行比较可以解决你的问题。

%% Create an Example Image:
rand('seed', 1982);
n = 16;
myImg= rand(n,n)*.2 + .5;

%% Normalize the Image:
myRange = getrangefromclass(myImg(1));
newMax = myRange(2);
newMin = myRange(1);

myImgNorm = (myImg - min(myImg(:)))*(newMax - newMin)/(max(myImg(:)) - min(myImg(:))) + newMin;

%% Display the Image:
figure(42);
clf;

% Display the original:
subplot(2,2,1);
imagesc(myImg);
set(gca, 'clim', [0,1]);;
title('(1) Original Image');

% Display the hist of the original:
subplot(2,2,3);
hist(myImg(:))
xlim([0,1]);
title('(2) Histogram Of Original Image');

% Display the normalized image:
subplot(2,2,2);
imagesc(myImgNorm);
title('(3) Normalized Image');

% Display the hist of the normalized image:
subplot(2,2,4);
hist(myImgNorm(:))
title('(4) Histogram of Normalized Image');
xlim([0,1]);

colormap gray

enter image description here

编辑:

此外,还有一些重点要说明getrangefromclass(...)如何处理您的问题。此函数返回“基于其类的图像的默认显示范围”---也就是说,它返回MATLAB认为合理的值范围是该数据类型表示图片的值。对于uint8数据,这是[0,255]。对于int16,这是[-32768,32767]。对于你的情况,加倍,范围是[0,1],不是因为它是最小值和最大值,而是因为这是常规的,而双数据类型有一个特殊的表示,使得这个范围非常合理。 请注意,范围与您的数据实际是什么无关。如果您的数据小于或大于min和max将与MATLAB认为对图片有益的数据完全不同。在双倍或单倍的情况下,您的价值可能会更大。要将值标准化为[0,1]之间,我们可以使用我们一直在讨论的代码。

在这种情况下,我们创建一个具有大正值和负值的随机图像,但我们将它们全部缩放到0到1之间。也就是说,我们制作最暗的颜色0和点亮的颜色1 ---而在最小的前面是负数千,最大的是正数千。但是,请注意直方图形状保持不变,而x轴值变为0,1。这应该说明为什么MATLAB范围是[0,1],但你的最小值/最大值是不同的----这很好,你的标准化代码将修复零到一之间的所有内容。

randn('seed', 1982);
myImg = randn(n,n)*1000;
% Normalize the Image:
myRange = getrangefromclass(myImg(1));
newMax = myRange(2);
newMin = myRange(1);

myImgNorm = (myImg - min(myImg(:)))*(newMax - newMin)/(max(myImg(:)) - min(myImg(:))) + newMin;

% Display the Image:
figure(42);
clf;

% Display the original:
subplot(2,2,1);
imagesc(myImg);
% set(gca, 'clim', [0,1]);;
title('(1) Original Image');
colorbar
% Display the hist of the original:
subplot(2,2,3);
hist(myImg(:))
title('(2) Histogram Of Original Image');
axis tight;

% Display the normalized image:
subplot(2,2,2);
imagesc(myImgNorm);
title('(3) Normalized Image');
colorbar

% Display the hist of the normalized image:
subplot(2,2,4);
hist(myImgNorm(:))
title('(4) Histogram of Normalized Image');
axis tight;

colormap gray

enter image description here

答案 1 :(得分:3)

回答了你之前的问题,我想我理解你的困惑。

首先,输入图像的类型为uint8(因此范围为[0,255]),由于我们需要对信号进行处理(Butterworth过滤),因此需要转换为{{ 1}}数据类型,以避免值被截断。

现在在处理结束时,生成的“图像”类型为double,但具有任意范围(它们代表信号中的平均能量)。现在,如果我们想要显示这些图像甚至对它们执行图像处理(您试图在原始代码中应用double),MATLAB希望类型为medfilt2的图像位于[0, 1]范围。

我在代码中使用的公式和你刚才提供的公式是兼容的,它只是我正常化到[0,1]的范围,因此doublenewMax = 1和等式就像我之前描述的那样结束:

newMin = 0

请记住,您应该自己规范化每个图像,即计算图像本身的公式中的最小值/最大值,而不是整个图像组。如果你回顾我提出的解决方案,图像存储在一个单元格数组中,并使用CELLFUN完成计算,分别得到每个图像的最小值/最大值:

 img = ( img - min(img(:)) ) ./ ( max(img(:)) - min(img(:)) );

显然,信号存储为线性化矢量(每个都在一个单元格中),因此我们将每个信号归一化到[0,1]范围,然后我们将其重新塑造成一个合适的图像矩阵。

现在,如果您想在此之后返回Tf = cellfun(@(x)reshape((x-min(x))./range(x),sz), Tf, 'Uniform',false); 图片,只需拨打uint8即可。

我应该补充一点,我们上面执行的线性变换的类型称为最小/最大标准化,但它肯定不是唯一的类型(其他示例请参见this answer)。人们也可以研究其他对比度增强技术(想想直方图均衡和the like

答案 2 :(得分:2)

我通常会使用图像处理工具箱中的mat2gray来实现以下目的:mat2gray。我应用与您在上面提到的完全相同的线性插值。在内部,它会调用imlincomb

您提到的问题让我相信您错误地实施了上述等式。