环境: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函数分析的更多相关文章

  1. split(),preg_split()与explode()函数分析与介

    split(),preg_split()与explode()函数分析与介 发布时间:2013-06-01 18:32:45   来源:尔玉毕业设计   评论:0 点击:965 split()函数可以实 ...

  2. string函数分析

    string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...

  3. start_amboot()函数分析

    一.整体流程 start_amboot()函数是执行完start.S汇编文件后第一个C语言函数,完成的功能自然还是初始化的工作 . 1.全局变量指针r8设定,以及全局变量区清零 2.执行一些类初始化函 ...

  4. uboot的jumptable_init函数分析

    一.函数说明 函数功能:安装系统函数指针 函数位置:common/exports.c 二.函数分析 void jumptable_init (void) { int i; gd->jt = (v ...

  5. Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析

    Linux-0.11内存管理模块是源码中比較难以理解的部分,如今把笔者个人的理解发表 先发Linux-0.11内核内存管理get_free_page()函数分析 有时间再写其它函数或者文件的:) /* ...

  6. 31.QPainter-rotate()函数分析-文字旋转不倾斜,图片旋转实现等待

    在上章和上上上章: 28.QT-QPainter介绍 30.QT-渐变之QLinearGradient. QConicalGradient.QRadialGradient 学习了QPainter基础绘 ...

  7. 如何验证一个地址可否使用—— MmIsAddressValid函数分析

    又是一篇内核函数分析的博文,我个人觉得Windows的内核是最好的老师,当你想实现一个功能之前可以看看Windows内核是怎么做的,说不定就有灵感呢:) 首先看下官方的注释说明: /*++ Routi ...

  8. STM32F10X固件库函数——串口清状态位函数分析

    STM32F10X固件库函数——串口清状态位函数分析 最近在测试串口热插拔功能的时候,意外发现STM32F10X的串口库函数中,清理串口状态位函数稍稍有点不解.下面是改函数的源码: /******** ...

  9. 常用string函数分析

    string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...

随机推荐

  1. C++中的cout输出机制

    代码: #include <iostream> using namespace std; int hello(){ cout<<"hello"<< ...

  2. Jasper_table_resolve get multiple copies of table in detail band issue

    resolve method: (1) put table component into the Title band / Page Header band / Summary band, not i ...

  3. (摘) MDI登陆问题

    MDI编程中需要验证用户身份,那么登陆窗口就需要在验证密码后进行相关的隐藏处理. (1)隐藏登陆窗口(登陆窗体作为启动) 登陆按钮事件:this.Hide();//隐藏登陆窗口MDI_Name M = ...

  4. 完美解决ListView 与 ScrollView 共存问题

    1:首先设置ListView的高度,在setAdapter之后调用此方法. public static void setListViewHeightBasedOnChildren(ListView l ...

  5. AJAX实例入门

    一.开门见山 这些时间,瞎子也看得见,AJAX正大踏步的朝我们走来.不管我们是拥护也好,反对也罢,还是视而不见,AJAX像一阵潮流,席转了我们所有的人. 关于AJAX的定义也好,大话也好,早有人在网上 ...

  6. What’s the difference between an interface and an abstract class in Java?

    原文 What’s the difference between an interface and an abstract class in Java? It’s best to start answ ...

  7. JAX-WS 学习二:基于WEB容器,发布WebService

    WebService 的发布通过调用 Endpoint.publish() 方法来启动一个java内嵌的WEB容器来实现的,如果要将WebService部署到一个WEB容器中去,需要使用jax-ws提 ...

  8. 【转】第一个MiniGUI程序:模仿QQ界面

    最近几天在学MiniGui,最好的学习方法就是实践,先写个练练笔.其实只是一个界面,不知道什么时候才能真正写个完整的程序.初次写GUI程序,感觉写得不好,还请高手来指教. //============ ...

  9. 【转】ffmpeg中的sws_scale算法性能测试

    经常用到ffmpeg中的sws_scale来进行图像缩放和格式转换,该函数可以使用各种不同算法来对图像进行处理.以前一直很懒,懒得测试和甄别应该使用哪种算法,最近的工作时间,很多时候需要等待别人.忙里 ...

  10. (转)Apache+Tomcat集群配置

    本文Apache+Tomcat集群配置 基于最新的Apache和Tomcat,具体是2011年4月20日最新的Tomcat和Apache集群和负载均衡配置. 准备环境 Apache Apache是ht ...