问题遇到的发生背景
使用FPGA进行图像人脸识别
理想预期的识别结果
首先,识别的结果就是将存在rom的图像取出来,之后进行二值化处理,当检测到像素人脸时,像素变为{16{1'b1}},进而在lcd上显示为白色区域,根据最后呈现出来图像区域判断是否是白色,进行人脸定位,得到以x_min,x_max,y_min,y_max为四个顶点的矩形框,最后以绿线将人脸区域框起来
verilog描述语言
下部分就是人脸识别的verilog描述语言,其中输入per_monoc是当检测到人脸区域时,值变为1
module face_detect(
input clk,
input rst_n,
input per_frame_vsync,
input per_frame_hsync,
input per_frame_clken,
input per_monoc,
input [10:0] h_disp,
input [10:0] v_disp,
input [10:0] pixel_x,
input [10:0] pixel_y,
output post_frame_vsync,
output post_frame_hsync,
output post_frame_clken,
output reg [10:0] x_min,
output reg [10:0] x_max,
output reg [10:0] y_min,
output reg [10:0] y_max,
output reg [15:0] post_img
);
parameter GREEN = 16'b00000_111111_00000;
parameter ROW = 11'd800;
parameter COL = 11'd1280;
reg [10:0] cnt_x;
reg [10:0] cnt_y;
wire row_flag;
wire frame_flag;//开始本帧数据
assign frame_flag = (cnt_x==1&&cnt_y==1) ? 1'b1:1'b0;
//cnt_x计数
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt_x <= 11'd0;
else if(per_frame_clken && cnt_x==COL-1'b1)
cnt_x <= 11'd0;
else if(per_frame_clken)
cnt_x <= cnt_x+1'b1;
else
cnt_x <= cnt_x;
end
assign row_flag = (per_frame_clken&&cnt_x==COL-1'b1) ? 1'b1:1'b0;
//cnt_y计数
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt_y <= 11'd0;
else if(row_flag&&cnt_y==ROW-1'b1)
cnt_y <= 11'd0;
else if(row_flag)
cnt_y <= cnt_y+1'b1;
else
cnt_y <= cnt_y;
end
//x_min 2clk
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
x_min <= COL;
else if(frame_flag)
x_min <= COL;
else if(per_monoc==1'b1 && (x_min>=cnt_x) )
x_min <= cnt_x;
else
x_min <= x_min;
end
//x_max
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
x_max <= 11'd0;
else if(frame_flag)
x_max <= 11'd0;
else if(per_monoc==1'b1 && (x_max<=cnt_x) )
x_max <= cnt_x;
else
x_max <= x_max;
end
//y_min
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
y_min <= ROW;
else if(frame_flag)
y_min <= ROW;
else if(per_monoc==1'b1 && (y_min>=cnt_y) )
y_min <= cnt_y;
else
y_min <= y_min;
end
//y_max
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
y_max <= 11'd0;
else if(frame_flag)
y_max <= 11'd0;
else if(per_monoc==1'b1 && (y_max<=cnt_y))
y_max <= cnt_y;
else
y_max <= y_max;
end
reg [10:0] x_min_r,x_max_r,y_min_r,y_max_r;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
{x_min_r,x_max_r,y_min_r,y_max_r} <= 44'd0;
else if(cnt_y==ROW-1'b1 && cnt_x==COL-1'b1)
{x_min_r,x_max_r,y_min_r,y_max_r} <= {x_min,x_max,y_min,y_max};
end
reg [3:0] per_frame_hsync_r;
reg [3:0] per_frame_vsync_r;
reg [3:0] per_frame_clken_r;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
per_frame_hsync_r <= 4'd0;
per_frame_vsync_r <= 4'd0;
per_frame_clken_r <= 4'd0;
end
else begin
per_frame_hsync_r <= {per_frame_hsync_r[2:0],per_frame_hsync};
per_frame_vsync_r <= {per_frame_vsync_r[2:0],per_frame_vsync};
per_frame_clken_r <= {per_frame_clken_r[2:0],per_frame_clken};
end
end
assign post_frame_vsync = per_frame_vsync_r[2];//延迟1拍
assign post_frame_hsync = per_frame_hsync_r[1];
assign post_frame_clken = per_frame_clken_r[1];
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
post_img <= 16'b0;
else if(post_frame_vsync)begin
if(pixel_y==y_min_r&&pixel_x>=x_min_r&&pixel_x<=x_max_r)
post_img <= GREEN;
else if(pixel_y==y_max_r && pixel_x>=x_min_r && pixel_x<=x_max_r)
post_img <= GREEN;
else if(pixel_x==x_min_r&&pixel_y>=y_min_r&&pixel_y<=y_max_r)
post_img <= GREEN;
else if(pixel_x==x_max_r&&pixel_y>=y_min_r&&pixel_y<=y_max_r)
post_img <= GREEN;
else
post_img <= {16{per_monoc}};
end
else
post_img <= 16'b0;
end
endmodule
运行结果及详细报错内容
按理来说,绿色矩形框将框住白色区域,但我得到的结果如下
就是它没框成一个矩形,而且还出现如上图所示的好几条不相关的绿线,而且这里的x_max,以及y_max没有体现出来,但是根据网上资料,对x_min,x_max,y_min,y_max进行定位那步,我并没有描述错误,所以就很迷。
我的解答思路和尝试过的方法
我尝试过好多种方法,比如修改时序、将上述代码中的x_min、x_max进行寄存什么的,但是结果还是不理想,所以向各位请教