转自:http://blog.csdn.net/fx677588/article/details/53301740

1. matlab图像保存说明

  matlab中读取图片后保存的数据是uint8类型(8位无符号整数,即1个字节),以此方式存储的图像称作8位图像,好处相比较默认matlab数据类型双精度浮点double(64位,8个字节),自然可以节省很大一部分存储空间。 
  详细来说imread把灰度图像存入一个8位矩阵,当为RGB图像时,就存入8位RGB矩阵中。例如,彩色图像像素大小是400*300( 高 * 宽 ),则保存的数据矩阵为400*300*3,其中每个颜色通道值是处于0~255之间。 
  但是虽然matlab中读入图像的数据类型是uint8,而在图像矩阵运算的时候,使用的数据类型却是double类型。一是为了保证精度,二是因为如果不转换,在对uint8进行加减时会产生溢出,可能提示的错误为: 

Function ‘*’ is not defined for values of class ‘uint8’

  1个字节无符号整型最大只能存储数据为255,对图片的操作所以很容易溢出。

2. matlab图像类型转换

  matlab读入图像的数据是uint8,而matlab中数值一般采用double型(64位)存储和运算。所以要先将图像转为double格式的才能运算,区别如下:

img = imread('./1.jpg'); % 读入是unit8型(0~255)数据
I1 = im2double(img); % 把图像转换成double精度类型(0~1)
I2 = double(img)/255; % uint8转换成double,作用同im2double

  这里补充说明一下,im2double( )和double( )的区别。double( img)就是简单的数据类型转换,将无符号整型转换为双精度浮点型double,但是数据大小没有变化,原本数据是0~255之间,转化后还是0~255。例如原来是255,那么转换后为255.0,小数位0个数是由double数据长度决定,实际数据大小还是255,只不过这个255已经是double类型空间存储了,再增加不会发生溢出情况。而im2double(img)则不仅仅是将uint8转换到double类型,而且把数据大小从0~255映射到0~1区间。 
  另外需要补充说明下面这种情况:

img = imread('./1.jpg');
I1 = double(img);
I2 = im2double(I2); % I2数据依然是0~255,并不是0~1,即I1=I2

  因为I1已经是double类型,imdouble不会对double类型数据0~255映射到区间0~1,所以上面im2double操作没有任何作用,I1和I2相等。 
  总结如下:函数im2double将输入转换成double类型。如果输入是uint8、unit16 或者是二值的logical类型,则函数im2double 将其值归一化到0~1之间,当然就是double类型的了。如果输入本身就是double类型,输出还是double类型,并不进行映射。 
  如果已经是double类型的数据需要映射,则进行下面操作即可:  

I2 = I1/255;

3. matlab图像显示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(unit8(I)); % 转成unit8

4. uint和double数据转换的深入说明

  double和uint8、uint16之间数据转换有下面的函数:

im2double(); % 将图像数组转换成double精度类型
im2uint8(); % 将图像数组转换成unit8类型
im2uint16(); % 将图像数组转换成unit16类型

  当然,当图像数据是double类型的0~1之间,下面两者操作是等价的:

I1=im2uint8(I);
I2=uint8(round(
I*255));

  但是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]

5. mat2gray()和im2double()区别

  这两个如果都是对uint8数据操作,区别就在于前者是归一化操作,归一化后也在0~1之间,自然结果也是double类型,后者是将数据从0~255映射到0~1。例如:

I  = uint8([1,1,2,3]);
I1 = mat2gray(I); % 归一化,I1结果是double型[0,0,0.5,1]
I2 = im2double(I); % 映射化,I2结果是double型[0.0039,0.0039,0.0078,0.0118]

需要分清楚归一化和映射的区别;

  可以看出,虽然两者都是一种归一化,im2double只不过最大值永远是常数255,最小值永远是0,如下: 
                                          (I−0.0)/(255.0−0.0)

  而mat2gray最大值和最小值都是当前矩阵中最大最小的值,如下: 

                                    I−min(I)/max(I)−min(I)

另外补充一个函数,mat2str()是将数型转换为字符串类型,一般在批量处理图片,给保存图片格式的名称中有作用,这样就不需要格式化sprintf操作了,非常方便。

