彩色图像灰度化 (RGB ⇒ Gray )(RGB ⇒ YUV)(Verilog)

简介:

        把一个彩色图像,也称为 RGB(红,绿,蓝)图像转化为灰度图像的行为称为彩色图像灰度化处理。也就是由原来的三个通道 RGB 转化为一个通道 YCrCb(从三个亮度值转换为一个亮度值), 也即 YUV(亮度,饱和度)的过程。常见的 24 位深度彩色图像 RGB888 中的每个像素的颜色由 R、G、B 三个分量决定,并且三个分量各占 1 个字节,每个分量的变化范围是 0~255。而灰色图像是一种特殊的彩色图像,其一个像素点的变化范围是 0~255,所以在进行图像处理的过程中,用灰度图像会比 RGB 图像少了很多计算量。想要进行彩色图像灰度化处理,有 4 种方法,以下会一一讲解。

加权平均法:

        这也是彩色图像灰度化处理最常用的一种方法,其原理是将三个分量以不同的权值进行加权平均,其公式为

gray( i , j ) = 0.299 * R( i , j ) + 0.587 * G( i , j ) + 0.114 * B( i , j )

        这里 0.299 + 0.587 + 0.114 = 1 ,这里刚好是满偏,这是通过不同的敏感度以及经验总结出来的公式。 在 Verilog 进行编写的过程中,为了能减少浮点运算以及除法运算导致运行速度过慢,在实现的过程中一般都是先扩大 1024 倍再缩小 1024倍来实现算法,如:

gray( i , j ) = [0.299 * R( i , j ) + 0.587 * G( i , j ) + 0.114 * B( i , j )] * 1024/1024

也即  

gray( i , j ) \approx [306 * R( i , j ) + 601 * G( i , j ) + 117 * B( i , j )] / 1024

因为 1024 是 2 的  10 次幂(这里只需要是 2 的 n 次幂就可以),所以可以采用移位寄存器的方法来处理。

 gray( i , j ) \approx [306 * R( i , j ) + 601 * G( i , j ) + 117 * B( i , j )] >> 10

最大值法: 

        将彩色图像中的三个彩色分量 R,G,B 的最大值作为灰度图的灰度值。具体表达式如下。

 gray(i, j) = max[ R( i , j ),G(i,j),B(i,j)]

        这个方法相比于上一个方法就比较简单了,最后的结果可能会略有偏差。

分量法:

        将彩色图像中的三分量的亮度作为三个灰度图像的灰度值,可根据应用需要选取一种灰度图像。具体表达式如下。

gray_{1}(i,j) = R(i,j)

gray_{2}(i,j) = G(i,j)

gray_{3}(i,j) = B(i,j)

        gray1 ( i , j ), gray2 ( i , j ), gray3 ( i , j ) 为转换后的灰度图像在( i , j )处的灰度值, R( i , j ),G( i , j ),B( i , j ) 分别为转换前的彩色图像在( i , j )处 R、G、B 三个分量的值。 

平均值法:

        将彩色图像中的三分量的亮度求平均得到一个灰度值。如下:

gray( i , j ) = \frac{R( i , j ) + G( i , j ) + B( i , j )}{3}

RGB 与 YUV 相互转换:

RGB ⇒ YUV

Y = 0.299 * R + 0.587 * G + 0.114 * B

U = – 0.1687 * R – 0.3313 * G + 0.5 * B +128

V = 0.5 * R – 0.4187 * G – 0.0813 * B +128

Y ≈ (( 77 * R + 150 * G + 29 * B ) >> 8)

U ≈ (( -43 * R – 85 * G + 128 * B ) >> 8) + 128

V ≈ (( 128 * R – 107 * G – 21 * B ) >> 8) + 128

Y ≈ (( 77 * R + 150 * G + 29 * B ) >> 8)

U ≈ (( -43 * R – 85 * G + 128 * B  + 32768 ) >> 8) 

V ≈ (( 128 * R – 107 * G – 21 * B + 32768 ) >> 8) 

        最后的公式可以避免在运算过程中产生的有符号数对结果产生影响。移位操作可以将 16 位寄存器的高八位直接赋给所需输出的 Y 、U 、V 信号,这样能不消耗更多的逻辑。

        在实现算法的过程中,我们可以先设计三个阶段实现这个公式,第一个阶段是把系数乘法,也就是把如 ( 77 * R )、( 150 * G ) 的结果算出来,第二个阶段是把第一阶段算出来的结果加在一起,第三个阶段是把所得到数据的高八位赋给输出的 Y 、U 、V 信号,也就是移位运算。总结一下就是第一个阶段算乘法,第二个阶段算加法,第三个阶段进行移位操作。

YUV ⇒ RGB

 R = Y + 1.402 * ( V – 128 )

G = Y – 0.34414 * ( U – 128 ) – 0.71414 * ( V – 128 )

 B = Y + 1.772 * ( U – 128 )

 R ≈ ( 256 * Y + 359 * V – 45940 ) >> 8

G ≈ ( 256 * Y – 88 * U – 183 * V + 34678 ) >> 8 

 B ≈ ( 256 * Y + 454 * U – 58065 ) >> 8

        这里为了实现 YUV ⇒ RGB 我们设定了 4 个阶段,前三个阶段与 RGB ⇒ YUV 相同,第四个阶段就是要判断最后算出来的 R 、G 、B 信号是否是负数,是否大于 255 ( R 、G 、B 是 8 bit),如果是负数,则将其直接赋值为 0 ,如果大于 255 就将其直接赋值为 255 。写代码判断时,可以用三目运算符,先判断是不是负数,在判断是不是大于 255 。判断大于 255 这个环节,可以把赋值的寄存器比输出信号高一位,判断最高位(也就是第 9 位)为 1 ,则该结果大于 255 。

        上述方法实现转换所占用的资源较多(乘法器所占资源较大,且在多位乘法中会出现时钟延时)。为了节省资源,我们可以选用向左移位的方式来计算乘法(左移 n 位即乘上2^n),例如:77 * R 可以写成 (R << 6) + (R << 3) + (R << 2) + R 的方式,用移位寄存器代替乘法器,从而节省资源以及乘法器可能带来的时间延时。

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2023年12月7日
下一篇 2023年12月7日

相关推荐