学习文章:https://www.cnblogs.com/xianyufpga/p/12408988.html
一、实战原理:
将彩色图像灰度化的方法有两种:一种就是实战4中RGB分量转灰度,另一种是转化为YCbCr格式,将Y分量提取出来,YCbCr格式中的Y分量表示的是图像的亮度和浓度,所以只输出Y分量,得到的图像就是灰度图像了。这里实现的是第二种方法:RGB565转RGB888,再转YCbCr444,最后取YCbCr的Y分量即可得到灰度图像。
YCbCr是通过有序的三元组来表示的,三元由Y(Luminance)、Cb(Chrominance-Blue)和Cr(Chrominance-Red)组成,其中Y表示颜色的明亮度和浓度,而Cb和Cr则分别表示颜色的蓝色浓度偏移量和红色浓度偏移量。人的肉眼对由YCbCr色彩空间编码的视频中的Y分量更敏感,而Cb和Cr的微小变化不会引起视觉上的不同。根据该原理,通过对Cb和Cr进行子采样来减小图像的数据量,使得图像对存储需求和传输带宽的要求大大减低,从而达到在完成图像压缩的同时也保证了视觉上几乎没有损失的效果,进而使得图像的传输速度更快,存储更加方便。我们要得到灰度图像,首先要将采集到的彩色图像转化为YCbCr。
由于本次实验的图片是RGB565格式,因此需要转换成RGB888格式(RGB888就是R-8bit,G-8bit,B-8bit)。
二、matlab实现:
由于matlab中本来就是RGB888格式,因此只需考虑RGB888格式转YCbCr444。
两者转换公式:
Y=0.299R+0.587G+0.114B
Cb=0.568(B-Y)+128=-0.172R-0.339G+0.511B+128
Cr=0.713(R-Y)+128=0.511R-0.428G-0.083B+128
代码设计:
%-------------------------------------------------------------------------- % RGB转YCbCr取Y值转灰度图 %-------------------------------------------------------------------------- clc; clear all; RGB = imread('G:image.jpg'); %读取图像 R = RGB(:,:,1); %R分量 G = RGB(:,:,2); %G分量 B = RGB(:,:,3); %B分量 [ROW,COL,N] = size(RGB); %获得图像尺寸[高度,长度,维度] for r = 1:ROW for c = 1:COL Y(r,c) = 0.299*R(r,c) + 0.587*G(r,c) + 0.114*B(r,c); Cb(r,c) = -0.172*R(r,c) - 0.339*G(r,c) + 0.511*B(r,c) + 128; Cr(r,c) = 0.511*R(r,c) - 0.428*G(r,c) - 0.083*B(r,c) + 128; end end subplot(2,2,1);imshow(R);title('R分量灰度图'); subplot(2,2,2);imshow(G);title('G分量灰度图'); subplot(2,2,3);imshow(B);title('B分量灰度图'); subplot(2,2,4);imshow(Y);title('Y分量灰度图');
原图:
效果:
三、Verilog实现:
由于图片格式RGB565,因此需要转成RGB888格式:
再将RGB888转换成YCbCr:
Y=0.299R+0.587G+0.114B
Cb=0.568(B-Y)+128=-0.172R-0.339G+0.511B+128
Cr=0.713(R-Y)+128=0.511R-0.428G-0.083B+128
公式实现先乘以256,后右移8位。分三步:
①计算乘法
②计算加减法
③除以256
接着,因为前面三步为了将Y分量提出出来,延迟了三个clk,因此要对同步信号和使能信号也进行延迟三个clk。
出现问题:Y分量灰度图实现了,但是不知道为什么跟其他分量灰度图按键切换的时候,图片位置会变动?