FPGAスタディノート
画像処理アルゴリズム
1. RGB转灰度算法
1.1 背景
1.2 FPGA实现RGB图像转Gray图像
1.RGBからグレースケールへのアルゴリズム
- 1.1背景:
- グレー画像:グレースケール画像、白黒画像、黒から白、グレースケール:0〜255(8ビット)。
- YUV画像:主にカラービデオ信号の伝送を最適化するために使用される、ヨーロッパのテレビシステムで採用されている色分け方法。カラーカメラまたはカラーCCDカメラを使用して画像をキャプチャし、カラー画像信号を分離し、それぞれ増幅および補正してRGBを取得します。マトリックス変換回路の後、輝度信号Yと2つの色差信号BY(U)、RY( V)が取得されます。送信者はそれをエンコードして同じチャネルで送信します。
「Y」:明るさ(輝度、輝度)、グレースケール値を表します。RGB入力信号によって確立され、RGB信号の特定の部分を重ね合わせます。
「U」と「V」はクロミナンス(クロマ)を表し、色と彩度を定義し、ピクセルの色を指定します。Cr:RGB入力信号の赤色部分とRGB信号の輝度値の差。Cb:RGB入力信号の青色部分とRGB信号の輝度値の差。 - Ycbcr画像:Ycbcr、Y'CbCr、YCBCR、Y'CBCR、色空間、連続画像処理、デジタル写真システムに使用されます。Y ':輝度、明るさ成分、CB、CR:青と赤の濃度オフセット成分。Y:輝度。光の密度を表し、非線形であり、ガンマ補正エンコーディング処理を使用します。
- 1.2 RGBイメージからグレーイメージへのFPGA実装
(2種類):1。RGBイメージ(R、G、B)のシングルチャンネル表示イメージ。2。RGBイメージをYcbcrイメージに変換し、Yコンポーネントを使用してイメージを表示します。
- RGB画像のシングルチャンネル表示画像(R、G、B)
- RGB画像をYcbcr画像に変換し、Yコンポーネントを使用して画像
RGBをYcbcrアルゴリズムに表示します。
式:
Y = 0.183R + 0.614G + 0.062B + 16;
Cb = -0.101R-0.338G + 0.439B + 128;
Cr = 0.439 R – 0.399G -0.040B + 128;
タイミングは計算に使用されず、出力への入力は3クロック遅延します。
第1段階のパイプライン:すべての乗算を計算します。
第2段階のパイプライン:すべての加算を計算し、加算のために正と負を分離します。第
3段階のパイプライン:最終的な合計を計算します。負の数の場合は0を取ります。
- Verilogコード
/*
RGB-->Ycbcr:
Y = 0.183R + 0.614G + 0.062B + 16;
Cb = -0.101R - 0.338G + 0.439B + 128;
Cr = 0.439R – 0.399G -0.040B + 128;
*/
module rgb2ycbcr#(
//formula_y
parameter p0183_10b = 10'd47, //0.183*256 = 46.848
parameter p0614_10b = 10'd157,//0.614*256 = 15.7184
parameter p0062_10b = 10'd16,//0.062*256 = 15.872
parameter p16_10b = 18'd4096,//16*256 = 4096
//formula_cb
parameter p0101_10b = 10'd26,//0.101*256=25.856
parameter p0338_10b = 10'd86,//0.338*256=86.852
parameter p0439_10b = 10'd112,//0439*256=112.384
parameter p128_10b = 10'd32768,//128*256=32768
//formula_cr
// parameter p0439_10b = 10'd112,//0.439*256=112.384
parameter p0399_10b = 10'd102,//0.399*256=102.144
parameter p0040_10b = 10'd10//0.04*256=10.24
// parameter p128_10b = 10'd32768//128*256=32768
)
(
input clk,
input rst_n,
input [7:0] data_in_r,
input [7:0] data_in_g,
input [7:0] data_in_b,
input data_in_en, //input enable signal
input sync_in_h,
input sync_in_v,
output [7:0] data_out_y,
output [7:0] data_out_cb,
output [7:0] data_out_cr,
output wire data_out_en,
output wire sync_out_h,
output wire sync_out_v
);
//----pipeline-----------------------
wire signed_cb;
wire signed_cr;
reg [17:0] mult_y_r;
reg [17:0] mult_y_g;
reg [17:0] mult_y_b;
reg [17:0] mult_cb_r;
reg [17:0] mult_cb_g;
reg [17:0] mult_cb_b;
reg [17:0] mult_cr_r;
reg [17:0] mult_cr_g;
reg [17:0] mult_cr_b;
reg [17:0] add_y_0;
reg [17:0] add_y_1;
reg [17:0] add_cb_0;
reg [17:0] add_cb_1;
reg [17:0] add_cr_0;
reg [17:0] add_cr_1;
reg [17:0] add_final_y;
reg [17:0] add_final_cb;
reg [17:0] add_final_cr;
reg [9:0] around_y;
reg [9:0] around_cb;
reg [9:0] around_cr;
//----syn timing------------------
reg syn_data_in_en0;
reg syn_data_in_en1;
reg syn_data_in_en2;
reg sync_in_h0;
reg sync_in_h1;
reg sync_in_h2;
reg sync_in_v0;
reg sync_in_v1;
reg sync_in_v2;
/*
Y = 0.183R + 0.614G + 0.062B + 16;
Cb = -0.101R - 0.338G + 0.439B + 128;
Cr = 0.439R – 0.399G -0.040B + 128;
*/
/*--------------------------------------------------------
|---------pipeline1_mult----------------------------------|
--------------------------------------------------------*/
//---mult_formula_y---------------------|
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
mult_y_r <= 18'd0;
mult_y_g <= 18'd0;
mult_y_b <= 18'd0;
end else
begin
mult_y_r <= data_in_r * p0183_10b;
mult_y_g <= data_in_g * p0614_10b;
mult_y_b <= data_in_b * p0062_10b;
end
//---mult_formula_cb---------------------|
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
mult_cb_r <= 18'd0;
mult_cb_g <= 18'd0;
mult_cb_b <= 18'd0;
end else
begin
mult_cb_r <= data_in_r * p0101_10b;
mult_cb_g <= data_in_g * p0338_10b;
mult_cb_b <= data_in_b * p0439_10b;
end
//---mult_formula_cr---------------------|
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
mult_cr_r <= 18'd0;
mult_cr_g <= 18'd0;
mult_cr_b <= 18'd0;
end else
begin
mult_cr_r <= data_in_r * p0439_10b;
mult_cr_g <= data_in_g * p0399_10b;
mult_cr_b <= data_in_b * p0040_10b;
end
/*--------------------------------------------------------
|---------pipeline1_add----------------------------------|
--------------------------------------------------------*/
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
add_y_0 <= 18'd0;
add_y_1 <= 18'd0;
add_cb_0 <= 18'd0;
add_cb_1 <= 18'd0;
add_cr_0 <= 18'd0;
add_cr_1 <= 18'd0;
end else
begin
//Y = 0.183R + 0.614G + 0.062B + 16;
add_y_0 <= mult_y_r + mult_y_g;
add_y_1 <= mult_y_b + p16_10b;
//Cb = -0.101R - 0.338G + 0.439B + 128;
add_cb_0 <= mult_cb_r + mult_cb_g;
add_cb_1 <= mult_cb_b + p16_10b;
//Cr = 0.439R – 0.399G -0.040B + 128;
add_cr_0 <= mult_cr_g + mult_cr_b;
add_cr_1 <= mult_cr_r + p16_10b;
end
/*--------------------------------------------------------
|-----pipeline3_add_final(negtive = 0)-------------------|
--------------------------------------------------------*/
assign signed_cb = (add_cb_0>=add_cb_1);
assign signed_cr = (add_cr_0>=add_cr_1);
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
begin
add_final_y <= 18'd0;
add_final_cb <= 18'd0;
add_final_cr <= 18'd0;
end else
begin
add_final_y <= add_y_0 + add_y_1;
add_final_cb <= signed_cb?(add_cb_0 - add_cb_1):1'd0;
add_final_cr <= signed_cr?(add_cr_0 - add_cr_1):1'd0;
end
end
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
around_y <= 10'd0;
around_cb <= 10'd0;
around_cr <= 10'd0;
end else
begin
around_y <= add_final_y[17:8]+{
9'd0,add_final_y[7]}; //around(add_final_y/256)
around_cb <= add_final_cb[17:8]+{
9'd0,add_final_cb[7]};
around_cr <= add_final_cr[17:8]+{
9'd0,add_final_cr[7]};
end
/*--------------------------------------------------------
|-----gray2ycbcr-----------------------------------------|
--------------------------------------------------------*/
assign data_out_y = (around_y[9:8]==2'b00)?around_y[7:0]:8'd255;
assign data_out_cb = (around_cb[9:8]==2'b00)?around_cb[7:0]:8'd255;
assign data_out_cr = (around_cr[9:8]==2'b00)?around_cr[7:0]:8'd255;
/*--------------------------------------------------------
|-----syn timing-----------------------------------------|
--------------------------------------------------------*/
//----data_in_en------------------------
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
syn_data_in_en0 <= 18'd0;
syn_data_in_en1 <= 18'd0;
syn_data_in_en2 <= 18'd0;
end else
begin
syn_data_in_en0 <= data_in_en;
syn_data_in_en1 <= syn_data_in_en0;
syn_data_in_en2 <= syn_data_in_en1;
end
//----sync_in_h-------------------------
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
sync_in_h0 <= 18'd0;
sync_in_h1 <= 18'd0;
sync_in_h2 <= 18'd0;
end else
begin
sync_in_h0 <= sync_in_h;
sync_in_h1 <= sync_in_h0;
sync_in_h2 <= sync_in_h1;
end
//----sync_in_v-------------------------
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
sync_in_v0 <= 18'd0;
sync_in_v1 <= 18'd0;
sync_in_v2 <= 18'd0;
end else
begin
sync_in_v0 <= sync_in_v;
sync_in_v1 <= sync_in_v0;
sync_in_v2 <= sync_in_v1;
end
//---------------------------------------
assign data_out_en = syn_data_in_en2;
assign sync_out_h = sync_in_h2;
assign sync_out_v = sync_in_v2;
/*--------------------------------------------------------
|--------------------------------------------------------|
--------------------------------------------------------*/
endmodule
- 結果
5インチTFT静電容量式タッチスクリーン
画像:800 * 480ピクセル
(1)。(Yiyanqianxi ^^)元のネットワーク画像:
(2)。FPGAディスプレイの元の画像:(3)。FPGA
グレースケール処理画像:
参考資料:「FPGAシステム設計・検証実践ガイド」
【注】:個人学習ノート、間違いがありましたら、お気軽に教えてください、丁寧です~~~