FPGA-Studie notes_image verarbeitet 2_RGB zum Graustufenalgorithmus

Anmerkungen zur FPGA-Studie

Bildverarbeitungsalgorithmus

1. RGB转灰度算法
   1.1 背景
   1.2 FPGA实现RGB图像转Gray图像

1. RGB-Graustufen-Algorithmus

  • 1.1 Hintergrund:
  1. Graues Bild: Graustufenbild, Schwarzweißbild, von Schwarz über Weiß bis Graustufen: 0 ~ 255 (8 Bit).
  2. YUV-Bild: Die vom europäischen TV-System verwendete Farbcodierungsmethode, die hauptsächlich zur Optimierung der Übertragung von Farbvideosignalen verwendet wird. Verwenden Sie eine Farbkamera oder eine Farb-CCD-Kamera, um Bilder aufzunehmen, die Farbbildsignale zu trennen bzw. zu verstärken und zu korrigieren, um RGB zu erhalten. Nach der Matrixumwandlungsschaltung werden das Helligkeitssignal Y und zwei Farbdifferenzsignale BY (U), RY ( V) erhalten werden. Der Absender codiert und sendet es auf demselben Kanal.
    "Y": Repräsentiert die Helligkeit (Luminanz, Luma), den Graustufenwert; wird durch das RGB-Eingangssignal festgelegt und überlagert bestimmte Teile des RGB-Signals miteinander.
    "U" und "V" stehen für Chrominanz (Chroma), definieren Farbe und Sättigung und geben die Pixelfarbe an. Cr: die Differenz zwischen dem roten Teil des RGB-Eingangssignals und dem Helligkeitswert des RGB-Signals; Cb: die Differenz zwischen dem blauen Teil des RGB-Eingangssignals und dem Helligkeitswert des RGB-Signals.
  3. Ycbcr-Bild: Ycbcr, Y'CbCr, YCBCR, Y'CBCR, Farbraum, zur kontinuierlichen Bildverarbeitung, digitales Fotografiesystem. Y ': Luma, Helligkeitskomponente, CB, CR: Offsetkomponenten mit blauer und roter Dichte. Y: Luminanz, die die Dichte des Lichts darstellt und nicht linear ist und eine Gammakorrektur-Codierungsverarbeitung verwendet.
  • 1.2 FPGA-Implementierung des RGB-Bilds in die Graubildmethode
    (2 Typen): 1. Einkanal-Anzeigebild des RGB-Bildes (R, G, B). 2. Konvertieren Sie das RGB-Bild in ein Ycbcr-Bild und zeigen Sie das Bild mit der Y-Komponente an
  1. Einkanal-Anzeigebild des RGB-Bildes (R, G, B)
    Fügen Sie hier eine Bildbeschreibung ein
  2. Konvertieren Sie das RGB-Bild in ein Ycbcr-Bild. Verwenden Sie die Y-Komponente, um das Bild anzuzeigen.
    Fügen Sie hier eine Bildbeschreibung ein
    RGB in Ycbcr-Algorithmus:
    Formel:
    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; Das
    Timing wird bei der Berechnung nicht verwendet, und die Eingabe zu Ausgabe wird um drei Takte verzögert.
    Die Pipeline der ersten Stufe: Berechnen Sie alle Multiplikationen, die
    Pipeline der zweiten Stufe: Berechnen Sie alle Additionen und trennen Sie das Positive und das Negative für die Addition
    ;
  • Verilog-Code
/*
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

  • Ergebnisse
    Kapazitiver 5-Zoll-TFT-Touchscreen
    Bild: 800 * 480 Pixel
    (1). (Yiyanqianxi ^^) Ursprüngliches Netzwerkbild:
    Fügen Sie hier eine Bildbeschreibung ein
    (2). FPGA-Anzeige Originalbild: Fügen Sie hier eine Bildbeschreibung ein
    (3). FPGA-Graustufen-Verarbeitungsbild:Fügen Sie hier eine Bildbeschreibung ein

Referenzmaterialien: "Praktischer Leitfaden für das Design und die Überprüfung von FPGA-Systemen"
[Hinweis]: Persönliche Studiennotizen: Wenn es Fehler gibt, können Sie mich gerne aufklären. Dies ist höflich ~~~


Ich denke du magst

Origin blog.csdn.net/weixin_50722839/article/details/113763484
Empfohlen
Rangfolge