matlab图像类型转换以及uint8、double、im2double、im2uint8和mat2gray等说明的更多相关文章

  1. MATLAB图像uint8,uint16,double, rgb转灰度解释

    1.uint8,uint16与double 为了节省存储空间,matlab为图像提供了特殊的数据类型uint8(8位无符号整数),以此方式存储的图像称作8位图像.matlab读入图像的数据是uint8 ...

  2. Matlab中double,im2double,mat2gray区别

    转载:http://blog.sina.com.cn/s/blog_6c41e2f30101559d.html ****************假设某图像数据A(uint8格式)*********** ...

  3. matlab图像基础知识

    1.MATLAB支持的几种图像文件格式: ⑴JPEG(Joint Photogyaphic Expeyts Group):一种称为联合图像专家组的图像压缩格式. ⑵BMP(Windows Bitmap ...

  4. 本图片处理类功能非常之强大可以实现几乎所有WEB开发中对图像的处理功能都集成了,包括有缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等功能

    import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.Graphic ...

  5. -1.#IND000 &&图像类型转换

    (1):float acos(float x) 参数x的范围为-1.0f到1.0f之间,返回值范围在0.0f到3.141592653f之间,值得注意的是:当x超出[-1.0f,1.0f]这个范围时此函 ...

  6. 【转载】VC++中的图像类型转换--使用开源CxImage类库

    一.CxImage类库简介 这只是翻译了CxImage开源项目主页上的部分简介及简单使用. CxImage类库是一个优秀的图像操作类库.它可以快捷地存取.显示.转换各种图像.有的读者可能说,有那么多优 ...

  7. Matlab图像彩色转灰色

    Matlab图像彩色转灰色 时间:2014年5月7日星期三 网上找的程序.实现图像彩色转灰色: I1=imread('C:\Users\Yano\Desktop\matlab\test1\4.jpg' ...

  8. matlab 图像和 opencv 图像的相互转换

    matlab可以生成C++代码, 但是在涉及图像数据的时候,要注意数据格式的转换. 1. Matlab图像数据在内存中的存放顺序是R通道图,G通道图,B通道图.对于每个通道,数据存放是先列后行. 2. ...

  9. matlab 图像Mat类型矩阵中的值(uint8)类型转换,防止溢出

    a=[50,60,70; 80,90,50; 100,55,40] 假设a是一个灰度图的mat形式(当然实际的size肯定比这大,我只是举例子),如果需要对这个矩阵的像素进行加减处理,很可能会产生溢出 ...

随机推荐

  1. Linux 环境变量 $PATH

    我们知道查阅文件属性的指令 ls 完整文件名为:/bin/ls(这是绝对路径),那为什么可以在任何地方执行/bin/ls 这个指令呢?  为什么在任何目录下输入 ls 就一定可以显示出一些讯息而不会说 ...

  2. RabbitMQ-优先级(priority)队列/消息

    就像在日常生活中,事情有轻重缓急一样.我们对于需要处理的消息也有这样的需求. 例如重要的消息我要尽快的得到处理,当然我们可以给重要的消息开个“VIP通道”,但是VIP数量很多,并且VIP也分层次呢? ...

  3. sl4j记录

  4. SAP-MM:收货转储时提示 M7053“只能在公司代码 **** 的期间 2014/04 和 2014/03 中记账”

    错误信息   消息号M7053   解决方法 Step 1.使用MMPV进入"关闭账期"界面. Step 2.输入"公司代码"."期间".& ...

  5. 初识AM335X

    TI 的AM335X,linux 操作系统,全都是陌生的东东,一点一点来熟悉吧. 拿的TI代理的一开发板,直接看文档.环境由于之前一同事已经装好了,公司条件受限,没法让我们一人一台ubuntu的机子来 ...

  6. linux网络编程学习笔记之五 -----并发机制与线程�

    进程线程分配方式 简述下常见的进程和线程分配方式:(好吧,我仅仅是举几个样例作为笔记...并发的水太深了,不敢妄谈...) 1.进程线程预分配 简言之,当I/O开销大于计算开销且并发量较大时,为了节省 ...

  7. git使用介绍

    Git简单介绍 参考网址: git使用简介 这个教程推荐使用:git教程 git和svn的差异 git和svn的最大差异在于git是分布式的管理方式而svn是集中式的管理方式.如果不习惯用代码管理工具 ...

  8. [转] Java多线程发展简史

    这篇文章,大部分内容,是周五我做的一个关于如何进行Java多线程编程的Knowledge Sharing的一个整理,我希望能对Java从第一个版本开始,在多线程编程方面的大事件和发展脉络有一个描述,并 ...

  9. 安卓扫码:简单的ZXing使用记录

    ZXing是Google提供的条形码.二维码等的生成.解析的库.最近工作需求去研究了一下,主要是研究怎么扫描二维码(QRCode).网上教程也不少,但大多看了不明所以,甚至看了半天都不知道解码到底从哪 ...

  10. 新版本ButterKnife的配置

    新版本的ButterKnife的添加方式发生了变化,然后摸索着记录了一下. 按照ButterKnife的官网描述,使用ButterKnife需要在Gradle中添加如下依赖: compile 'com ...