FPGA实现RGB与HSV的转换

RGB到HSV的转换公式为

在这里插入图片描述

由于s的范围是0到1,所以用verilog实现时,将s扩大256倍,容易表示,当然会丢失精度,其次,这里用到许多除法,笔者用的工具可以直接综合除法,所以这里没有例化除法器,当然,例化除法器ip核也是一样的效果。

实现代码如下:

module rgb2hsv(
input clk,
input reset_n,
input [7:0]rgb_r,
input [7:0]rgb_g,
input [7:0]rgb_b,
input vs,
input hs,
input de,
output [8:0]hsv_h,
output [8:0]hsv_s,
output [7:0]hsv_v,
output hsv_vs,
output hsv_hs,
output hsv_de);


reg [7:0]max;
reg	[7:0]min;
reg	[13:0]rgb_r_r;
reg	[13:0]rgb_g_r;
reg	[13:0]rgb_b_r;

reg [13:0]rgb_r_r2;
reg	[13:0]rgb_g_r2;
reg	[13:0]rgb_b_r2;
reg	[7:0]max_r;

wire [7:0]max_min;
assign	max_min=max-min;
reg  [7:0]max_min_r;
wire [13:0]max60;
assign max60=max*60;

wire [13:0] g_b;
wire [13:0] b_r;
wire [13:0] r_g;
assign	g_b=(rgb_g_r>=rgb_b_r)?(rgb_g_r-rgb_b_r):(rgb_b_r-rgb_g_r);
assign  b_r=(rgb_b_r>=rgb_r_r)?(rgb_b_r-rgb_r_r):(rgb_r_r-rgb_b_r);
assign  r_g=(rgb_r_r>=rgb_g_r)?(rgb_r_r-rgb_g_r):(rgb_g_r-rgb_r_r);


reg [13:0]temp;
reg	[13:0]hsv_h_r;
reg	[15:0]hsv_s_r;
reg	[7:0]hsv_v_r;


always@(posedge clk or negedge reset_n)begin
	if(!reset_n)begin
		rgb_r_r<=0;
		rgb_g_r<=0;
		rgb_b_r<=0;
	end
	else begin
		rgb_r_r<=60*rgb_r;
        rgb_g_r<=60*rgb_g;
        rgb_b_r<=60*rgb_b;
	end
end	

always@(posedge clk or negedge reset_n)begin
	if(!reset_n)begin
		rgb_r_r2<=0;
        rgb_g_r2<=0;
	    rgb_b_r2<=0;
	end
	else begin
		rgb_r_r2<=rgb_r_r;
	    rgb_g_r2<=rgb_g_r;
	    rgb_b_r2<=rgb_b_r;
	end
end
	
always@(posedge clk or negedge reset_n)begin
	if(!reset_n)
		max<=0;
	else if((rgb_r>=rgb_b)&&(rgb_r>=rgb_g))
		max<=rgb_r;
	else if((rgb_g>=rgb_b)&&(rgb_g>=rgb_r))
		max<=rgb_g;
	else if((rgb_b>=rgb_r)&&(rgb_b>=rgb_g))
		max<=rgb_b;
end

always@(posedge clk or negedge reset_n)begin
	if(!reset_n)
		min<=0;
	else if((rgb_r<=rgb_b)&&(rgb_r<=rgb_g))
		min<=rgb_r;
	else if((rgb_g<=rgb_b)&&(rgb_g<=rgb_r))
		min<=rgb_g;
	else if((rgb_b<=rgb_r)&&(rgb_b<=rgb_g))
		min<=rgb_b;
end

always@(posedge clk or negedge reset_n)begin
	if(!reset_n)
		max_min_r<=0;
	else
		max_min_r<=max_min;
end

