matlab图像数据类型uint8,double关系

matlab图像数据类型uint8,double关系

(一)double型的图像矩阵转化为uint8(I)类型

为了节省存储空间,matlab为图像提供了特殊的数据类型uint8(8位无符号整数),以此方式存储的图像称作8位图像。matlab读入图像的数据是uint8,而matlab中数值一般采用double型(64位)运算。
运算的时候将原图像的灰度值转换成double的作用主要是考虑计算过程中的精度的问题,double的数据是有小数点的,而uint8是0-255的整数,如果直接用uint8计算,会在计算过程中产生舍入误差,这种误差在图像的数据中是比较大的误差。

代码编写:

I = rgb2gray(imread('D:\数字图像处理\第二章学习\dog2.jpg'));    %把图像变为灰度图像
f = im2double(I);   
g = im2uint8(f);
figure;
subplot(1, 2, 1), imshow(f), title('double类型图像');
subplot(1, 2, 2), imshow(g), title('uint8类型图像');

代码分析:

使用im2double()将uint8转换到double类型,而且把数据大小从0-255映射到0-1区间。然后用im2uint8(),这样不仅完成数据类型转换,而且将0-1之间映射为0-255之间的数据。

运行效果如下:

实验结果:

针对“要是把运算后是double型的图像矩阵转化为uint8(I)类型,虽然可以保证显示范围,但是显示精度确实大大降低,好多细节的区域不会显示出来,”,目前代码运行结果显示细节的区域显示差别不大,细节区域基本都能显示出来,但是针对显示精度问题,可以从理论得到论证,double的数据是有小数点的,而uint8是0-255的整数,如果直接用uint8计算,会在计算过程中产生舍入误差,这种误差在图像的数据中是比较大的误差。

matlab中double转化为uint8

下面展示im2uint8()和uint8()两种方法在不同初始状态下的实现效果,分析优劣,代码详细解释在注释中。

状态1:

代码编写:

I = rgb2gray(imread('D:\数字图像处理\第二章学习\dog1.jpg'));    %把图像变为灰度图像f  = im2double(I);   
f = im2double(I);       %im2double()将uint8转换到double类型,而且把数据大小从0~255映射到0~1区间。
g = im2uint8(f);         %im2uint8()实现double转化为uint8
h = uint8(round(f*255));       %uint8()实现double转化为uint8
figure;
subplot(1, 2, 1), imshow(g), title('im2uint8');
subplot(1, 2, 2), imshow(h), title('uint8');

运行状态如下:

由上图可以看出:当图像数据是double类型的0~1之间,两者操作是等价的。

状态2:

代码编写:

I = rgb2gray(imread('D:\数字图像处理\第二章学习\dog2.jpg'));    %把图像变为灰度图像  
f = double(I);    %double()将无符号整型转换为双精度浮点型double,数据大小没有变化,原本数据是0~255之间,转化后还是0~255。
g = im2uint8(f);      %im2uint8()实现double转化为uint8
h = uint8(round(f));     %uint8()实现double转化为uint8
figure;
subplot(1, 2, 1), imshow(g), title('im2uint8');
subplot(1, 2, 2), imshow(h), title('uint8');

运行状态如下:

由上图可以看出:如果图像矩阵数据是double类型的0-255,直接im2uint8()转换的话,matlab会将大于1的数据都转换为255,0-1之间的数据才会映射到0~255之间整型的数据,所以图像会显示白色。而unit8()转换后显示的图像仍然正常。

数学原理:

在数据类型转换时候uint8和im2uint8的区别,uint8的操作仅仅是将一个double类型的小数点后面的部分去掉;但是im2uint8是将输入中所有小于0的数设置为0,而将输入中所有大于1的数值设置为255,再将所有其他值乘以255。

代码编写:

A = linspace(-1,2,65536);      %在-1到2之间均匀取65536个点
x = A;
B = im2uint8(A);
figure;
plot(x,A);hold on;
plot(x,B);hold off;
title('im2uint8')
BB = uint8(A);
figure;
plot(x,A);hold on;
plot(x,BB);hold off;
title('uint8')

