1.sobel算子(verilog)
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2021/11/20 15:33:31
// Design Name:
// Module Name: x
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module x(
input wire vga_clk,
input wire rst_n,
input wire [9:0] pos_x,
input wire [9:0] pos_y,
input wire [23:0] rgb_data,
output reg [11:0] soble_out
);
reg state;
wire [7:0] r;
wire [7:0] g;
wire [7:0] b;
wire [23:0] gray;
assign r=rgb_data[23:16];
assign g=rgb_data[15:8];
assign b=rgb_data[7:0];
assign gray = r*5/16 +g*9/16 + b*2/4;
//assign gray_data ={gray,gray,gray };
reg line_clk;
reg [7:0] linebuf0[639:0];
reg [7:0] linebuf1[639:0];
reg [7:0] p0;
reg [7:0] p1;
reg [7:0] p2;
reg [9:0] conv_out;
always@(posedge vga_clk or negedge rst_n)
if(pos_y >0 && pos_y <480 && pos_x == 0)
line_clk =1;
else
line_clk =0;
//--------------------state-----------------------
always@(posedge vga_clk or negedge rst_n)
if(pos_y == 1'd1)
state<= 0;
else
state <= ~state;
always@(posedge vga_clk)
begin
case(state)
1'b0:
begin
linebuf0[pos_x] <= gray;
linebuf1[pos_x]<= linebuf1[pos_x];
p2<=gray;
p1<=p2;
p0 <=p1;
if(pos_x>1 && pos_y >2)
// 1 2 3 -1 -2 -1
//4 5 6 0 0 0
//7 8 9 1 2 1
begin
if((p0 +p1*2 +p2) >(linebuf0[pos_x-2]+ linebuf0[pos_x-1]+linebuf0[pos_x]))
conv_out <= ( (p0 +p1*2 +p2)-(linebuf0[pos_x-2]+ linebuf0[pos_x-1]+linebuf0[pos_x]) )/4;
else
conv_out <= ( (linebuf0[pos_x-2]+ linebuf0[pos_x-1]+linebuf0[pos_x]) -(p0 +p1*2 +p2) )/4;
end
end
1'b1: begin
linebuf1[pos_x] <= gray;
linebuf0[pos_x]<= linebuf0[pos_x];
p2<=gray;
p1<=p2;
p0 <=p1;
if(pos_x>1 && pos_y >2)
begin
if((p0 +p1*2 +p2) >(linebuf1[pos_x-2]+ linebuf1[pos_x-1]+linebuf1[pos_x]))
conv_out <= ( (p0 +p1*2 +p2)-(linebuf1[pos_x-2]+ linebuf1[pos_x-1]+linebuf1[pos_x]) );
else
conv_out <= ( (linebuf1[pos_x-2]+ linebuf1[pos_x-1]+linebuf1[pos_x]) -(p0 +p1*2 +p2) );
end
end
endcase
end
always@(*)
soble_out = {conv_out[5:2],conv_out[5:2],conv_out[5:2]};
endmodule
2.均值滤波。
module gausssmooth(
input clk,
input rst_n,
input [7:0]img_pix,
output [7:0]post_img_Y
);
wire [7:0] matrix_p11, matrix_p12, matrix_p13;//3x3 materix output
wire [7:0] matrix_p21, matrix_p22, matrix_p23;
wire [7:0] matrix_p31, matrix_p32, matrix_p33;
wire matrix_clken;
Shift_RAM_3X3 u_Shift_RAM_3X3(
//global signals
.clk (clk),
.rst_n (rst_n),
//Image data prepred to be processd
.per_clken (clk), //Prepared Image data output/capture enable clock
.per_img_Y (img_pix), //Prepared Image brightness input
//Image data has been processd
.matrix_clken (matrix_clken), //Prepared Image data output/capture enable clock
.matrix_p11 (matrix_p11),
.matrix_p12 (matrix_p12),
.matrix_p13 (matrix_p13), //3X3 Matrix output
.matrix_p21 (matrix_p21),
.matrix_p22 (matrix_p22),
.matrix_p23 (matrix_p23),
.matrix_p31 (matrix_p31),
.matrix_p32 (matrix_p32),
.matrix_p33 (matrix_p33)
);
//Mean Filter of 3X3 datas, need 2 clock
//Step 1
reg [10:0] mean_value1, mean_value2, mean_value3;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
mean_value1 <= 0;
mean_value2 <= 0;
mean_value3 <= 0;
end
else
begin
mean_value1 <= matrix_p11 + matrix_p12 + matrix_p13;
mean_value2 <= matrix_p21 + 11'd0 + matrix_p23;
mean_value3 <= matrix_p31 + matrix_p32 + matrix_p33;
end
end
//Step2
reg [10:0] mean_value4;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
mean_value4 <= 0;
else
mean_value4 <= mean_value1 + mean_value2 + mean_value3;
end
assign post_img_Y = mean_value4[10:3];
endmodule
module Shift_RAM_3X3(
//global signals
input clk,
input rst_n,
//Image data prepred to be processd
input per_clken,//Prepared Image data output/capture enable clock
input [7:0] per_img_Y,//Prepared Image brightness input
//Image data has been processd
output matrix_clken, //Prepared Image data output/capture enable clock
output reg [7:0] matrix_p11,
output reg [7:0] matrix_p12,
output reg [7:0] matrix_p13, //3X3 Matrix output
output reg [7:0] matrix_p21,
output reg [7:0] matrix_p22,
output reg [7:0] matrix_p23,
output reg [7:0] matrix_p31,
output reg [7:0] matrix_p32,
output reg [7:0] matrix_p33
);
//----------------------------------------------
//consume 1clk
wire [7:0] row1_data;//frame data of the 1th row
wire [7:0] row2_data;//frame data of the 2th row
reg [7:0] row3_data;//frame data of the 3th row
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
row3_data <= 8'b0;
else begin
if(per_clken)
row3_data <= per_img_Y;
else
row3_data <= row3_data;
end
end
//----------------------------------------------------------
//module of shift ram for row data
wire shift_clk_en = per_clken;
//Shift_RAM_3X3_8bit1
c_shift_ram_0 u1_Shift_RAM_3X3_8bit (
.D(row3_data), // input wire [7 : 0] D
.CLK(shift_clk_en), // input wire CLK
.SCLR(~rst_n), // input wire SCLR
.Q(row2_data) // output wire [7 : 0] Q
);
//Shift_RAM_3X3_8bit2
c_shift_ram_0 u2_Shift_RAM_3X3_8bit (
.D(row2_data), // input wire [7 : 0] D
.CLK(shift_clk_en), // input wire CLK
.SCLR(~rst_n), // input wire SCLR
.Q(row1_data) // output wire [7 : 0] Q
);
//-------------------------------------------
//per_clken delay 3clk
reg [1:0] per_clken_r;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
per_clken_r <= 2'b0;
else
per_clken_r <= {per_clken_r[0], per_clken};
end
wire read_clken = per_clken_r[0];
assign matrix_clken = per_clken_r[1];
//---------------------------------------------------------------------
/****************************************
(1)read data from shift_RAM
(2)caulate the sobel
(3)steady data after sobel generate
******************************************/
//wire [23:0] matrix_row1 = {matrix_p11, matrix_p12,matrix_p13};//just for test
//wire [23:0] matrix_row2 = {matrix_p21, matrix_p22,matrix_p23};
//wire [23:0] matrix_row3 = {matrix_p31, matrix_p32,matrix_p33};
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
{matrix_p11, matrix_p12, matrix_p13} <= 24'h0;
{matrix_p21, matrix_p22, matrix_p23} <= 24'h0;
{matrix_p31, matrix_p32, matrix_p33} <= 24'h0;
end
// else if(read_frame_href)begin
else if(read_clken)begin//shift_RAM data read clock enbale
{matrix_p11, matrix_p12, matrix_p13} <= {matrix_p12, matrix_p13, row1_data};//1th shift input
{matrix_p21, matrix_p22, matrix_p23} <= {matrix_p22, matrix_p23, row2_data};//2th shift input
{matrix_p31, matrix_p32, matrix_p33} <= {matrix_p32, matrix_p33, row3_data};//3th shift input
end
else begin
{matrix_p11, matrix_p12, matrix_p13} <= {matrix_p11, matrix_p12, matrix_p13};
{matrix_p21, matrix_p22, matrix_p23} <= {matrix_p21, matrix_p22, matrix_p23};
{matrix_p31, matrix_p32, matrix_p33} <= {matrix_p31, matrix_p32, matrix_p33};
end
// end
/* else begin
{matrix_p11, matrix_p12, matrix_p13} <= 24'h0;
{matrix_p21, matrix_p22, matrix_p23} <= 24'h0;
{matrix_p31, matrix_p32, matrix_p33} <= 24'h0;
end */
end
endmodule
3.中值滤波,在上面已经提出了3*3的矩阵数据以后,有已下算法
module mid_top(
input s1,
input s2,
input s3,
input s4,
input s5,
input s6,
input s7,
input s8,
input s9,
output reg [7:0] mid_out
);
reg [7:0] MAX1,MAX2,MAX3,MAX4,
MIN1,MIN2,MIN3,MIN4,
MED1,MED2,MED3,MED4;
initial
begin
MAX1 <= 8'b0;
MAX2 <= 8'b0;
MAX3 <= 8'b0;
MAX4 <= 8'b0;
MIN1 <= 8'b0;
MIN2 <= 8'b0;
MIN3 <= 8'b0;
MIN4 <= 8'b0;
MED1 <= 8'b0;
MED2 <= 8'b0;
MED3 <= 8'b0;
MED4 <= 8'b0;
end
always@(*)
begin
if(s1 >= s2 && s1 >= s3)
MAX1 <= s1;
else if(s2 >= s3 && s2 >= s1)
MAX1 <= S2;
else if(s3 >= s1 && s3 >= s2)
MAX1 <= s3;
else
MAX1 <= MAX1;
end
always@(*)
begin
if(s4 >= s5 && s4 >= s6)
MAX2 <= s4;
else if(s5 >= s4 && s5 >= s6)
MAX2 <= S5;
else if(s6 >= s4 && s6 >= s5)
MAX2 <= s6;
else
MAX2 <= MAX2;
end
always@(*)
begin
if(s7 >= s8 && s7 >= s9)
MAX3 <= s7;
else if(s8 >= s7 && s8 >= s9)
MAX3 <= S8;
else if(s9 >= s7 && s9 >= s8)
MAX3 <= s9;
else
MAX3 <= MAX3;
end
always@(*)
begin
if(s1 <= s2 && s1 <= s3)
MIN1 <= s1;
else if(s2 <= s3 && s2 <= s1)
MIN1 <= S2;
else if(s3 <= s1 && s3 <= s2)
MIN1 <= s3;
else
MIN1 <= MIN1;
end
always@(*)
begin
if(s4 <= s5 && s4 <= s6)
MIN2 <= s4;
else if(s5 <= s4 && s5 <= s6)
MIN2 <= S5;
else if(s6 <= s4 && s6 <= s5)
MIN2 <= s6;
else
MIN2 <= MIN2;
end
always@(*)
begin
if(s7 <= s8 && s7 <= s9)
MIN3 <= s7;
else if(s8 <= s7 && s8 <= s9)
MIN3 <= S8;
else if(s9 <= s7 && s9 <= s8)
MIN3 <= s9;
else
MIN3 <= MIN3;
end
always@(*)
begin
if(s1 >= s2 && S3 >= S1 || s1 >= s3 && S2 >= S1)
MED1 <= s1;
else if(s2 >= s3 && s1 >= s2 || s2 >= s1 && s3 >= s2)
MED1 <= S2;
else if(s3 >= s1 && s2 >= s3 ||s3 >= s2 && s2 >= s1 )
MED1 <= s3;
else
MED1 <= MED1;
end
always@(*)
begin
if(s4 >= s5 && s6>= s4 || s4 >= s6 && s5>= s4)
MED2 <= s4;
else if(s5 >= s4 && s6 >= s5 || s5 >= s6 && s4 >= s5)
MED2 <= S5;
else if(s6 >= s5 && s4 >= s6 || s6 >= s4 && s5 >= s6)
MED2 <= s6;
else
MED2 <= MED2;
end
always@(*)
begin
if(s7 >= s8 && s9>= s7 || s7 >= s9 && s8>= s7)
MED3 <= s7;
else if(s8 >= s7 && s9 >= s8 || s8 >= s9 && s7 >= s8)
MED3 <= S8;
else if(s9 >= s7 && s8 >= s9 || s9 >= s8 && s7 >= s9)
MED3 <= s9;
else
MED3 <= MED3;
end
//MAX4
always@(*)
begin
if(MIN1 >= MIN2 && MIN1 >= MIN3)
MAX4 <= MIN1;
else if(MIN2 >= MIN1 && MIN2 >= MIN3)
MAX4 <= MIN2;
else if(MIN3 >= MIN1 && MIN3 >= MIN2)
MAX4 <= MIN3;
else
MAX4 <= MAX4;
end
//MIN4
always@(*)
begin
if(MAX1 <= MAX2 && MAX1 <= MAX3)
MIN4 <= MAX1;
else if(MAX2 <= MAX1 && MAX2 <= MAX3)
MIN4 <= MAX2;
else if(MAX3 <= MAX1 && MAX3 <= MAX2)
MIN4 <= MAX3;
else
MIN4 <= MAX4;
end
//MED4
always@(*)
begin
if(MED1 >= MED2 && MED3>= MED1 || MED1 >= MED3 && MED2>= MED1)
MED4 <= MED1;
else if(MED2 >= MED3 && MED2 >= MED2 || MED2 >= MED2 && MED3 >= MED2)
MED4 <= MED2;
else if(MED3 >= MED2 && MED1 >= MED3 || MED3 >= MED1 && MED2 >= MED3)
MED4 <= MED3;
else
MED4 <= MED4;
end
//get mid_out from MIN4 MED4 MAX4
always@(*)
begin
if(MIN4 >= MED4 && MAX4>= MIN4 || MIN4 >= MAX4 && MED4>= MIN4)
mid_out <= MIN4;
else if(MED4 >= MIN4 && MAX4 >= MED4 || MED4 >= MAX4 && MIN4 >= MED4)
mid_out <= MED4;
else if(MAX4 >= MED4 && MIN4 >= MAX4 || MAX4 >= MIN4 && MED4 >= MAX4)
mid_out <= MAX4;
else
mid_out <= mid_out;
end
endmodule
4.腐蚀与膨胀(需要转换为二值图像)
module mid_top(
input s1,
input s2,
input s3,
input s4,
input s5,
input s6,
input s7,
input s8,
input s9,
output reg [7:0] mid_out
);
reg L1;
reg L2;
reg L3;
initial
begin
L1 = 0;
L2 =0;
L3 =0;
end
//腐蚀
always@(*)
begin
L1 <= s1 && s2 &&s3;
L2 <= s4 && s5 &&s6;
L3 <= s7 && s8 &&s9;
end
always@(*)
begin
mid_out <= L1 && L2 && L3;
end
//膨胀
always@(*)
begin
L1 <= s1 || s2 ||s3;
L2 <= s4 || s5 ||s6;
L3 <= s7 || s8 ||s9;
end
always@(*)
begin
mid_out <= L1 || L2 || L3;
end
endmodule