always@(posedge clk or negedge reset_n)begin
	if(!reset_n)
		temp<=0;
	else if(max_min!=0)begin
		if(rgb_r_r==max60)
			temp<=g_b/{6'b0,max_min};
		else if(rgb_g_r==max60)
			temp<=b_r/{6'b0,max_min};
		else if(rgb_b_r==max60)
			temp<=r_g/{6'b0,max_min};
	end
	else if(max_min==0)
		temp<=0;
end

always@(posedge clk or negedge reset_n)begin
	if(!reset_n)
		max_r<=0;
	else
		max_r<=max;
end

always@(posedge clk or negedge reset_n)begin
	if(!reset_n)
		hsv_h_r<=0;
	else if(max_r==0)
		hsv_h_r<=0;
	else if(rgb_r_r2==60*max_r)
		hsv_h_r<=(rgb_g_r2>=rgb_b_r2)?temp:(14'd360-temp);
	else if(rgb_g_r2==60*max_r)
		hsv_h_r<=(rgb_b_r2>=rgb_r_r2)?(temp+120):(14'd120-temp);
	else if(rgb_b_r2==60*max_r)
		hsv_h_r<=(rgb_r_r2>=rgb_g_r2)?(temp+240):(14'd240-temp);
end

always@(posedge clk or negedge reset_n)begin
	if(!reset_n)
		hsv_s_r<=0;
	else if(max_r==0)
		hsv_s_r<=0;
	else
		hsv_s_r<={max_min_r,8'b0}/{8'b0,max_r};
end


always@(posedge clk or negedge reset_n)begin
	if(!reset_n)
		hsv_v_r<=0;
	else
		hsv_v_r<=max_r;
end
	
reg [2:0]vs_delay;
reg	[2:0]hs_delay;
reg	[2:0]de_delay;

	
always@(posedge clk or negedge reset_n)begin
	if(!reset_n)begin
		vs_delay<=0;
        hs_delay<=0;
        de_delay<=0;
	end
	else begin
		vs_delay <= { vs_delay[1:0],vs};
        hs_delay <= { hs_delay[1:0],hs};
        de_delay <= { de_delay[1:0],de};
	end
end

assign hsv_vs=vs_delay[2];
assign hsv_hs=hs_delay[2];
assign hsv_de=de_delay[2];

assign hsv_h=hsv_h_r[8:0];
assign hsv_s=hsv_s_r[8:0];
assign hsv_v=hsv_v_r;

endmodule

HSV到RGB的转换公式:
在这里插入图片描述

实现代码:

module hsv2rgb(
input clk,
input reset_n,
input [8:0]i_hsv_h,
input [8:0]i_hsv_s,
input [7:0]i_hsv_v,
input vs,
input hs,
input de,
output [7:0]rgb_r,
output [7:0]rgb_g,
output [7:0]rgb_b,
output rgb_vs,
output rgb_hs,
output rgb_de

);


reg [7:0]i_hsv_v_r1;
reg [7:0]i_hsv_v_r2;
reg [7:0]i_hsv_v_r3;
reg [7:0]i_hsv_v_r4;
reg [8:0]i_hsv_h_r;
reg [8:0]i_hsv_s_r1;
reg [8:0]i_hsv_s_r2;
reg [8:0]i_hsv_s_r3;
reg [8:0]i_hsv_s_r4;

wire [8:0]temp;
assign temp=9'd256-i_hsv_s;

reg [16:0] p;//p=V-V*S,,扩大256
reg [7:0] p2;
reg [7:0]p3;
reg [2:0]I;//H/60的商
reg [2:0]I2;
reg [2:0]I3;
wire [5:0]f;//H/60的余数
assign f=i_hsv_h_r-I*60;
reg [15:0]f_60;

reg [15:0]adjust;



always@(posedge clk or negedge reset_n)begin
if(!reset_n)begin
i_hsv_v_r1 <= 0;
i_hsv_v_r2 <= 0;
i_hsv_v_r3<=0;
i_hsv_v_r4<=0;
end
else begin
i_hsv_v_r1<=i_hsv_v;
i_hsv_v_r2<=i_hsv_v_r1;
i_hsv_v_r3<=i_hsv_v_r2;
i_hsv_v_r4<=i_hsv_v_r3;
end
end

always@(posedge clk or negedge reset_n)begin
if(!reset_n)
i_hsv_h_r<=0;
else
i_hsv_h_r<=i_hsv_h;
end

always@(posedge clk or negedge reset_n)begin
if(!reset_n)begin
i_hsv_s_r1<=0;
i_hsv_s_r2<=0;
i_hsv_s_r3<=0;
i_hsv_s_r4<=0;
end
else begin
i_hsv_s_r1<=i_hsv_s;
i_hsv_s_r2<=i_hsv_s_r1;
i_hsv_s_r3<=i_hsv_s_r2;
i_hsv_s_r4<=i_hsv_s_r3;
end
end

always@(posedge clk or negedge reset_n)begin
if(!reset_n)begin
p<=0;
p2<=0;
p3<=0;
end
else begin
p<=temp*i_hsv_v;
p2<=p[15:8];
p3<=p2;
end
end

always@(posedge clk or negedge reset_n)begin
if(!reset_n)
I<=0;
else if(i_hsv_h<60)
I<=0;
else if((i_hsv_h<120)&&(i_hsv_h>=60))
I<=1;
else if((i_hsv_h<180)&&(i_hsv_h>=120))
I<=2;
else if((i_hsv_h<240)&&(i_hsv_h>=180))
I<=3;
else if((i_hsv_h<300)&&(i_hsv_h>=240))
I<=4;
else
I<=5;
end

always@(posedge clk or negedge reset_n)begin
if(!reset_n)begin
I2<=0;
I3<=0;
end
else begin
I2<=I;
I3<=I2;
end
end


always@(posedge clk or negedge reset_n)begin
if(!reset_n)
f_60<=0;
else
f_60<={f,8'b0}/60;
end

always@(posedge clk or negedge reset_n)begin
if(!reset_n)
adjust<=0;
else
adjust<=(i_hsv_v_r2-p2)*f_60[7:0];
end


/**************************************/
reg [7:0]rgb_r_r;
reg [7:0]rgb_g_r;
reg [7:0]rgb_b_r;

reg [3:0]vs_delay;
reg [3:0]hs_delay;
reg [3:0]de_delay;

always@(posedge clk or negedge reset_n)begin
if(!reset_n)begin
rgb_r_r<=0;
rgb_g_r<=0;
rgb_b_r<=0;
end
else case(I3)
0: begin
rgb_r_r<=i_hsv_v_r3;
rgb_g_r<=p3+adjust[15:8];
rgb_b_r<=p3;
end

1: begin
rgb_r_r<=i_hsv_v_r3-adjust[15:8];
rgb_g_r<=i_hsv_v_r3;
rgb_b_r<=p3;
end

2: begin
rgb_r_r<=p3;
rgb_g_r<=i_hsv_v_r3;
rgb_b_r<=p3+adjust[15:8];
end

3: begin
rgb_r_r<=p3;
rgb_g_r<=i_hsv_v_r3-adjust[15:8];
rgb_b_r<=i_hsv_v_r3;
end

4: begin
rgb_r_r<=p3+adjust[15:8];
rgb_g_r<=p3;
rgb_b_r<=i_hsv_v_r3;
end

5: begin
rgb_r_r<=i_hsv_v_r3;
rgb_g_r<=p3;
rgb_b_r<=i_hsv_v_r3-adjust[15:8];
end

default: begin
rgb_r_r<=0;
rgb_g_r<=0;
rgb_b_r<=0;
end
endcase
end

always@(posedge clk or negedge reset_n)begin
if(!reset_n)begin
vs_delay<=0;
hs_delay<=0;
de_delay<=0;
end
else begin
vs_delay<={vs_delay[2:0],vs};
hs_delay<={hs_delay[2:0],hs};
de_delay<={de_delay[2:0],de};
end
end

assign rgb_r = (i_hsv_s_r4==0)?i_hsv_v_r4:rgb_r_r;
assign rgb_g = (i_hsv_s_r4==0)?i_hsv_v_r4:rgb_g_r;
assign rgb_b = (i_hsv_s_r4==0)?i_hsv_v_r4:rgb_b_r;

assign rgb_vs = vs_delay[3];
assign rgb_hs = hs_delay[3];
assign rgb_de = de_delay[3];

endmodule

参考文献:

[1]袁奋杰, 周晓, 丁军,等. 基于FPGA的RGB和HSV色空间转换算法实现[J]. 电子器件, 2010, 33(4):5.

  • 11
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值