FPGA数字图像处理基础:色彩空间转换(Verilog)-fpga颜色识别

3.1.3 实现效果分析

通过Matlab显示Verilog处理后的image_out.txt文件:

%**********************************************************************

% ——————————————————————-

% Company: Cascatrix

% Engineer: Carson

%

% Create Date: 2023/02/13

% Design Name: ycbcr_display

% Module Name: ycbcr_display

% Tool Versions: v1.0

% Description: Convert .txt into YCbCr and display image in RGB

%——————————————————————-

%*********************************************************************/

clear;clear all;clc;

% Image resolution

row = 1080;

col = 1920;

n = 3;

% Create output image

image_out = uint8(zeros(row,col,n));

% Write data into output image

FileImage = fopen(image_out.txt,r);

for x = 1:row

for y = 1:col

YCbCr = fscanf(FileImage,%s,1);

image_out(x,y,1) = uint8(hex2dec(YCbCr(1:2)));

image_out(x,y,2) = uint8(hex2dec(YCbCr(3:4)));

image_out(x,y,3) = uint8(hex2dec(YCbCr(5:6)));

end

end

fclose(FileImage);

% Convert YCbCr into RGB

image_out = ycbcr2rgb(image_out);

% Vivado reads image in BGR

image_out = cat(3,image_out(:,:,3),image_out(:,:,2),image_out(:,:,1));

% Show the output image

imshow(image_out),title(Image output);

% Create image in .jpg format

imwrite(image_out,cascatrix_output.jpg);

Matlab图像显示结果:

FPGA数字图像处理基础:色彩空间转换(Verilog)-fpga颜色识别

3.2 RGB生成灰度图像Verilog代码

本节分析基于FPGA实现RGB生成灰度图算法,在Vivado和Matlab联合仿真的基础上,对Verilog转换实现结果在Matlab中展示,验证代码的可行性。

3.2.1 预处理操作

类似于RGB转为YCbCr,由RGB生成灰度图中同样存在小数乘法与加法运算,FPGA不擅长小数处理,因此采用扩大2^n倍后向右移n位进行实现,具体实现方法如下:

RGB生成灰度图算法:

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

将方程扩大256倍后右移8位,算法依然等价:

Gray= 256*(0.299*R + 0.587*G + 0.114*B)>>8

算法推导得:

Gray= (77*R + 150*G + 29*B)>>8

算法转化为FPGA擅长的乘法与移位运算。

3.2.2 Verilog代码

基于Matlab与Verilog联合仿真工程,添加格式转换模块cx_RGB_gray构建顶层top模块,对top进行仿真。

FPGA数字图像处理基础:色彩空间转换(Verilog)-fpga颜色识别

各模块代码如下:

1. 顶层模块 cx_top.v:

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////

// Company: Cascatrix

// Engineer: Carson

//

// Create Date: 2023/02/12

// Design Name: Image_Color_Space

// Module Name: cx_top

// Tool Versions: v1.0

// Description: Covert RGB into YUV(YCbCr) and generate gray value

//

//////////////////////////////////////////////////////////////////////////////////

module cx_top(

input wire clk,

input wire rst_n,

output wireen,

output wirehsyn,

output wirevsyn,

output wire [7:0]gray_data

);

wire [23:0] data;

cx_image inst_cx_image(

.clk(clk),

.hsyn (hsyn),

.vsyn (vsyn),

.en (en ),

.data (data)

);

cx_RGB_gray inst_cx_RGB_gray

(

.clk(clk),

.rst_n (rst_n ),

.rgb_data (data),

.gray_data (gray_data)

);

endmodule

2. 图像文件读取模块 cx_image.v:

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////

// Company: Cascatrix

// Engineer: Carson

//

// Create Date: 2023/02/12

// Design Name: Image_Color_Space

// Module Name: cx_image

// Tool Versions: v1.0

// Description: Covert RGB into YUV(YCbCr) and generate gray value

//

//////////////////////////////////////////////////////////////////////////////////

`define PIXEL_1920_1080

//`define PIXEL_1680_1050

//`define PIXEL_1280_1024

//`define PIXEL_1280_720

//`define PIXEL_1024_768

//`define PIXEL_800_600

//`define PIXEL_640_480

module cx_image(

inputwireclk,

outputreghsyn,

outputregvsyn,

outputwireen,

outputreg [23:0]data

);

//1920×1080 148.5Mhz

`ifdef PIXEL_1920_1080

parameter H_ACTIVE = 1920;// 行数据有效时间

parameter H_FRONT_PORCH = 88; // 行消隐前肩时间

parameter H_SYNC_TIME = 44; // 行同步信号时间

parameter H_BACK_PORCH = 148; // 行消隐后肩时间

parameter V_ACTIVE = 1080;// 列数据有效时间

parameter V_FRONT_PORCH = 4; // 列消隐前肩时间

parameter V_SYNC_TIME = 5; // 列同步信号时间

parameter V_BACK_PORCH = 36; // 列消隐后肩时间

`endif

