在进行计算操作时,常常要涉及到取整操作。我所做的工作大部分跟图像处理相关,我们知道,pixel value都是整数,在涉及到小数的计算时(比如直方图操作),往往要使用取整方法。
Matlab中取整函数有以下4个:fix, ceil, floor, round,取整函数可对单个数据或者矩阵作处理。
-
Fix
Round toward zero,意思是向0的方向取整
-
Ceil
Round toward positive infinity 朝正无穷大方向取整
-
Floor
Round toward negative infinity 朝负无穷大方向取整
-
Round
Round to nearest decimal or integer 朝最接近的整数取整
算法在硬件化(比如FPGA)实现时,往往使用定点化操作,定点化的核心思想如下,假如要实现a * 0.3的操作,那么我们可以先计算a * 3,结果再除上10,便完成了a * 0.3的定点化。
下面举个图像处理的例子来细说定点化,比如图像处理中常见的颜色空间转换,实际上转换系数都是浮点数,BT601色域下RGB转YCbCr公式如下:
Y = 0.2568 * R + 0.5041 * G + 0.0979 * B + 16
Cb = -0.1482 * R – 0.291 * G + 0.4392 * B + 128
Cr = 0.4392 * R – 0.3678 * G – 0.0714 * B + 128
顺便说一下,matlab中rgb2ycbcr函数也是用的上面的公式来实现的,接下来说转换矩阵,不考虑后面加16和128。
BT601RGB2YCbCr = [
0.2568 0.5041 0.0979
-0.1482 -0.2910 0.4392
0.4392 -0.3678 -0.0714]
8bit定点化时,相当于乘上256,矩阵如下
BT601RGB2YCbCr_8bit = [
65.7408 129.0496 25.0624
-37.9392 -74.4960 112.4352
112.4352 -94.1568 -18.2784]
经过定点化处理,使用round函数,朝最近的整数方向取整,得到
BT601RGB2YCbCr_fix8bit = round(BT601RGB2YCbCr_fix) = [
66 129 25
-38 -74 112
112 -94 -18]
我们做如下实现:
Y = (66 * R + 129 * G + 25 * B + 128) >> 8 + 16
Cb = (-38 * R – 74 * G + 112 * B + 128) >> 8 + 128
Cr = (112 * R – 94 * G – 18 * B + 128) >> 8 + 128
括号中加128等价于在浮点操作下加上0.5,主要是因为硬件计算时会朝比自己小的方向取整,所以加上0.5,实际上是对原始数据完成四舍五入。
硬件里面做完处理,最后右移8位,然后Y分量加上16,Cb、Cr分量加上128,即可得到转换后的YCbCr分量的值。