运行状态如下:

从图中可以清晰看出:蓝色的显示-1到2,红色的线是我们想看到的结果,在im2uint8图像中将输入中所有小于0的数设置为0,而将输入中所有大于1的数值设置为255;uint8对浮点数进行了取整操作。

综合分析:

图像数据在计算前需要转换为double,以保证精度;很多矩阵数据也都是double的。要想显示图像,必须先转换为图像的标准数据格式。如果转换前的数据符合图像数据标准(比如如果是double则要位于0~1之间) ,那么可以直接使用im2uint8。如果转换前的数据分布不合规律,则使用uint8,将其自动切割至0~255( 超过255的按255)。总的来说:im2uint8要求被转化的数据必须是符合图像数据标准(如:double [0 1]) ,而uint8()则不必,它会自动截断数据。由此可以推出unit8()是效果优的方法。

(二)图像的【0,1】和【0,255】显示

理论根源:

一般的CCD或者数码相机采样得到的亮度等级都是2的8次方个,也就是[0,255],这是采样结果,所以最简单的,就是直接用0到255表示了。但是有时候,我们要对图像进行各种变换,如果每次都用整数进行运算,后面的计算误差就会很大,所以就临时变成了浮点数,算完了之后再转回去,如果你用的是一个浮点数,无论你怎么变,信息量都不会丢失,至于后来为什么又要转回[0,255],这是因为显示器也可以是8位的,用[0,255]存储,可以直接显示。

matlab默认double类型图片数据是位于0~1之间的,而uint8是位于0-255之间。

uint8类型为无符号8位整数,范围 : [0 255],四舍五入。

uint8(-1)
uint8(99.4)
uint8(99.6)
 uint8(100)
 uint8(266)
double(0.22)

代码编写:

I = double(imread('D:\数字图像处理\第二章学习\adapth1.png'));
figure;
subplot(1, 3, 1), imshow(I), title('直接对double型图像显示');
subplot(1, 3, 2), imshow(I/255), title('将图像矩阵转化到0-1之间');
subplot(1, 3, 3), imshow(uint8(I)), title('将double类型的0~255数据转为uint8类型');

运行效果如下:

在这里插入图片描述

代码分析:

double( )就是简单的数据类型转换,将无符号整型转换为双精度浮点型double,但是数据大小没有变化,原本数据是0-255之间,转化后还是0-255。例如原来是255,那么转换后为255.0,小数位0个数是由double数据长度决定,实际数据大小还是255,只不过这个255已经是double类型空间存储了。代码第一行并没有选用im2double(),因为im2double()不仅仅是将uint8转换到double类型,而且把数据大小从0-255映射到0-1区间。

直接对double之间的数据矩阵I运行imshow(I),我们会发现有时候显示的是一个白色的图像。 这是因为imshow()显示图像时对double型的默认动态范围为【0,1】,I经过double( )变换后为double型,但值绝大部分都大于1,所以大范围都会显示为白色。imshow显示uint8型时是0-255范围。所以对double类型的图像显示的时候,要么归一化到0-1之间,要么将double类型的0~255数据转为uint8类型。

优劣对比:

  1. 运算的时候将原图像的灰度值转换成double的作用主要是考虑计算过程中的精度的问题,double的数据是有小数点的,而uint8是0-255的整数,如果直接用uint8计算,会在计算过程中产生舍入误差,这种误差在图像的数据中是比较大的误差。而且如不转换,在对uint8进行加减时会溢出。
  2. 显示的时候是因为我们的显示系统采用的颜色模式大多为RGB模式,其每一种颜色分量的取值只能在0-255,所以显示时要用uint8数据。
  3. 在Matlab中,数值一般都采用double型(64位,8个字节)存储和运算,为了节省存储空间,Matlab为图像提供了特殊的数据类型uint8(8位无符号整数,即一个字节)存储的时候的一般存储为uint8类型,以此方式存储的图像称为8位型像。

猜你喜欢

转载自blog.csdn.net/Dujing2019/article/details/89042609
今日推荐