//1680×1050 119Mhz

`ifdef PIXEL_1680_1050

parameter H_ACTIVE = 1680;// 行数据有效时间

parameter H_FRONT_PORCH = 48; // 行消隐前肩时间

parameter H_SYNC_TIME = 32; // 行同步信号时间

parameter H_BACK_PORCH = 80; // 行消隐后肩时间

parameter V_ACTIVE = 1050;// 列数据有效时间

parameter V_FRONT_PORCH = 3; // 列消隐前肩时间

parameter V_SYNC_TIME = 6; // 列同步信号时间

parameter V_BACK_PORCH = 21; // 列消隐后肩时间

`endif

//1280×1024 108Mhz

`ifdef PIXEL_1280_1024

parameter H_ACTIVE = 1280;// 行数据有效时间

parameter H_FRONT_PORCH = 48; // 行消隐前肩时间

parameter H_SYNC_TIME = 112; // 行同步信号时间

parameter H_BACK_PORCH = 248; // 行消隐后肩时间

parameter V_ACTIVE = 1024;// 列数据有效时间

parameter V_FRONT_PORCH = 1; // 列消隐前肩时间

parameter V_SYNC_TIME = 3; // 列同步信号时间

parameter V_BACK_PORCH = 38; // 列消隐后肩时间

`endif

//1280X720 74.25MHZ

`ifdef PIXEL_1280_720

parameter H_ACTIVE = 1280;// 行数据有效时间

parameter H_FRONT_PORCH = 110; // 行消隐前肩时间

parameter H_SYNC_TIME = 40; // 行同步信号时间

parameter H_BACK_PORCH = 220; // 行消隐后肩时间

parameter V_ACTIVE = 720; // 列数据有效时间

parameter V_FRONT_PORCH = 5; // 列消隐前肩时间

parameter V_SYNC_TIME = 5; // 列同步信号时间

parameter V_BACK_PORCH = 20; // 列消隐后肩时间

`endif

//1024×768 65Mhz

`ifdef PIXEL_1024_768

parameter H_ACTIVE = 1024;// 行数据有效时间

parameter H_FRONT_PORCH = 24; // 行消隐前肩时间

parameter H_SYNC_TIME = 136; // 行同步信号时间

parameter H_BACK_PORCH = 160; // 行消隐后肩时间

parameter V_ACTIVE = 768; // 列数据有效时间

parameter V_FRONT_PORCH = 3; // 列消隐前肩时间

parameter V_SYNC_TIME = 6; // 列同步信号时间

parameter V_BACK_PORCH = 29; // 列消隐后肩时间

`endif

//800×600 40Mhz

`ifdef PIXEL_800_600

parameter H_ACTIVE = 800;// 行数据有效时间

parameter H_FRONT_PORCH = 40 ;// 行消隐前肩时间

parameter H_SYNC_TIME = 128;// 行同步信号时间

parameter H_BACK_PORCH = 88 ;// 行消隐后肩时间

parameter V_ACTIVE = 600;// 列数据有效时间

parameter V_FRONT_PORCH = 1 ;// 列消隐前肩时间

parameter V_SYNC_TIME = 4 ;// 列同步信号时间

parameter V_BACK_PORCH = 23 ;// 列消隐后肩时间

`endif

//640×480 25.175Mhz

`ifdef PIXEL_640_480

parameter H_ACTIVE = 640; // 行数据有效时间

parameter H_FRONT_PORCH = 16 ; // 行消隐前肩时间

parameter H_SYNC_TIME = 96 ; // 行同步信号时间

parameter H_BACK_PORCH = 48 ; // 行消隐后肩时间

parameter V_ACTIVE = 480; // 列数据有效时间

parameter V_FRONT_PORCH = 10 ; // 列消隐前肩时间

parameter V_SYNC_TIME = 2 ; // 列同步信号时间

parameter V_BACK_PORCH = 33 ; // 列消隐后肩时间

`endif

parameter H_TOTAL_TIME = H_ACTIVE + H_FRONT_PORCH + H_SYNC_TIME + H_BACK_PORCH;

parameter V_TOTAL_TIME = V_ACTIVE + V_FRONT_PORCH + V_SYNC_TIME + V_BACK_PORCH;

reg h_act = d0;

reg v_act = d0;

reg [12:0] h_syn_cnt = d0;

reg [12:0] v_syn_cnt = d0;

reg [23:0] dout = d0;

reg [23:0] image [0 : H_ACTIVE*V_ACTIVE-1];

reg [31:0] image_cnt = d0;

assign en = h_act & v_act;

//读取txt文件到image数组中

initial begin

$readmemh(“D:/FPGA_Document/CX_Document/CX_Image /02_Image_color_space/image_src/image_in.txt”, image);

end

// 行扫描计数器

always@(posedge clk)

begin

if(h_syn_cnt == H_TOTAL_TIME-1)

h_syn_cnt <= 13b0;

else

h_syn_cnt <= h_syn_cnt + 1b1;

end

// 列扫描计数器

