matlab-图像处理-图片显示数据类型转化问题+imshow的合理使用

前言:此实验为利用低通滤波器实现图像平滑。本文并不介绍此实验的做法,而是解决,在算子函数和主函数逻辑正常的情况下,实验结果无法正常显示的细节问题。

1、为理想梯度函数传入double类型数据矩阵,子函数中转化为uint8类型 并用imshow(A,[])显示 主函数

%experiment_4_2
clc;
clear;
I1=imread('wire.jpg');
% I=rgb2gray(I);
figure;
subplot(2,2,1),imshow(I1);
title('原图像');
I=imnoise(I1,'salt & pepper',0.04);
I2=imnoise(I1,'salt & pepper',0.04);
I=im2double(I);%如果图像不是double类型的则转化为double
subplot(2,2,2);imshow(I);
title('加噪声后的图像')
s=fftshift(fft2(I));
s1=fftshift(fft2(I2));
% subplot(2,2,3);
% imshow(abs(s),[]);
% title('图像傅里叶变换后所得频谱');
subplot(2,2,3);
imshow(log(abs(s)),[]);
title('原始图像取对数后所得频谱')
Ideal(s);%
% butter(s);
% Index(s);
% Gradient(s);

理想梯度函数

%Ideal.m
function Ideal(s)
[a,b]=size(s);
a0=round(a/2);
b0=round(b/2);%找到中心点
d=10;
for i=1:a
    for j=1:b
        distance=sqrt((i-a0)^2+(j-b0)^2);
        if distance<=d h=1;
        else h=0;
        end;
        s(i,j)=h*s(i,j);
    end;
end;
figure;
subplot(1,2,1);
imshow(log(s),[]),title('理想高通滤波器所得频谱');
**s=uint8(real(ifft2(ifftshift(s))));**
subplot(1,2,2);
**imshow(s,[]);**
title('理想高通滤波所得图像');    
end

显示结果
matlab-图像处理-图片显示数据类型转化问题+imshow的合理使用_第1张图片

以上情况为将uint8数据类型用imshow(,[])格式显示(此函数作用:显示基于缩放显示的灰度图像imshow以[min(I(:)) max(I(:))]为显示范围,即I中最小值显示为黑色,最大值显示为白色。)即 自定义显示范围,多用于double类型数组显示。

2、由主函数传递给理想滤波器函数double类型图像数据矩阵,理想滤波器函数处理完毕后转化为uint8类型数据并用imshow(A)显示。

matlab-图像处理-图片显示数据类型转化问题+imshow的合理使用_第2张图片

3、在子函数用将

s=uint8(real(ifft2(ifftshift(s))));

换成

s=im2uint8(real(ifft2(ifftshift(s))));

显示结果
matlab-图像处理-图片显示数据类型转化问题+imshow的合理使用_第3张图片
至此,问题得到解决。
上述图片无法显示的问根源在数据类型转换问题
1)将double类型数据转化为uint8,用uint8(img)or im2uint8(img)?
uint8(img):uint8型是0~255范围,其只是能将255.0转化为255而已
im2uint8(img):double类型数据保存图片是0-1,,此函数能将0-1的double值映射到0-255.
2)将uint8类型转化为double类型,用double(img) or im2double(img)?
但是matlab默认double类型图片数据是位于0-1之间的,而uint8是位于0-255。所以如果矩阵数据图像是double类型(0-1之间)可直接im2uint8,这样不仅完成数据类型转换,而且将0-1之间映射为了0~255之间的数据。
   但是如果图像矩阵数据是double类型的0-255,直接im2uint8转换的话,matlab会将大于1的数据都转换为255,0-1之间的数据才会映射到0-255之间整型的数据。例如下面程序:

img64 = [1,2,3,4];
I8    = im2uint8(img64); % I8结果为[255 255 255 255]

总结:由于MATLAB的特性,一般用uint8保存图片,而计算时为保证精度,要转化为double。在转化的时候,要根据矩阵的范围和数据类型,合理选择转化函数就会避免此情况。

3、 将函数中此句,逆傅里叶变换函数

s=uint8(real(ifft2(ifftshift(s))));

变成

s=real(ifft2(ifftshift(s)));

此时显示结果:
matlab-图像处理-图片显示数据类型转化问题+imshow的合理使用_第4张图片

4、在3转换的基础上,用imshow(filename)显示

imshow(s);

matlab-图像处理-图片显示数据类型转化问题+imshow的合理使用_第5张图片
两者有略微区别,这是因为imshow(A)与imshow(A,[])两者都是显示图片, 如果A的灰度都在20以下,但确实又有灰度变化,你直接imshow看起来几乎都是黑的,imshow(A,[])后会从最小到最大拉伸显示,使显示的图片对比度差距更明显,所以会感觉上一张图片的内容会更加丰富一些,体现的理想滤波器的振铃效应也更加明显一些。可以确定的是,在子函数中将逆傅里叶变换的函数强制转化为uint8类型矩阵会丢失信息。

补充:imshow问题

在matlab处理完数据好,我们希望显示或者imwrite写入图片时候,需要注意。如果直接对double之间的数据矩阵I运行imshow(I),我们会发现有时候显示的是一个白色的图像。
  这是因为imshow()显示图像时对double型是认为在0-1范围内,即大于1时都是显示为白色,而imshow显示uint8型时是0-255范围。所以对double类型的图像显示的时候,要么归一化到0-1之间,要么将double类型的0-255数据转为uint8类型。解决方法如下:

imshow(I/255);    % 将图像矩阵转化到0-1之间
imshow(I,[]);     % 自动调整数据的范围以便于显示
inshow(uint8(I)); % 转成uint8

你可能感兴趣的:(笔记,图像处理)