rgb转hsv (Verilog)

rgb色彩空间对人的友好性远不及hsv色彩空间,在hsv空间,我们可以容易区分不同颜色,可以将亮度信息与颜色信息分离开来,也可以单纯增强图像色彩的饱和度,比如让花瓣更红更饱满。hsv在彩色边缘分割也大有用处,传统的边缘提取都是依靠灰度信息,其实灰度图往往只能保留90%的边缘信息,剩余的10%是无法体现出来的。这就需要彩色边缘分割来进行补充,标量的梯度就自然而然转为向量的梯度(rgb/hsv/hsi)。
先给出rgb 转 hsv 公式

在这里插入图片描述在这里插入图片描述在这里插入图片描述

可以借助quartus 自带的颜色选择来观察HSV 与 RGB之间的关系。
(Tools -> Options -> Colors)
彩色边缘应用的注意点
{
从图中观察到红色最为特殊,它是0°线的左右两方区域,这里容易出错,如果你求hs分量的欧式距离,那么红色的距离会一大一小分两端。解决办法可以让 h <10 范围的值转化成 360 - h 。(10是估计值)
还需要注意饱和度 S ,饱和度和掺杂白光的程度成反比,对于饱和度S < 30,亮度 V > 220 统一认为是白色。
亮度 V < 46 的所有颜色统一认为是黑色。

}
RGB转HSV的检测结果经过验证和软件里的高度一致

module  rgb_hsv(
	input                         clk,
	input                       	rst,	
	input	     [7:0]            rgb_r,
	input	     [7:0]            rgb_g,
	input	     [7:0]            rgb_b,	
	output reg [8:0] 			  hsv_h,//  0 - 360
	output reg [7:0] 			  hsv_s,// 0- 255
	output reg [7:0] 			  hsv_v // 0- 255

	
);

reg [7:0] top;//分子
reg [13:0] top_60;//*60
reg [2:0] rgb_se;
reg [2:0] rgb_se_n;//方向
reg [7:0] max;//最大分量
reg [7:0] min;//最小分量
reg [7:0] max_min;//max - min
reg [7:0] hsv_s_m;
reg [7:0] max_n;
reg [7:0] division;//除法

//find max min 1----
assign r_g = (rgb_r > rgb_g)? 1'b1:1'b0; 
assign r_b = (rgb_r > rgb_b)? 1'b1:1'b0; 
assign g_b = (rgb_g > rgb_b)? 1'b1:1'b0; 
always @ (posedge clk or negedge rst)
begin
	if (!rst)
	begin
		max <= 8'd0;
		min <= 8'd0;
		top <= 8'd0;
		rgb_se <= 3'b010;
	end
	else 
	begin
	case ({r_g,r_b,g_b})
	
	3'b000:
			begin//b g r
			max <= rgb_b;
			min <= rgb_r;
			top <= rgb_g - rgb_r;//-
			rgb_se <= 3'b000;
			end
	3'b001:
			begin//g b r
			max <= rgb_g;
			min <= rgb_r;
			top <= rgb_b - rgb_r;//+
			rgb_se <= 3'b001;
			end
	3'b011:
			begin//g r b
			max <= rgb_g;
			min <= rgb_b;
			top <= rgb_r - rgb_b;//-
			rgb_se <= 3'b011;
			end
	3'b100:
			begin//b r g
			max <= rgb_b;
			min <= rgb_g;
			top <= rgb_r - rgb_g;//+
			rgb_se <= 3'b100;
			end
	3'b110:
			begin//r b g
			max <= rgb_r;
			min <= rgb_g;
			top <= rgb_b - rgb_g;//+
			rgb_se <= 3'b110;
			end
	3'b111:
			begin//r g b
			max <= rgb_r;
			min <= rgb_b;
			top <= rgb_g - rgb_b;//-
			rgb_se <= 3'b111;
			end
	default
			begin
			max <= 8'd0;
			min <= 8'd0;
			top <= 8'd0;
			rgb_se <= 3'b010;
			end
	endcase
end
end
// *60   max - min          2-----------------
always @ (posedge clk or negedge rst)
begin
	if (!rst)
		begin
		top_60 <= 14'd0;
		rgb_se_n <= 3'b010;
		max_min <= 8'd0;
		max_n <= 8'd0;
		end
	else
		begin
		top_60 <= {top,6'b000000} - {top,2'b00};//60 = 2^6 - 2^2
		rgb_se_n <= rgb_se;
		max_min <= max - min;
		max_n <= max;
		end
end
//   /(max - min)    3----------------------
always @ (*)
begin
	division = (max_min > 8'd0) ? top_60 / max_min : 8'd240;//注意max = min  
end
// + - 120 240 360
always @ (posedge clk or negedge rst)
begin
	if (!rst)
	
		hsv_h <= 9'd0;
	
	else 
	begin
	case (rgb_se_n)
	
	3'b000:
			//b g r
			hsv_h <= 9'd240 - division;//-
			
	3'b001:
			//g b r
			hsv_h <= 9'd120 + division;//+
			
	3'b011:
			//g r b
			hsv_h <= 9'd120 - division;//-
			
	3'b100:
			//b r g
			hsv_h <= 9'd240 + division;//+
			
	3'b110:
			//r b g
			hsv_h <= 9'd360 - division;//-
			
			
	3'b111:
			//r g b
			hsv_h <= division;//+
			
	default
			hsv_h <= 9'd0;
	endcase
end
end

//  s=(max - min)/max * 256
always @ (*)
begin
	hsv_s_m = (max_n > 8'd0)? {max_min[7:0],8'b00000000} / max_n : 8'd0;
end
always@(posedge clk or negedge rst)
begin
	if (!rst)
      hsv_s <= 8'd0;
	else
	hsv_s <= hsv_s_m;
end
//  hsv_v = max
always@(posedge clk or negedge rst)
begin
  if (!rst)
  hsv_v <= 8'd0;
  else
  hsv_v <= max_n;
 end
 // 3-------------------



endmodule


   

  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值