always@(posedge clk)

begin

if(h_syn_cnt == H_TOTAL_TIME-1)

begin

if(v_syn_cnt == V_TOTAL_TIME-1)

v_syn_cnt <= 13b0;

else

v_syn_cnt <= v_syn_cnt + 1b1;

end

end

// 行同步控制

always@(posedge clk)

begin

if(h_syn_cnt < H_SYNC_TIME)

hsyn <= 1b0;

else

hsyn <= 1b1;

end

// 场同步控制

always@(posedge clk)

begin

if(v_syn_cnt < V_SYNC_TIME)

vsyn <= 1b0;

else

vsyn <= 1b1;

end

always@(posedge clk)

begin

if(v_syn_cnt == V_SYNC_TIME + V_BACK_PORCH – 1 && h_syn_cnt == 0)

v_act = 1b1;

else if(v_syn_cnt == V_SYNC_TIME + V_BACK_PORCH + V_ACTIVE – 1 && h_syn_cnt == 0)

v_act = 1b0;

end

always@(posedge clk)

begin

if(h_syn_cnt == H_SYNC_TIME + H_BACK_PORCH – 1)

h_act = 1b1;

else if(h_syn_cnt == H_SYNC_TIME + H_BACK_PORCH + H_ACTIVE – 1)

h_act = 1b0;

end

always@(posedge clk)

begin

if(h_act & v_act)

image_cnt <= image_cnt + 1b1;

else if(image_cnt == H_ACTIVE*V_ACTIVE – 1)

image_cnt <= 32b0;

end

always@(posedge clk)

begin

if(h_act & v_act)

data <= image[image_cnt][23:0];

else

data <= 24b0;

end

endmodule

3. RGB转gray模块 cx_RGB_gray:

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////

// Company: Cascatrix

// Engineer: Carson

//

// Create Date: 2023/02/12

// Design Name: Image_Color_Space

// Module Name: cx_RGB_gray

// Tool Versions: v1.0

// Description: Covert RGB into YUV(YCbCr) and generate gray value

//

//////////////////////////////////////////////////////////////////////////////////

module cx_RGB_gray(

input wireclk,

input wirerst_n,

inputwire [23:0]rgb_data,

output wire [7:0]gray_data

);

reg [7:0] r;

reg [7:0] g;

reg [7:0] b;

reg [15:0] gray_value;

always@(*)

begin

r <= rgb_data[7:0];

g <= rgb_data[15:8];

b <= rgb_data[23:16];

end

always@(*)

begin

if(!rst_n)

begin

gray_value <= 16d0;

end

else

begin

gray_value <= 77 * r + 150 * g + 29 * b;

end

end

assign gray_data = gray_value[15:8];

endmodule

4. 仿真模块 sim_tb.v:

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////

// Company: Cascatrix

// Engineer: Carson

//

// Create Date: 2023/02/12

// Design Name: Image_Color_Space

// Module Name: top

// Tool Versions: v1.0

// Description: Image output simulation

//

//////////////////////////////////////////////////////////////////////////////////

module sim_tb(

);

reg clk;

reg rst_n;

reg [31:0] pixel_cnt;

wire de;

wire [7:0] data;

integer image_txt;

parameter PIXEL_TOTAL = 1920*1080;

//parameter PIXEL_TOTAL = 1680*1050;

//parameter PIXEL_TOTAL = 1280*1024;

//parameter PIXEL_TOTAL = 1280*720;

//parameter PIXEL_TOTAL = 1024*768;

//parameter PIXEL_TOTAL = 800*600;

//parameter PIXEL_TOTAL = 640*480;

cx_top inst_cx_top

(

.clk (clk ),

.en (de ),

.hsyn ( ),

.vsyn ( ),

.gray_data (data )

);

always #1 clk = ~clk;

initial

begin

clk = 1;

rst_n = 0;

#100

rst_n = 1;

end

initial

begin

image_txt = $fopen(“D:/FPGA_Document/ CX_Document/ CX_Image/02_Image_color_space/image_src/image_out.txt”);

end

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

begin

pixel_cnt <= 0;

end

else if(de)

begin

pixel_cnt = pixel_cnt + 1;

$fwrite(image_txt,”%h “,data);

end

end

always@(posedge clk)

begin

if(pixel_cnt == PIXEL_TOTAL)

begin

$display(“CX: image_out.txt is output completed successfully! %t”, $realtime, “ps”);

$fclose(image_txt);

$stop;

end

end

endmodule

免责声明:文章内容来自互联网,本站不对其真实性负责,也不承担任何法律责任,如有侵权等情况,请与本站联系删除。
转载请注明出处:FPGA数字图像处理基础:色彩空间转换(Verilog)-fpga颜色识别 https://www.yhzz.com.cn/a/4507.html

上一篇 2023-04-11 01:33:21
下一篇 2023-04-11 01:37:56

相关推荐

联系云恒

在线留言: 我要留言
客服热线:400-600-0310
工作时间:周一至周六,08:30-17:30,节假日休息。