图像格式及Matlab的格式转换
1. matlab图像保存说明
matlab中读取图片后保存的数据是uint8类型(8位无符号整数,即1个字节),以此方式存储的图像称作8位图像,好处相比较默认matlab数据类型双精度浮点double(64位,8个字节),自然可以节省很大一部分存储空间。
详细来说imread把灰度图像存入一个8位矩阵,当为RGB图像时,就存入8位RGB矩阵中。例如,彩色图像像素大小是400300( 高 * 宽 ),则保存的数据矩阵为400300*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,但是数据大小没有变化,原本数据是0255之间,转化后还是0255。例如原来是255,那么转换后为255.0,小数位0个数是由double数据长度决定,实际数据大小还是255,只不过这个255已经是double类型空间存储了,再增加不会发生溢出情况。而im2double(img)则不仅仅是将uint8转换到double类型,而且把数据大小从0255映射到01区间。
另外需要补充说明下面这种情况:
img = imread('./1.jpg');I1 = double(img);I2 = im2double(I2); % I2数据依然是0~255,并不是0~1,即I1=I2
因为I1已经是double类型,imdouble不会对double类型数据0255映射到区间01,所以上面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型是认为在01范围内,即大于1时都是显示为白色,而imshow显示uint8型时是0255范围。所以对double类型的图像显示的时候,要么归一化到01之间,要么将double类型的0255数据转为uint8类型。解决方法如下:
imshow(I/255); % 将图像矩阵转化到0-1之间imshow(I,[]); % 自动调整数据的范围以便于显示inshow(uint8(I)); % 转成uint8
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类型图片数据是位于01之间的,而uint8是位于0255。所以如果矩阵数据图像是double类型(01之间)可直接im2uint8,这样不仅完成数据类型转换,而且将01之间映射为了0~255之间的数据。
但是如果图像矩阵数据是double类型的0255,直接im2uint8转换的话,matlab会将大于1的数据都转换为255,01之间的数据才会映射到0~255之间整型的数据。例如下面程序:
img64 = [1,2,3,4];I8 = im2uint8(img64); % I8结果为[255255255255]
5. mat2gray()和im2double()区别
这两个如果都是对uint8数据操作,区别就在于前者是归一化操作,归一化后也在01之间,自然结果也是double类型,后者是将数据从0255映射到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.0255.0−0.0
而mat2gray最大值和最小值都是当前矩阵中最大最小的值,如下:
I−min(I)max(I)−min(I)
另外补充一个函数,mat2str()是将数型转换为字符串类型,一般在批量处理图片,给保存图片格式的名称中有作用,这样就不需要格式化sprintf操作了,非常方便。
资源来源:https://www.cnblogs.com/psztswcbyy/p/7489516.html
我的个人博客主页,欢迎访问
我的CSDN主页,欢迎访问
我的GitHub主页,欢迎访问
图像格式及Matlab的格式转换的更多相关文章
- FFmpeg学习4:音频格式转换
前段时间,在学习试用FFmpeg播放音频的时候总是有杂音,网上的很多教程是基于之前版本的FFmpeg的,而新的FFmepg3中audio增加了平面(planar)格式,而SDL播放音频是不支持平面格式 ...
- ffplay源码分析5-图像格式转换
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10311376.html ffplay是FFmpeg工程自带的简单播放器,使用FFmpeg ...
- bmp,jpg,png,tif,wmf,emf与eps图片格式转换
wmf/emf是两种Microsoft Windows的图形文件格式.它是一个矢量图格式,但是也允许包含位图.本质上,一个WMF文件保存一系列可以用来重建图片的Windows GDI命令.在某种程度上 ...
- Qt QImag图像保存、格式转换
图像保存bool QImage::save(const QString &fileName, const char *format = Q_NULLPTR, int quality = -1) ...
- 【视频处理】YUV与RGB格式转换
YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与YUV的变换公式如下: YUV(25 ...
- 日期格式转换 java 2016-09-03T00:00:00.000+08:00
/** * 日期格式转换yyyy-MM-dd'T'HH:mm:ss.SSSXXX (yyyy-MM-dd'T'HH:mm:ss.SSSZ) TO yyyy-MM-dd HH:mm:ss * @ ...
- RSA密钥之C#格式与Java格式转换
前言 最近由于项目需求,服务端由c#编写,客户端由java编写.通信数据使用RSA非对称加密.但是java和c#生成的密钥格式是不一样的,所以需要转换格式才可以正常使用.网上搜到使用java进行格式转 ...
- 【VC++技术杂谈007】使用GDI+进行图片格式转换
本文主要介绍如何使用GDI+对图片进行格式转换,可以转换的图片格式为bmp.jpg.png. 1.加载GDI+库 GDI+是GDI图形库的一个增强版本,提供了一系列Visual C++ API.为了使 ...
- Oracle日期格式转换,tochar(),todate()
Oracle日期格式转换 本文主要介绍Oracle中的日期转换. 1. 日期转化为字符串 (以2016年10月20日为例) select to_char(sysdate,'yyyy-mm-dd hh2 ...
- C#返回时间格式转换成 js 字符串
在.net 中,调用 post 或者 get和后台通信时,如果有时间返回信息,后台返回的时间信息一般是这样格式:Thu Jul 9 23:14:53 UTC+0800 2015,那么要在前台显示就会有 ...
随机推荐
- Active Record 活动记录
ActiveRecord活动记录类 一.声明AR类(模型层) namespaceapp\models; useyii\db\ActiveRecord; classCustomer extends Ac ...
- Android事件分发-基础原理和场景分析
作者:京东零售 郭旭锋 1 为什么需要事件分发 和其他平台类似,Android 中 View 的布局是一个树形结构,各个 ViewGroup 和 View 是按树形结构嵌套布局的,从而会出现用户触摸的 ...
- 【Visual Leak Detector】源码文件概览
说明 使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记.本篇对 VLD 源码包中的各文件用途做个概述.同系列文章目录可见 <内存泄漏检测工具>目录 目录 说明 1. 整体概览 2. ...
- 去中心化金融-Lec2
Finance Finance is the process that involves the creation, management, and investment of money and f ...
- SpringCloud导入spring boot项目当作子模块微服务IDEA不识别子module问题
1.在父工程下面引入module. <modules> <module>study-design-mode</module> </modules> 2. ...
- .NET开源分布式锁DistributedLock
一.线程锁和分布式锁 线程锁通常在单个进程中使用,以防止多个线程同时访问共享资源. 在我们.NET中常见的线程锁有: 自旋锁:当线程尝试获取锁时,它会重复执行一些简单的指令,直到锁可用 互斥锁: Mu ...
- 「学习笔记」AC 自动机
「学习笔记」AC 自动机 点击查看目录 目录 「学习笔记」AC 自动机 算法 问题 思路 代码 例题 Keywords Search 玄武密码 单词 病毒 最短母串 文本生成器 背单词 密码 禁忌 前 ...
- EasyExcel设置单元格边框
/** * 单元格边框 * @return {@link HorizontalCellStyleStrategy} * @date 2021/10/26 13:22 * @author <a h ...
- 2022-10-23:给你一个整数数组 nums 。如果 nums 的一个子集中, 所有元素的乘积可以表示为一个或多个 互不相同的质数 的乘积,那么我们称它为 好子集 。 比方说,如果 nums =
2022-10-23:给你一个整数数组 nums .如果 nums 的一个子集中, 所有元素的乘积可以表示为一个或多个 互不相同的质数 的乘积,那么我们称它为 好子集 . 比方说,如果 nums = ...
- 云端炼丹,算力白嫖,基于云端GPU(Colab)使用So-vits库制作AI特朗普演唱《国际歌》
人工智能AI技术早已深入到人们生活的每一个角落,君不见AI孙燕姿的歌声此起彼伏,不绝于耳,但并不是每个人都拥有一块N卡,没有GPU的日子总是不好过的,但是没关系,山人有妙计,本次我们基于Google的 ...