我是靠谱客的博主 外向路人,最近开发中收集的这篇文章主要介绍FPGA-图像处理-仿真说明图片读取和写入灰度转换高斯滤波二值化边缘检测(sobel)顶层文件改进中- - - -,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 说明
  • 图片读取和写入
  • 灰度转换
  • 高斯滤波
  • 二值化
  • 边缘检测(sobel)
  • 顶层文件
  • 改进中- - - -

任务
读入一张bmp图片,对图片进行灰度处理,二值化以及边缘检测(sobel算子),将处理后的数据写入bmp显示,全部过程以仿真形式。我这用的vivado。

说明

在图像处理领域,要实现Sobel或者均值滤波等算法,则需要按照3*3矩阵的格式提取数据,
在这里插入图片描述
需要用到移位寄存器SHIFT RAM IP核。
Altera厂家的EDA环境下移位寄存器IP核可以实现多行的缓存输出,但是Xilinx下的Vivado环境,仅仅支持缓存输出一行数据,不过其实也无关紧要,我们这里可以使用两个SHIFT RAM IP核和正在输入的一行数据三者共同组成3行数据。

图片读取和写入

可参考FPGA-仿真读写bmp图片
使用图片(128*128):
在这里插入图片描述

本次实验的图片读取写入tb

/*******************************************************************************
*
*
*
(c) Copyright 1995-2017 TAIHO ELE Co,Ltd.
*
*
All rights reserved.
*
*
*
********************************************************************************
*
*
FileName
:
top_tb.v
*
Abstract
:
This module is an example for coding.
*
Author
:
Mouhongbing
*
Version
:
1.1
*
Release
:
2022.9.29
*
Revision
:
*
Version Date
Author
Modification description
*
1.0
Mouhongbing
2022.9.29
*
******************************************************************************/
`timescale 1ns / 1ns
module top_tb;
reg
clk;
reg
rst;
wire	[23:0]
dout;
reg
din_vld;
wire
dout_vld;
//图像属性:图像宽度 图像高度 图像尺寸 图像像素点起始位
integer bmp_width;
integer bmp_high;
integer bmp_size;
integer start_index;
//bmp file id
integer bmp_file_id;
integer bmp_dout_id;
integer dout_txt_id;
//文件句柄
integer h;
//文件bmp文件数据
reg
[7:0]	rd_data
[0:49300];
reg
[7:0]
rd_data2 [0:49300];
//写操作
reg
[23:0]	wr_data;
integer i = 0;
integer index;
integer j = 0;
parameter CYCLE=20;
always #(CYCLE/2) clk=~clk;
initial
begin
clk=1'b1;
rst=1'b0;
#(CYCLE);
rst=1'b1;
#CYCLE;
rst=1'b0;
din_vld=1'b0;
//打开原始图像
bmp_file_id = $fopen("D:\python\pic\er.bmp","rb");
//打开输出数据
dout_txt_id = $fopen("D:\python\pic\output_file.txt","w+");
//读取bmp文件
h = $fread(rd_data,bmp_file_id);
// 图像宽度
bmp_width = {rd_data[21], rd_data[20], rd_data[19], rd_data[18]};
// 图像宽度
bmp_high = {rd_data[25], rd_data[24], rd_data[23], rd_data[22]};
// 像素起始位置
start_index = {rd_data[13], rd_data[12], rd_data[11], rd_data[10]};
// 图像尺寸
bmp_size = {rd_data[5], rd_data[4], rd_data[3], rd_data[2]};
$fclose(bmp_file_id);
//输出txt
for(index = start_index; index < bmp_size-2; index = index + 3)begin
//将像素点数据写入txt文件
din_vld=1'b1;
wr_data = {rd_data[index + 2], rd_data[index + 1], rd_data[index]};
$fwrite(dout_txt_id, "%d,", wr_data[7:0]);
$fwrite(dout_txt_id, "%d,", wr_data[15:8]);
$fwrite(dout_txt_id, "%dn", wr_data[23:16]);
#(CYCLE);
end
din_vld=1'b0;
$fclose(dout_txt_id);
end
initial
begin
#(3*CYCLE);
//打开输出图像
bmp_dout_id = $fopen("D:\python\pic\output_file.bmp","wb");//将数据写入bmp
for(i = 0; i < start_index; i = i + 1)begin //写入文件头部信息
$fwrite(bmp_dout_id, "%c", rd_data[i]);
end
j=start_index;
while(j<bmp_size) //写入像素点信息
begin
if(dout_vld==1'b1)
begin
$fwrite(bmp_dout_id, "%c", dout[7:0]);
$fwrite(bmp_dout_id, "%c", dout[15:8]);
$fwrite(bmp_dout_id, "%c", dout[23:16]);
j=j+3;
end
else
begin
j=j;
end
#CYCLE;
end
$fclose(bmp_dout_id);
end
top
u_top
(
//clock and reset
.rst
(rst),
//reset
.clk
(clk),
//clock
.rgb_din
(wr_data),
//输入数据
.din_vld
(din_vld),
//数据有效
.rgb_out
(dout),
//输出数据
.dout_vld
(dout_vld)
//数据有效
);
endmodule

灰度转换

对于彩色图像转化为灰度图像,有一个著名的色彩心理学公式,即:
在这里插入图片描述
但是在实际应用时,由于FPGA希望避免复杂的浮点运算,所以这里我们采用整数运算。将R、G、B三个分量对应的系数放大256倍得到整数结果:

在这里插入图片描述

/*******************************************************************************
*
*
*
(c) Copyright 1995-2017 TAIHO ELE Co,Ltd.
*
*
All rights reserved.
*
*
*
********************************************************************************
*
*
FileName
:
rgb2gray.v
*
Abstract
:
This module is an example for coding.
*
Author
:
Mouhongbing
*
Version
:
1.1
*
Release
:
2022.9.30
*
Revision
:
*
Version Date
Author
Modification description
*
1.0
Mouhongbing
2022.9.30
*
******************************************************************************/
`timescale 1ns/100ps
//----------------------------------------------------------------------

