im2uint8函数分析
环境:Win7 64位 + Matlab R2010a
本次分析的函数为im2uint8,这个函数在图像处理中要用到,主要把图像数据类转换到uint8
uint8函数有效的输入的图像数据类为:logical,uint8,uint16,double,single和int16
- 如果输入类型为logical,则输入数据为1时转换为255,数据为0还是0。
- 如果输入类型为uint8,则输入数据保持不变。
- 如果输入类型为uint16,则输入数据除以255,然后四舍五入。
- 如果输入数据为double,则输入数据乘以255,小于0的数设置为0,大于255的数设置为255,其他的数四舍五入。
- 如果输入数据为single,处理方式和double一样。
- 如果输入数据为int16,处理暂且没弄清楚。
上面输出的结果根据Matlab提供的M文件进行分析,M文件如下
function u = im2uint8(varargin)
%IM2UINT8 Convert image to 8-bit unsigned integers.
% IM2UINT8 takes an image as input, and returns an image of class uint8. If
% the input image is of class uint8, the output image is identical to it. If
% the input image is not uint8, IM2UINT8 returns the equivalent image of class
% uint8, rescaling or offsetting the data as necessary.
%
% I2 = IM2UINT8(I1) converts the intensity image I1 to uint8, rescaling the
% data if necessary.
%
% RGB2 = IM2UINT8(RGB1) converts the truecolor image RGB1 to uint8, rescaling
% the data if necessary.
%
% I = IM2UINT8(BW) converts the binary image BW to a uint8 intensity image,
% changing one-valued elements to 255.
%
% X2 = IM2UINT8(X1,'indexed') converts the indexed image X1 to uint8,
% offsetting the data if necessary. Note that it is not always possible to
% convert an indexed image to uint8. If X1 is double, then the maximum value
% of X1 must be 256 or less. If X1 is uint16, the maximum value of X1 must be
% 255 or less.
%
% Class Support
% -------------
% Intensity and truecolor images can be uint8, uint16, double, logical,
% single, or int16. Indexed images can be uint8, uint16, double or
% logical. Binary input images must be logical. The output image is uint8.
%
% Example
% -------
% I1 = reshape(uint16(linspace(0,65535,25)),[5 5])
% I2 = im2uint8(I1)
%
% See also IM2DOUBLE, IM2INT16, IM2SINGLE, IM2UINT16, UINT8. % Copyright 1993-2004 The MathWorks, Inc.
% $Revision: 1.20.4.5 $ $Date: 2005/11/15 00:58:23 $ iptchecknargin(1,2,nargin,mfilename); img = varargin{1};
iptcheckinput(img,{'double','logical','uint8','uint16','single','int16'}, ...
{'nonsparse'},mfilename,'Image',1); if nargin == 2
typestr = varargin{2};
iptcheckstrs(typestr,{'indexed'},mfilename,'type',2);
end % 如果图像类型为uint8,则不改变
if isa(img, 'uint8')
u = img; % 如果图像类型为logical(二值),则将1转为255和0仍然为0
elseif isa(img, 'logical')
u=uint8(img);
u(img)=255; else %double, single, uint16, or int16
if nargin == 1 %输入参数个数为1
if isa(img, 'int16') %如果图像类型为int16,则将其转为int16--这是因为grayto8函数不支持int16
img = int16touint16(img);
end % intensity image; call MEX-file
u = grayto8(img); else %输入参数个数为2
if isa(img, 'int16')
eid = sprintf('Images:%s:invalidIndexedImage',mfilename);
msg1 = 'An indexed image can be uint8, uint16, double, single, or ';
msg2 = 'logical.';
error(eid,'%s %s',msg1, msg2); elseif isa(img, 'uint16')
if (max(img(:)) > 255)
msg = 'Too many colors for 8-bit integer storage.';
eid = sprintf('Images:%s:tooManyColorsFor8bitStorage',mfilename);
error(eid,msg);
else
u = uint8(img);
end else %double or single 值范围1-256
if max(img(:)) >= 257
msg = 'Too many colors for 8-bit integer storage.';
eid = sprintf('Images:%s:tooManyColorsFor8bitStorage',mfilename);
error(eid,msg);
elseif min(img(:)) < 1
msg = 'Invalid indexed image: an index was less than 1.';
eid = sprintf('Images:%s:invalidIndexedImage',mfilename);
error(eid,msg);
else
u = uint8(img-1);
end
end
end
end
这其中有个grayto8函数,这个函数在MEX文件中,具体源代码google找了一份,注释了一下
/*
* GRAYTO8 MEX-file
*
* B = GRAYTO8(A) converts the double array A to uint8 by scaling A by 255
* and then rounding. NaN's in A are converted to 0. Values in A greater
* than 1.0 are converted to 255; values less than 0.0 are converted to 0.
*
* B = GRAYTO8(A) converts the uint16 array A by scaling the elements of A
* 255/65535, rounding, and then casting to uint8.
*
* Copyright 1993-2007 The MathWorks, Inc.
*
*/ #include "mex.h"
#include "math.h"
#include "mwsize.h" // double类型转换
void ConvertFromDouble(double *pr, uint8_T *qr, mwSize numElements) {
mwSize k;
double val; for (k = ; k < numElements; k++) {
val = *pr++;
if (mxIsNaN(val)) {
*qr++ = ;
}
else {
val = val * 255.0 + 0.5; // 数据加0.5是为了四舍五入需要 例如 uint8(245.1+0.5)=245 和 uint8(245.6+0.5)=246
if (val > 255.0) val = 255.0;
if (val < 0.0) val = 0.0;
*qr++ = (uint8_T) val;
}
}
} // single类型转换(处理方式和double类型一样)
void ConvertFromSingle(float *pr, uint8_T *qr, mwSize numElements) {
mwSize k;
float val; for (k = ; k < numElements; k++) {
val = *pr++;
if (mxIsNaN(val))
*qr++ = ;
else {
val = val * 255.0f + 0.5f;
if (val > 255.0) val = 255.0;
if (val < 0.0) val = 0.0;
*qr++ = (uint8_T) val;
}
}
} // uint16类型转换
void ConvertFromUint16(uint16_T *pr, uint8_T *qr, mwSize numElements) {
mwSize k;
/*
除以257的原因来自于uint16数字映射到uint8
例如数字x转换到uint8
y = x*255/65535
由于257 = 65535/255,则y=x/257
*/
double factor = 1.0 / 257.0; for (k = ; k < numElements; k++)
*qr++ = (uint8_T) ( (double) (*pr++) * factor + 0.5 );
} void ValidateInputs(int nrhs, const mxArray *prhs[]) {
if (nrhs < ) {
mexErrMsgIdAndTxt("Images:grayto8:tooFewInputs",
"%s","Too few input arguments.");
}
if (nrhs > ) {
mexErrMsgIdAndTxt("Images:grayto8:tooManyInputs",
"%s","Too many input arguments.");
}
if (!mxIsDouble(prhs[]) && !mxIsUint16(prhs[]) && !mxIsSingle(prhs[])) {
mexErrMsgIdAndTxt("Images:grayto8:invalidType",
"%s","Input must be double, single, or uint16.");
}
if (mxIsComplex(prhs[])) {
mexWarnMsgIdAndTxt("Images:grayto8:ignoringImaginaryPartOfInput",
"%s","Ignoring imaginary part of input.");
}
} void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
uint8_T *qr; (void) nlhs; /* unused parameter */ ValidateInputs(nrhs, prhs); plhs[] = mxCreateNumericArray(mxGetNumberOfDimensions(prhs[]),
mxGetDimensions(prhs[]),
mxUINT8_CLASS, mxREAL);
qr = (uint8_T *) mxGetData(plhs[]); if (mxIsDouble(prhs[]))
ConvertFromDouble((double *) mxGetData(prhs[]), qr, mxGetNumberOfElements(prhs[])); else if (mxIsUint16(prhs[]))
ConvertFromUint16((uint16_T *) mxGetData(prhs[]), qr, mxGetNumberOfElements(prhs[])); else
ConvertFromSingle((float *) mxGetData(prhs[]), qr, mxGetNumberOfElements(prhs[])); }
im2uint8函数分析的更多相关文章
- split(),preg_split()与explode()函数分析与介
split(),preg_split()与explode()函数分析与介 发布时间:2013-06-01 18:32:45 来源:尔玉毕业设计 评论:0 点击:965 split()函数可以实 ...
- string函数分析
string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...
- start_amboot()函数分析
一.整体流程 start_amboot()函数是执行完start.S汇编文件后第一个C语言函数,完成的功能自然还是初始化的工作 . 1.全局变量指针r8设定,以及全局变量区清零 2.执行一些类初始化函 ...
- uboot的jumptable_init函数分析
一.函数说明 函数功能:安装系统函数指针 函数位置:common/exports.c 二.函数分析 void jumptable_init (void) { int i; gd->jt = (v ...
- Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析
Linux-0.11内存管理模块是源码中比較难以理解的部分,如今把笔者个人的理解发表 先发Linux-0.11内核内存管理get_free_page()函数分析 有时间再写其它函数或者文件的:) /* ...
- 31.QPainter-rotate()函数分析-文字旋转不倾斜,图片旋转实现等待
在上章和上上上章: 28.QT-QPainter介绍 30.QT-渐变之QLinearGradient. QConicalGradient.QRadialGradient 学习了QPainter基础绘 ...
- 如何验证一个地址可否使用—— MmIsAddressValid函数分析
又是一篇内核函数分析的博文,我个人觉得Windows的内核是最好的老师,当你想实现一个功能之前可以看看Windows内核是怎么做的,说不定就有灵感呢:) 首先看下官方的注释说明: /*++ Routi ...
- STM32F10X固件库函数——串口清状态位函数分析
STM32F10X固件库函数——串口清状态位函数分析 最近在测试串口热插拔功能的时候,意外发现STM32F10X的串口库函数中,清理串口状态位函数稍稍有点不解.下面是改函数的源码: /******** ...
- 常用string函数分析
string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...
随机推荐
- vector-2
assign函数 语法: void assign( input_iterator start, input_iterator end ); void assign( size_type num, co ...
- PAT 65. A+B and C (64bit) (20)
题目链接:http://pat.zju.edu.cn/contests/pat-a-practise/1065 思路分析: 1)对a+b造成的long long 类型的数据溢出进行特殊处理: a> ...
- C# winform 窗体 彻底退出窗体的方法
1.this.Close(); 只是关闭当前窗口,若不是主窗体的话,是无法退出程序的,另外若有托管线程(非主线程),也无法干净地退出: 2.Application.Exit(); 强制所有消 ...
- (转)css中通常会用到浮动与清除,也是一个必须掌握的知识点,概念性的东西不多说,下面举几个例子,来说明它的用法:1.文字环绕效果 2.多个div并排显示 3.清除浮动(默认显示)
一.文字环绕效果: html代码如下: 1 <body> 2 3 <style type="text/css"> 4 #big img {float: le ...
- BufferedReader的ready与readLine使用,以及Premature EOF异常
我的个人主页:http://www.foreyou.net 有些人在读取服务器端返回的数据的时候,使用了BufferedReader类的ready: while(reader.ready()) { / ...
- 优化C#程序的48种方法
一.用属性代替可访问的字段 1..NET数据绑定只支持数据绑定,使用属性可以获得数据绑定的好处: 2.在属性的get和set访问器重可使用lock添加多线程的支持. 二.readonly(运行时常量) ...
- error C2143 & error C4430
错误 1 error C2143: 语法错误 : 缺少“;”(在“*”的前面) 错误 2 error C4430: 缺少类型说明符 - 假定为 int.注意: C++ 不支持默认 int 错误 3 e ...
- impala编译
impala编译 编译系统centos 5.10 说明:版本1.3.x----2.1.x都能编译 一.预装库 1.gcc安装 yum install gcc44 yum install gcc44-c ...
- JSTL解析——003——core标签库02
上一节主要讲解了<c:if/><c:choose/><c:when/><c:otherwise><c:out/>标签的使用,下面继续讲解其它 ...
- Linux入门基础 #8:Linux拓展权限
本文出自 http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...