一.基本知识
Raw RGB 每个像素只有一种颜色(R、G、B中的一种);
RGB 每个像素都有三种颜色,每一个的值在0~255之间;
在手机摄像头的测试过程中,由sensor输出的数据就是Raw data(Raw RGB),经过彩色插值就变成RGB。
也不一定就是测试过程,想要获得真正的图像,都必须有的一个过程;
sensor输出的数据格式,主要分两种:YUV(比较流行),RGB,这就是sonsor的数据输出;这其中的GRB就是Raw RGB,是sensor的bayer阵列获取的数据(每种传感器获得对应的颜色亮度);
RGB Bayer(CMOS sensor直接输出的数据):
四种不同的格式如下:
二.FPGA代码
1.bayer2RGB模块
module Bayer_RGB #(
parameter ROW_WIDTH = 1920,
parameter COL_WIDTH = 1080
)
(
input I_clk_pixel,
input I_rst_p,
input I_v_sync,//high active
input I_h_sync,//high active -data valid
input [7:0] I_bayer_data,
output O_RGB_data_valid,
output [7:0] O_RGB_data_R,
output [7:0] O_RGB_data_G,
output [7:0] O_RGB_data_B,
output O_v_sync
);
reg v_sync_d1;
reg v_sync_d2;
reg v_sync_d3;
wire v_sync_pos;
reg h_sync_d1;
reg h_sync_d2;
reg h_sync_d3;
wire h_sync_neg;
reg [7:0] bayer_data_d1;
reg [7:0] bayer_data_d2;
reg [7:0] bayer_data_d3;
reg [10:0] row_cnt;
reg [10:0] col_cnt;
wire [7:0] shift_reg1_dout;
wire [7:0] shift_reg2_dout;
reg [7:0] shift_reg2_dout_d1;
reg RGB_data_valid;
reg [7:0] RGB_R;
reg [8:0] RGB_G;
reg [7:0] RGB_B;
always@(posedge I_clk_pixel)
begin
v_sync_d1 <= I_v_sync;
v_sync_d2 <= v_sync_d1;
v_sync_d3 <= v_sync_d2;
h_sync_d1 <= I_h_sync;
h_sync_d2 <= h_sync_d1;
h_sync_d3 <= h_sync_d2;
bayer_data_d1 <= I_bayer_data;
bayer_data_d2 <= bayer_data_d1;
bayer_data_d3 <= bayer_data_d2;
shift_reg2_dout_d1 <= shift_reg2_dout;
end
assign v_sync_pos = v_sync_d1 & (~v_sync_d2);
assign h_sync_neg = (~h_sync_d1) & h_sync_d2;
//=======================================================================cnt
always@(posedge I_clk_pixel or posedge I_rst_p)
begin
if(I_rst_p)
row_cnt <= 11'b0;
else if(v_sync_pos)
row_cnt <= 11'b0;
else if(h_sync_d2)
if(row_cnt == ROW_WIDTH-1 )
row_cnt <= 11'b0;
else
row_cnt <= row_cnt+ 1;
else
row_cnt <= row_cnt;
end
always@(posedge I_clk_pixel or posedge I_rst_p)
begin
if(I_rst_p)
col_cnt <= 11'b0;
else if(v_sync_pos)
col_cnt <= 11'b0;
else if(row_cnt == ROW_WIDTH-1 && h_sync_d2)
col_cnt <= col_cnt+ 1;
else
col_cnt <= col_cnt;
end
//=================GBRG==================================
always@(posedge I_clk_pixel or posedge I_rst_p)
begin
if(I_rst_p)
begin
RGB_R <= 8'b0;
RGB_G <= 8'b0;
RGB_B <= 8'b0;
end
else
case({col_cnt[0],row_cnt[0]})
2'b00:
begin
RGB_R <= shift_reg2_dout_d1;
RGB_G <= (bayer_data_d2 + shift_reg2_dout)>>1;
RGB_B <= bayer_data_d1;
end
2'b01:
begin
RGB_R <= shift_reg2_dout;
RGB_G <= (bayer_data_d1 + shift_reg2_dout_d1)>>1;
RGB_B <= bayer_data_d2;
end
2'b10:
begin
RGB_R <= bayer_data_d2;
RGB_G <= (bayer_data_d1 + shift_reg2_dout_d1)>>1;
RGB_B <= shift_reg2_dout;
end
2'b11:
begin
RGB_R <= bayer_data_d1;
RGB_G <= (bayer_data_d2 + shift_reg2_dout)>>1;
RGB_B <= shift_reg2_dout_d1;
end
default:
begin
RGB_R <= 8'b0;
RGB_G <= 8'b0;
RGB_B <= 8'b0;
end
endcase
end
shift_ram_8x1080 shift_ram_8x1080_inst1 (
.D(bayer_data_d1), // input wire [7 : 0] D
.CLK(I_clk_pixel), // input wire CLK
.CE(h_sync_d1), // input wire CE
.SCLR(I_rst_p), // input wire SCLR
.Q(shift_reg1_dout) // output wire [7 : 0] Q
);
shift_ram_8x840 shift_ram_8x840_inst2 (
.D(shift_reg1_dout), // input wire [7 : 0] D
.CLK(I_clk_pixel), // input wire CLK
.CE(h_sync_d1), // input wire CE
.SCLR(I_rst_p), // input wire SCLR
.Q(shift_reg2_dout) // output wire [7 : 0] Q
);
assign O_RGB_data_valid = h_sync_d3;
assign O_v_sync = v_sync_d3;
//assign O_RGB_data = {RGB_R,RGB_G,RGB_B} ;
assign O_RGB_data_R = RGB_R;
assign O_RGB_data_G = RGB_G[7:0];
assign O_RGB_data_B = RGB_B;
endmodule
2.testbench
module bayer_RGB_matlab_tb(
);
reg I_clk_pixel;
reg I_rst_p;
reg I_v_sync;
reg I_h_sync;
wire [7:0] I_bayer_data;
wire O_RGB_data_valid;
wire [7:0] O_RGB_data_R;
wire [7:0] O_RGB_data_G;
wire [7:0] O_RGB_data_B;
always #5 I_clk_pixel <= ~I_clk_pixel;
initial begin
I_clk_pixel = 0;
I_rst_p = 1;
#10;
I_rst_p = 0;
end
Bayer_RGB
#(
.ROW_WIDTH(1280),
.COL_WIDTH(1024)
)
Bayer_RGB_inst
(
.I_clk_pixel(I_clk_pixel),
.I_rst_p(I_rst_p),
.I_v_sync(I_v_sync),
.I_h_sync(I_h_sync),
.I_bayer_data(I_bayer_data),
.O_RGB_data_valid(O_RGB_data_valid),
.O_RGB_data_R(O_RGB_data_R),
.O_RGB_data_G(O_RGB_data_G),
.O_RGB_data_B(O_RGB_data_B),
.O_v_sync()
);
//=====================input==================================
reg [7:0] mem [1310719:0];
integer fin,number_file_R,number_file_G,number_file_B;
reg [29:0] addr;
initial begin
I_v_sync = 0;
I_h_sync = 0;
addr = 0;
#20;
$readmemh("E:/Matlab_project/bayer/bayer.txt",mem);
#100;
repeat(10) @(posedge I_clk_pixel ) begin I_v_sync = 1;end
repeat(1) @(posedge I_clk_pixel ) begin I_h_sync = 1;end
repeat(1310719) @(posedge I_clk_pixel ) begin I_h_sync = 1; addr = addr+ 1;end
repeat(20) @(posedge I_clk_pixel ) begin I_v_sync = 0;I_h_sync = 0 ; end
end
assign I_bayer_data = mem[addr];
initial begin
number_file_R = $fopen("E:/Matlab_project/bayer/Bayer2Gray_FPGA_R.txt","w");
number_file_G = $fopen("E:/Matlab_project/bayer/Bayer2Gray_FPGA_G.txt","w");
number_file_B = $fopen("E:/Matlab_project/bayer/Bayer2Gray_FPGA_B.txt","w");
repeat(1311000) @(posedge I_clk_pixel)
begin
if(O_RGB_data_valid)
begin
$fwrite(number_file_R,"%d\n",O_RGB_data_R);//注意是$fwrite 而不是$write
$fwrite(number_file_G,"%d\n",O_RGB_data_G);//注意是$fwrite 而不是$write
$fwrite(number_file_B,"%d\n",O_RGB_data_B);//注意是$fwrite 而不是$write
end
end
#10
$display("the image Bayer TO RGB is done!!!\n");
$display("the cost time is %t",$time);
$fclose(number_file_R);//只有$fclose 才可以写进去数据或更改原有数据
$fclose(number_file_G);
$fclose(number_file_B);
end
endmodule
三.Matlab 代码
1.生成仿真文件
clear;
close all;
src = imread('bayer.jpg');
r = src(:,:,1);
g = src(:,:,2);
b = src(:,:,3);
imshow(src);
[m,n,k] = size(src);
N = m*n; %m行,n列
data_lenth = 8; %数据位宽
data_r = reshape(r',1,N); %数字矩阵改为1行N列
% data_g = reshape(g',1,N);
% data_b = reshape(b',1,N);
fin = fopen('bayer.txt','wt');
for i = 1:N
fprintf(fin,'%x\n',data_r(i));
end
fclose(fin);
2.FPGA处理后图像显示
close all;
clear;
n = 1280;
m = 1024;
im = zeros(m,n,3);
im = uint8(im);
Bayer2Gray_FPGA_R = load('Bayer2Gray_FPGA_R.txt');%verilog 产生的灰度图
Bayer2Gray_FPGA_R = reshape(Bayer2Gray_FPGA_R,n,m);
Bayer2Gray_FPGA_R = uint8(Bayer2Gray_FPGA_R');
im(:,:,1) = Bayer2Gray_FPGA_R;
Bayer2Gray_FPGA_G = load('Bayer2Gray_FPGA_G.txt');%verilog 产生的灰度图
Bayer2Gray_FPGA_G = reshape(Bayer2Gray_FPGA_G,n,m);
Bayer2Gray_FPGA_G = uint8(Bayer2Gray_FPGA_G');
im(:,:,2) = Bayer2Gray_FPGA_G;
Bayer2Gray_FPGA_B = load('Bayer2Gray_FPGA_B.txt');%verilog 产生的灰度图
Bayer2Gray_FPGA_B = reshape(Bayer2Gray_FPGA_B,n,m);
Bayer2Gray_FPGA_B = uint8(Bayer2Gray_FPGA_B');
im(:,:,3) = Bayer2Gray_FPGA_B;
imshow(im), title('Image-FPGA')