//
MODULE DEFINTION

//----------------------------------------------------------------------

module rgb2gray
(
//clock and reset

rst,
//reset

clk,
//clock 
din,
din_vld,
dout,
dout_vld
);
//interface parameter

//----------------------------------------------------------------------

//
PORT SIGNAL DEFINATION

//----------------------------------------------------------------------

//clock and reset

input
rst;
//reset

input
clk;
//clock

input	[23:0]
din;
input
din_vld;
output
[7:0]
dout;
output
dout_vld;
//----------------------------------------------------------------------

//
PORT SIGNAL TYPE

//----------------------------------------------------------------------

//clock and reset

wire
rst;
//reset

wire
clk;
//clock

wire	[23:0]
din;
wire
din_vld;
reg
[7:0]
dout;
reg
dout_vld;
//----------------------------------------------------------------------

//
INTERNAL SIGNAL DEFINATION

//----------------------------------------------------------------------

//RGB 
reg
[7:0]
data_r;
reg
[7:0]
data_g;
reg
[7:0]
data_b;
//加权值后RGB
reg
[17:0]
pixel_r ;
reg
[17:0]
pixel_g ;
reg
[17:0]
pixel_b ;
//vld
reg
[1:0]
vld;
//
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
data_r<=8'b0;
data_g<=8'b0;
data_b<=8'b0;
end
else
begin
data_r<=din[23:16];
data_g<=din[15:8];
data_b<=din[7:0];
end
end
//vld 寄存
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
vld<=2'b0;
end
else
begin
vld<={vld[0],din_vld};
end
end
//RGB权值
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
pixel_r<=17'b0;
pixel_g<=17'b0;
pixel_b<=17'b0;
end
else if(vld[0]==1'b1)
begin
pixel_r<=data_r*77;
pixel_g<=data_g*150;
pixel_b<=data_b*29;
end
end
//
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
dout<=19'b0;
end
else if(vld[1]==1'b1)
begin
dout<=(pixel_r+pixel_g+pixel_b)>>8;
end
end
//vld
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
dout_vld<=1'b0;
end
else
begin
dout_vld<=vld[1];
end
end
endmodule

效果展示
在这里插入图片描述

高斯滤波

在灰度转换过程中,可能会因为取整操作引入噪声,所以接下来使用高斯滤波算法来去除灰度转化过程中引入的噪声。在本次使用实际处理过程中发现使用了高斯滤波最后效果并不理想,最后是去掉了这个模块,有兴趣的童鞋可以研究。

高斯滤波的具体操作是使用一个NN卷积模板对整幅图像扫描,用模板确定的邻域内的像素加权平均值代替模板中心像素点的值。本文使用的33卷积模板如下:
在这里插入图片描述
在这里插入图片描述
其中,I(x,y)表示原图像中坐标为(x,y)的像素值;G(x,y)表示高斯滤波之后的值。这里为了计算方便,选取的模板H的权重系数都是2的系数。模板中心的权值最大,这样有利于克服边界效应,避免经过高斯滤波之后图像模糊。

/*******************************************************************************
*
*
*
(c) Copyright 1995-2017 TAIHO ELE Co,Ltd.
*
*
All rights reserved.
*
*
*
********************************************************************************
*
*
FileName
:
gauss.v
*
Abstract
:
This module is an example for coding.
*
Author
:
Mouhongbing
*
Version
:
1.1
*
Release
:
2022.10.8
*
Revision
:
*
Version Date
Author
Modification description
*
1.0
Mouhongbing
2022.10.8
*
******************************************************************************/
`timescale 1ns/100ps
//----------------------------------------------------------------------

//
MODULE DEFINTION

//----------------------------------------------------------------------

module gauss
(
//clock and reset

rst,
//reset

clk,
//clock

din,
din_vld,
dout,
dout_vld
);
//interface parameter

//----------------------------------------------------------------------

//
PORT SIGNAL DEFINATION

//----------------------------------------------------------------------

//clock and reset

input
rst;
//reset

input
clk;
//clock

input
[7:0]
din;
input
din_vld;
output
[7:0]
dout;
output
dout_vld;
//----------------------------------------------------------------------

//
PORT SIGNAL TYPE

//----------------------------------------------------------------------

//clock and reset

wire
rst;
//reset

wire
clk;
//clock

wire
[7:0]
din;
wire
din_vld;
reg
[7:0]
dout;
reg
dout_vld;
//----------------------------------------------------------------------

//
INTERNAL SIGNAL DEFINATION

//----------------------------------------------------------------------

wire
[7:0]
row1_data;
wire
[7:0]
row2_data;
wire
[7:0]
row3_data;
wire
[7:0]
row1_data_r;
wire
[7:0]
row2_data_r;
//有效值
reg
[2:0]
vld;
//3*3
reg
[7:0]
row1_1;
reg
[7:0]
row1_2;
reg
[7:0]
row1_3;
reg
[7:0]
row2_1;
reg
[7:0]
row2_2;
reg
[7:0]
row2_3;
reg
[7:0]
row3_1;
reg
[7:0]
row3_2;
reg
[7:0]
row3_3;
//sum
reg
[9:0]
sum_1;
reg
[9:0]
sum_2;
reg
[9:0]
sum_3;
reg
[11:0]
sum;
//缓存三行 第一级流水
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
row1_1<=7'b0;row1_2<=7'b0;row1_3<=7'b0;
row2_1<=7'b0;row2_2<=7'b0;row2_3<=7'b0;
row3_1<=7'b0;row3_2<=7'b0;row3_3<=7'b0;
end
else if(vld[0]==1'b1)
begin
row1_1<=row1_data;row1_2<=row1_1;row1_3<=row1_2;
row2_1<=row2_data;row2_2<=row2_1;row2_3<=row2_2;
row3_1<=row3_data;row3_2<=row3_1;row3_3<=row3_2;
end
end
//第二级流水
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)begin
sum_1 <= 10'b0;
sum_2 <= 10'b0;
sum_3 <= 10'b0;
end
else if(vld[1]==1'b1)begin
sum_1 <= {2'd0,row1_1} + {1'd0,row1_2,1'd0} + {2'd0,row1_3};
sum_2 <= {1'b0,row2_1,1'b0} + {row2_2,2'd0} + {1'd0,row2_3,1'b0};
sum_3 <= {2'd0,row3_1} + {1'd0,row3_2,1'd0} + {2'd0,row3_3};
end
end
//第三级流水sum
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)begin
sum<=12'b0;
end
else if(vld[2]==1'b1)begin
sum<=sum_1+sum_2+sum_3;
end
end
//vld
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
vld<=3'b0;
end
else
begin
vld<={vld[1:0],din_vld};
end
end
//dout_vld
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
dout_vld<=1'b0;
end
else
begin
dout_vld<=vld[2];
end
end
//dout
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
dout<=8'b0;
end
else
begin
dout<=sum[4+:8];//从第4个开始,位宽为8
end
end
assign row1_data=row1_data_r;
assign row2_data=row1_data_r;
assign row3_data=din;
c_shift_ram_1 u_shift_ram_0 (
.D(din),
// input wire [0 : 0] D
.CLK(clk),
// input wire CLK
.SCLR(rst),
// input wire SCLR
.Q(row2_data_r)
// output wire [0 : 0] Q
);
c_shift_ram_1 u_shift_ram_1 (
.D(row2_data_r),
// input wire [0 : 0] D
.CLK(clk),
// input wire CLK
.SCLR(rst),
// input wire SCLR
.Q(row1_data_r)
// output wire [0 : 0] Q
);
endmodule

效果展示:(不理想,所以最后没有用这个模块)
在这里插入图片描述

二值化

了解更多二值化操作可参考图像二值化算法

首先使用的是全局二值化,给定一个全局阈值

/*******************************************************************************
*
*
*
(c) Copyright 1995-2017 TAIHO ELE Co,Ltd.
*
*
All rights reserved.
*
*
*
********************************************************************************
*
*
FileName
:
gray2bin.v
*
Abstract
:
This module is an example for coding.
*
Author
:
Mouhongbing
*
Version
:
1.1
*
Release
:
2022.9.30
*
Revision
:
*
Version Date
Author
Modification description
*
1.0
Mouhongbing
2022.9.30
*
******************************************************************************/
`timescale 1ns/100ps
//----------------------------------------------------------------------

//
MODULE DEFINTION

//----------------------------------------------------------------------

module gray2bin
(
//clock and reset

rst,
//reset

clk,
//clock

din,
din_vld,
dout,
dout_vld
);
//interface parameter

//----------------------------------------------------------------------

//
PORT SIGNAL DEFINATION

//----------------------------------------------------------------------

//clock and reset

input
rst;
//reset

input
clk;
//clock

input
[7:0]
din;
input
din_vld;
output
dout;
output
dout_vld;
//----------------------------------------------------------------------

//
PORT SIGNAL TYPE

//----------------------------------------------------------------------

//clock and reset

wire
rst;
//reset

wire
clk;
//clock

wire
[7:0]
din;
wire
din_vld;
reg
dout;
reg
dout_vld;
//----------------------------------------------------------------------

//
INTERNAL SIGNAL DEFINATION

//----------------------------------------------------------------------

//阈值比较
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
dout_vld<=1'b0;
dout<=1'b0;
end
else
begin
dout_vld<=din_vld;
dout<=(din>100);
end
end
endmodule
/*******************************************************************************
*
*
*
(c) Copyright 1995-2017 TAIHO ELE Co,Ltd.
*
*
All rights reserved.
*
*
*
********************************************************************************
*
*
FileName
:
gray2local_bin.v
*
Abstract
:
This module is an example for coding.
*
Author
:
Mouhongbing
*
Version
:
1.1
*
Release
:
2022.10.11
*
Revision
:
*
Version Date
Author
Modification description
*
1.0
Mouhongbing
2022.10.11
*
******************************************************************************/
`timescale 1ns/100ps
//----------------------------------------------------------------------

//
MODULE DEFINTION

//----------------------------------------------------------------------

module gray2local_bin
(
//clock and reset

rst,
//reset

clk,
//clock

din,
din_vld,
dout,
dout_vld
);
//interface parameter

//----------------------------------------------------------------------

//
PORT SIGNAL DEFINATION

//----------------------------------------------------------------------

//clock and reset

input
rst;
//reset

input
clk;
//clock

input
[7:0]
din;
input
din_vld;
output
dout;
output
dout_vld;
//----------------------------------------------------------------------

//
PORT SIGNAL TYPE

//----------------------------------------------------------------------

//clock and reset

wire
rst;
//reset

wire
clk;
//clock

wire
[7:0]
din;
wire
din_vld;
reg
dout;
reg
dout_vld;
//----------------------------------------------------------------------

//
INTERNAL SIGNAL DEFINATION

//----------------------------------------------------------------------

wire
[7:0]
row1_data;
wire
[7:0]
row2_data;
wire
[7:0]
row3_data;
wire
[7:0]
row1_data_r;
wire
[7:0]
row2_data_r;
//有效值
reg
[3:0]
vld;
//3*3
reg
[7:0]
row1_1;
reg
[7:0]
row1_2;
reg
[7:0]
row1_3;
reg
[7:0]
row2_1;
reg
[7:0]
row2_2;
reg
[7:0]
row2_3;
reg
[7:0]
row3_1;
reg
[7:0]
row3_2;
reg
[7:0]
row3_3;
//sum
reg
[12:0]
sum;
//阈值
reg
[7:0]
thresh;
//中心值延迟
reg
[7:0]
value_delay1;
reg
[7:0]
value_delay2;
//3*3滑动窗口
parameter
NUM = 5'd9;
//缓存三行 第一级流水
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
row1_1<=1'b0;row1_2<=1'b0;row1_3<=1'b0;
row2_1<=1'b0;row2_2<=1'b0;row2_3<=1'b0;
row3_1<=1'b0;row3_2<=1'b0;row3_3<=1'b0;
end
else if(vld[0]==1'b1)
begin
row1_1<=row1_data;row1_2<=row1_1;row1_3<=row1_2;
row2_1<=row2_data;row2_2<=row2_1;row2_3<=row2_2;
row3_1<=row3_data;row3_2<=row3_1;row3_3<=row3_2;
end
end
//第二级流水sum 
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)begin
sum<= 13'b0;
end
else if(vld[1]==1'b1)begin
sum<=row1_1+row1_2+row1_3+row2_1+row2_2+row2_3+row3_1+row3_2+row3_3;
end
end
//第三级流水均值+k
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)begin
thresh <= 8'b0;
end
else if(vld[2]==1'b1)begin
thresh <= (sum+{sum,3'b0})>>7;//取近似 sum*0.9/NUM~sum*9/96
>>6 >>5
NUM==9
//thresh <= sum>>3;
end
end
//vld
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
vld<=4'b0;
end
else
begin
vld<={vld[2:0],din_vld};
end
end
//dout_vld
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
dout_vld<=1'b0;
end
else
begin
dout_vld<=vld[3];
end
end
//输出阈值大于thresh输出1
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
dout<=1'b0;
end
else if(thresh<value_delay2)
begin
dout<=1'b1;
end
else
begin
dout<=1'b0;
end
end
//当前中心值
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
value_delay1<=8'b0;
value_delay2<=8'b0;
end
else
begin
value_delay1<=row2_2;
value_delay2<=value_delay1;
end
end
assign row1_data=row1_data_r;
assign row2_data=row2_data_r;
assign row3_data=din;
c_shift_ram_1 u_shift_ram_0 (
.D(din),
// input wire [0 : 0] D
.CLK(clk),
// input wire CLK
.SCLR(rst),
// input wire SCLR
.Q(row2_data_r)
// output wire [0 : 0] Q
);
c_shift_ram_1 u_shift_ram_1 (
.D(row2_data_r),
// input wire [0 : 0] D
.CLK(clk),
// input wire CLK
.SCLR(rst),
// input wire SCLR
.Q(row1_data_r)
// output wire [0 : 0] Q
);
endmodule

效果展示:
在这里插入图片描述
如果换张图片带有阴影:
在这里插入图片描述
会是怎样呢?

边缘检测(sobel)

Sobel算子主要用于检测图像边缘,在物体的边缘通常都有像素的变化,反映了物体与背景之间的差异,或者两个物体之间的差异。它是一个离散差分算子,用来计算像素点上下、左右领域内像素点的加权差,根据在边缘处达到极值来检测边缘。另外,Sobel算子对噪声也有一定的平滑作用,检测出精确的边缘信息,但是边缘定位精度不高。
Sobel算子在水平方向和垂直方向各采用一个模板,检测各方向上的边缘,其优点是计算简单,速度快;但是对于纹理较为复杂的图像,检测效果不理想。水平方向模板Sx和垂直方向模板Sy如下:
在这里插入图片描述
在这里插入图片描述

图像中每个像素点对应的梯度值按照以下公式计算:
在这里插入图片描述
图像中每个像素点对应的梯度值按照以下公式计算:
在这里插入图片描述

/*******************************************************************************
*
*
*
(c) Copyright 1995-2017 TAIHO ELE Co,Ltd.
*
*
All rights reserved.
*
*
*
********************************************************************************
*
*
FileName
:
sobel.v
*
Abstract
:
This module is an example for coding.
*
Author
:
Mouhongbing
*
Version
:
1.1
*
Release
:
2022.10.8
*
Revision
:
*
Version Date
Author
Modification description
*
1.0
Mouhongbing
2022.10.8
*
******************************************************************************/
`timescale 1ns/100ps
//----------------------------------------------------------------------

//
MODULE DEFINTION

//----------------------------------------------------------------------

module sobel
(
//clock and reset

rst,
//reset

clk,
//clock

din,
//输入二值化图像
din_vld,
dout,
dout_vld
);
//interface parameter

//----------------------------------------------------------------------

//
PORT SIGNAL DEFINATION

//----------------------------------------------------------------------

//clock and reset

input
rst;
//reset

input
clk;
//clock

input
din;
input
din_vld;
output
dout;
output
dout_vld;
//----------------------------------------------------------------------

//
PORT SIGNAL TYPE

//----------------------------------------------------------------------

//clock and reset

wire
rst;
//reset

wire
clk;
//clock

wire
din;
wire
din_vld;
reg
dout;
reg
dout_vld;
//----------------------------------------------------------------------

//
INTERNAL SIGNAL DEFINATION

//----------------------------------------------------------------------

wire
row1_data;
wire
row2_data;
wire
row3_data;
wire
row1_data_r;
wire
row2_data_r;
//有效值
reg
[3:0]
vld;
//3*3
reg
row1_1;
reg
row1_2;
reg
row1_3;
reg
row2_1;
reg
row2_2;
reg
row2_3;
reg
row3_1;
reg
row3_2;
reg
row3_3;
//x, y sum
reg
[2:0]
x0_sum;
reg
[2:0]
x2_sum;
reg
[2:0]
y0_sum;
reg
[2:0]
y2_sum;
//x,y abs
reg
[2:0]
x_abs;
reg
[2:0]
y_abs;
//阈值
reg
[2:0]
g;
//缓存三行 第一级流水
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
row1_1<=1'b0;row1_2<=1'b0;row1_3<=1'b0;
row2_1<=1'b0;row2_2<=1'b0;row2_3<=1'b0;
row3_1<=1'b0;row3_2<=1'b0;row3_3<=1'b0;
end
else if(vld[0]==1'b1)
begin
row1_1<=row1_data;row1_2<=row1_1;row1_3<=row1_2;
row2_1<=row2_data;row2_2<=row2_1;row2_3<=row2_2;
row3_1<=row3_data;row3_2<=row3_1;row3_3<=row3_2;
end
end
//第二级流水
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)begin
x0_sum <= 3'b0;
x2_sum <= 3'b0;
y0_sum <= 3'b0;
y2_sum <= 3'b0;
end
else if(vld[1]==1'b1)begin
x0_sum <= {2'd0,row1_1} + {1'd0,row1_2,1'd0} + {2'd0,row1_3};
x2_sum <= {2'd0,row3_1} + {1'd0,row3_2,1'd0} + {2'd0,row3_3};
y0_sum <= {2'd0,row1_1} + {1'd0,row2_1,1'd0} + {2'd0,row3_1};
y2_sum <= {2'd0,row1_3} + {1'd0,row2_3,1'd0} + {2'd0,row3_3};
end
end
//第三级流水abs
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)begin
x_abs <= 3'b0;
y_abs <= 3'b0;
end
else if(vld[2]==1'b1)begin
x_abs <= (x0_sum >= x2_sum)?(x0_sum-x2_sum):(x2_sum-x0_sum);
y_abs <= (y0_sum >= y2_sum)?(y0_sum-y2_sum):(y2_sum-y0_sum);
end
end
//第四级流水计算梯度
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)begin
g <= 3'b0;
end
else if(vld[3]==1'b1)begin
g <= x_abs + y_abs;//绝对值之和 近似 平方和开根号
end
end
//vld
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
vld<=4'b0;
end
else
begin
vld<={vld[2:0],din_vld};
end
end
//dout_vld
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
dout_vld<=1'b0;
end
else
begin
dout_vld<=vld[3];
end
end
//输出阈值大于3输出1
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
dout<=1'b0;
end
else if(g>2)
begin
dout<=1'b1;
end
else
begin
dout<=1'b0;
end
end
assign row1_data=row1_data_r;
assign row2_data=row2_data_r;
assign row3_data=din;
c_shift_ram_0 u_shift_ram_0 (
.D(din),
// input wire [0 : 0] D
.CLK(clk),
// input wire CLK
.SCLR(rst),
// input wire SCLR
.Q(row2_data_r)
// output wire [0 : 0] Q
);
c_shift_ram_0 u_shift_ram_1 (
.D(row2_data_r),
// input wire [0 : 0] D
.CLK(clk),
// input wire CLK
.SCLR(rst),
// input wire SCLR
.Q(row1_data_r)
// output wire [0 : 0] Q
);
endmodule

效果展示
在这里插入图片描述

顶层文件

/*******************************************************************************
*
*
*
(c) Copyright 1995-2017 TAIHO ELE Co,Ltd.
*
*
All rights reserved.
*
*
*
********************************************************************************
*
*
FileName
:
top.v
*
Abstract
:
This module is an example for coding.
*
Author
:
Mouhongbing
*
Version
:
1.1
*
Release
:
2022.9.23
*
Revision
:
*
Version Date
Author
Modification description
*
1.0
Mouhongbing
2022.9.23
*
******************************************************************************/
`timescale 1ns/100ps
//----------------------------------------------------------------------

//
MODULE DEFINTION

//----------------------------------------------------------------------

module top
(
//clock and reset

rst,
//reset

clk,
//clock

rgb_din,
//
din_vld,
rgb_out,
//
dout_vld
);
//interface parameter

//----------------------------------------------------------------------

//
PORT SIGNAL DEFINATION

//----------------------------------------------------------------------

//clock and reset

input
rst;
//reset

input
clk;
//clock

input
[23:0]
rgb_din;
input
din_vld;
output
[23:0]
rgb_out;
output
dout_vld;
//----------------------------------------------------------------------

//
PORT SIGNAL TYPE

//----------------------------------------------------------------------

//clock and reset

wire
rst;
//reset

wire
clk;
//clock

wire
[23:0]
rgb_din;
wire
din_vld;
reg
[23:0]
rgb_out;
reg
dout_vld;
//----------------------------------------------------------------------

//
INTERNAL SIGNAL DEFINATION

//----------------------------------------------------------------------

//灰度
wire	[7:0]	dout_gray;
wire
gray_vld;
//高斯滤波
wire
[7:0]
dout_gauss;
wire
gauss_vld;
//二值化
wire
dout_bin;
wire
bin_vld;
//sobel
wire
dout_sobel;
wire
sobel_vld;
//灰度转化
rgb2gray u_rgb2gray
(
//clock and reset

.rst
(rst
),
//reset

.clk
(clk
),
//clock 
.din
(rgb_din
),
.din_vld
(din_vld
),
.dout
(dout_gray
),
.dout_vld
(gray_vld
)
);
//对灰度图进行高斯滤波
//gauss u_gauss
//(
//
//clock and reset
//
.rst
(rst
),
//reset
//
.clk
(clk
),
//clock
//
//
.din
(dout_gray ),
//
.din_vld
(gray_vld
),
//
//
.dout
(dout_gauss),
//
.dout_vld
(gauss_vld )
//);

//灰度转全局二值化
gray2bin u_gray2bin
(
//clock and reset

.rst
(rst
),
//reset

.clk
(clk
),
//clock

.din
(dout_gray
),
.din_vld
(gray_vld	),
.dout
(dout_bin	),
.dout_vld
(bin_vld
)
);
//局部二值化
//gray2local_bin u_gray2local_bin
//(

//
//clock and reset

//
.rst
(rst
),
//reset

//
.clk
(clk
),
//clock

//

//
.din
(dout_gray
),
//
.din_vld
(gray_vld	),
//
//
.dout
(dout_bin	),
//
.dout_vld
(bin_vld
)

//

//);

//sobel
sobel u_sobel
(
//clock and reset

.rst
(rst
),
//reset

.clk
(clk
),
//clock

.din
(dout_bin
),
//输入二值化图像
.din_vld
(bin_vld	),
.dout
(dout_sobel ),
.dout_vld
(sobel_vld
)
);
always@(posedge clk,posedge rst)
begin
if(rst==1'b1)
begin
rgb_out<=24'b0;
dout_vld<=1'b0;
end
else
begin
rgb_out<={24{dout_sobel}};
dout_vld<=sobel_vld;
//
rgb_out<={3{dout_gauss}};
//
dout_vld<=gauss_vld;
end
end
endmodule

改进中- - - -

最后

以上就是外向路人为你收集整理的FPGA-图像处理-仿真说明图片读取和写入灰度转换高斯滤波二值化边缘检测(sobel)顶层文件改进中- - - -的全部内容,希望文章能够帮你解决FPGA-图像处理-仿真说明图片读取和写入灰度转换高斯滤波二值化边缘检测(sobel)顶层文件改进中- - - -所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部