基于FPGA的图像中值滤波原理与实现
图像中值滤波的FPGA实现
- 项目简述
- 中值滤波器原理
- 中值滤波器的实现
- 测试模块的代码
- 仿真结果
- 下板结果
- 总结
项目简述
中值滤波器在去除尖端噪声中非常重要,是信号处理中最长用到的滤波器。图像中的一些椒盐噪声或者其它突变比较大的噪声可以使用中值滤波器去除,所以这篇文章我们来讲解FPGA实现图像的中值滤波。本次项目的简述如下:PC机通过千兆以太网发送到FPGA开发板中,然后经过中值滤波缓存进DDR3中,最后经过DDR3发送到上位机中显示。
本次实验所用到的软硬件环境如下:
1、VIVADO2019.1软件环境
2、Modelsim10.7c仿真环境
3.米联客MA7035FA(100T)开发板
4、米联客USB3.0上位机软件
中值滤波器原理
图像信号在形成、传输和记录的过程中,由于成像系统、 传输介质、 工作环境和记录设备等的固有缺陷,不可避免地产生各种类型的噪声,降低了图像的质量,进而影响后续处理(如边缘检测、图像分割、特征提取、模式识别等)的效果或准确性。因此,对噪声图像进行滤波是必要预处理过程。
这里需要注意中值滤波基于排序统计理论,是抑制噪声的***非线性信号处理技术***。其核心运算是以模板中的数据进行排序,使得某个亮点(暗点)的噪声在排序过程中被排在数据序列的两侧。因为数据序列中间位置上的值一般不是噪声点的值,从而达到抑制噪声的目的。
假设有图像 A, 对其进行中值滤波, 即求出该 3x3 矩阵中的排序在中间位置的那个值。
当然前面的文章中我们已经详细讲解了3*3矩阵的构建方法,那么这篇文章,我们主要集中在找上面图像矩阵中的中值,然后代替图像的数据。方法一,是对上面的矩阵进行硬件排序,硬件排序的效率非常高,但是理解与实现起来较困难,我会在后面的专门的文章中进行相应的讲解。第二种方法就是两两找最大值的方法,对齐介绍如下:
第一步: 分别求出 3 行中同一行的最大值、 最小值、 中间值
设 max_h1 为第一行的最大值, min_h1 为第一行的最小值, mid_h1 为第一
行的中间值。
同理有 max_h2, mid_h2, min_h2, max_h3, mid_h3, min_h3。
第二步: 3 行的最大值、 最小值、 中间值进行比较
max_h1, m2ax_h2, max_h3 这 3 个值比较, 得到这 3 个值的最小值 min_max。
mid_h1, mid_h2, mid_h3 这 3 个值比较, 得到这 3 个值的中间值 mid_mid。
min_h1, min_h2, min_h3 这 3 个值比较, 得到这 3 个值的最大值 max_min。
第三步: 得到 3x3 矩阵的中间值
将第二步得到的 min_max, mid_mid, max_min 进行比较, 得到的中间值,
即该 3x3 矩阵的中间值。
至于为什么上面找到的值就是图像矩阵的中值,同学们可以试着分别对上面 max_h1 ,mid_h1 ,max_h1 ,max_h2, mid_h2, min_h2, max_h3, mid_h3, min_h3进行排序的大体范围判断。然后,就可以发现排序第5位的数据就在min_max, mid_mid, max_min的中间值。
中值滤波器的实现
这里因为简单的数学关系,我们同样不再给出时序图,而是直接会给出相应的代码:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : sobel.v
// Create Time : 2020-04-08 08:32:02
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************module sobel(//System Interfacesinput sclk ,input rst_n ,//Communication Interfacesinput [ 7:0] rx_data ,input pi_flag ,output reg [ 7:0] tx_data ,output reg po_flag
);//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
parameter COL_NUM = 1024 ;
parameter ROW_NUM = 768 ;
parameter VALUE = 80 ;wire [ 7:0] mat_row1 ;
wire [ 7:0] mat_row2 ;
wire [ 7:0] mat_row3 ;
wire mat_flag ;
reg [ 7:0] mat_row1_1 ;
reg [ 7:0] mat_row2_1 ;
reg [ 7:0] mat_row3_1 ;
reg [ 7:0] mat_row1_2 ;
reg [ 7:0] mat_row2_2 ;
reg [ 7:0] mat_row3_2 ;
reg mat_flag_1 ;
reg mat_flag_2 ;
reg mat_flag_3 ;
reg mat_flag_4 ;
reg mat_flag_5 ;
reg mat_flag_6 ;
reg mat_flag_7 ;reg [ 7:0] max_h1 ;
reg [ 7:0] mid_h1 ;
reg [ 7:0] min_h1 ;
reg [ 7:0] max_h2 ;
reg [ 7:0] mid_h2 ;
reg [ 7:0] min_h2 ;
reg [ 7:0] max_h3 ;
reg [ 7:0] mid_h3 ;
reg [ 7:0] min_h3 ;
reg [ 7:0] min_max ;
reg [ 7:0] mid_mid ;
reg [ 7:0] max_min ; //========================================================================================\
//************** Main Code **********************************
//========================================================================================/
always @(posedge sclk)beginmat_row1_1 <= mat_row1;mat_row2_1 <= mat_row2;mat_row3_1 <= mat_row3;mat_row1_2 <= mat_row1_1;mat_row2_2 <= mat_row2_1;mat_row3_2 <= mat_row3_1;endalways @(posedge sclk)beginmat_flag_1 <= mat_flag; mat_flag_2 <= mat_flag_1; mat_flag_3 <= mat_flag_2; mat_flag_4 <= mat_flag_3; mat_flag_5 <= mat_flag_4; mat_flag_6 <= mat_flag_5; mat_flag_7 <= mat_flag_6; endalways @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)max_h1 <= 8'd0; else if(mat_row1 >= mat_row1_1 && mat_row1 >= mat_row1_2)max_h1 <= mat_row1;else if(mat_row1_1 >= mat_row1 && mat_row1_1 >= mat_row1_2) max_h1 <= mat_row1_1;elsemax_h1 <= mat_row1_2;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)mid_h1 <= 8'd0; else if((mat_row1 >= mat_row1_1 && mat_row1_1 >= mat_row1_2) || (mat_row1_2 >= mat_row1_1 && mat_row1_1 >= mat_row1))mid_h1 <= mat_row1_1;else if((mat_row1_1 >= mat_row1 && mat_row1 >= mat_row1_2) || (mat_row1_2 >= mat_row1 && mat_row1 >= mat_row1_1))mid_h1 <= mat_row1;elsemid_h1 <= mat_row1_2;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)min_h1 <= 8'd0; else if(mat_row1 <= mat_row1_1 && mat_row1 <= mat_row1_2)min_h1 <= mat_row1;else if(mat_row1_1 <= mat_row1 && mat_row1_1 <= mat_row1_2) min_h1 <= mat_row1_1;elsemin_h1 <= mat_row1_2; always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)max_h2 <= 8'd0; else if(mat_row2 >= mat_row2_1 && mat_row2 >= mat_row2_2)max_h2 <= mat_row2;else if(mat_row2_1 >= mat_row2 && mat_row2_1 >= mat_row2_2) max_h2 <= mat_row2_1;elsemax_h2 <= mat_row2_2;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)mid_h2 <= 8'd0; else if((mat_row2 >= mat_row2_1 && mat_row2_1 >= mat_row2_2) || (mat_row2_2 >= mat_row2_1 && mat_row2_1 >= mat_row2))mid_h2 <= mat_row2_1;else if((mat_row2_1 >= mat_row2 && mat_row2 >= mat_row2_2) || (mat_row2_2 >= mat_row2 && mat_row2 >= mat_row2_1))mid_h2 <= mat_row2;elsemid_h2 <= mat_row2_2;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)min_h2 <= 8'd0; else if(mat_row2 <= mat_row2_1 && mat_row2 <= mat_row2_2)min_h2 <= mat_row2;else if(mat_row2_1 <= mat_row2 && mat_row2_1 <= mat_row2_2) min_h2 <= mat_row2_1;elsemin_h2 <= mat_row2_2; always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)max_h3 <= 8'd0; else if(mat_row3 >= mat_row3_1 && mat_row3 >= mat_row3_2)max_h3 <= mat_row3;else if(mat_row3_1 >= mat_row3 && mat_row3_1 >= mat_row3_2) max_h3 <= mat_row3_1;elsemax_h3 <= mat_row3_2;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)mid_h3 <= 8'd0; else if((mat_row3 >= mat_row3_1 && mat_row3_1 >= mat_row3_2) || (mat_row3_2 >= mat_row3_1 && mat_row3_1 >= mat_row3))mid_h3 <= mat_row3_1;else if((mat_row3_1 >= mat_row3 && mat_row3 >= mat_row3_2) || (mat_row3_2 >= mat_row3 && mat_row3 >= mat_row3_1)) mid_h3 <= mat_row3;elsemid_h3 <= mat_row3_2;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)min_h3 <= 8'd0; else if(mat_row3 <= mat_row3_1 && mat_row3 <= mat_row3_2)min_h3 <= mat_row3;else if(mat_row3_1 <= mat_row3 && mat_row3_1 <= mat_row3_2) min_h3 <= mat_row3_1;elsemin_h3 <= mat_row3_2;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)min_max <= 8'd0;else if(max_h1 <= max_h2 && max_h1 <= max_h3)min_max <= max_h1;else if(max_h2 <= max_h1 && max_h2 <= max_h3)min_max <= max_h2;elsemin_max <= max_h3;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)mid_mid <= 8'd0;else if((mid_h1 >= mid_h2 && mid_h2 >= mid_h3) || (mid_h3 >= mid_h2 && mid_h2 >= mid_h1))mid_mid <= mid_h2;else if((mid_h2 >= mid_h1 && mid_h1 >= mid_h3) || (mid_h3 >= mid_h1 && mid_h1 >= mid_h2))mid_mid <= mid_h1;elsemid_mid <= mid_h3;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)max_min <= 8'd0;else if(min_h1 <= min_h2 && min_h1 <= min_h3) max_min <= min_h1;else if(min_h2 <= min_h1 && min_h2 <= min_h3)max_min <= min_h2;elsemax_min <= min_h3;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)tx_data <= 8'd0; else if((mid_mid >= min_max && min_max >= max_min) || (max_min >= min_max && min_max >= mid_mid))tx_data <= min_max;else if((min_max >= mid_mid && mid_mid >= max_min) || (max_min >= mid_mid && mid_mid >= min_max))tx_data <= mid_mid;elsetx_data <= max_min;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)po_flag <= 1'b0;else if(mat_flag_2 == 1'b1 && mat_flag_4 == 1'b1) po_flag <= 1'b1;elsepo_flag <= 1'b0; mat_3x3 mat_3x3_inst(//System Interfaces.sclk (sclk ),.rst_n (rst_n ),//Communication Interfaces.rx_data (rx_data ),.pi_flag (pi_flag ),.mat_row1 (mat_row1 ),.mat_row2 (mat_row2 ),.mat_row3 (mat_row3 ),.mat_flag (mat_flag ));endmodule
这里说明一下为了文章的简洁性,我们这里不再给出整个工程的代码,知识给出了中值滤波部分的程序。具体的项目工程代码查看前面的文章***基于FPGA的图像边缘检测***,至于要把这篇论文种的sobel模块换成上面的sobel便可以完成图像的中值滤波,至于这里取名字sobel也只是因为偷懒没改模块名。
测试模块的代码
测试模块的代码如下:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : tb_sobel.v
// Create Time : 2020-04-08 09:19:44
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************module tb_sobel();//System Interfaces
reg sclk ;
reg rst_n ;
//Communication Interfaces
reg [ 7:0] rx_data ;
reg pi_flag ;
wire [31:0] tx_data ;
wire po_flag ;
reg [ 1:0] cnt ; initial beginsclk = 1'b0;rst_n <= 1'b0;pi_flag <= 1'b0;rx_data <= 8'd0;#(1000);rst_n <= 1'b1;#(10000);gendata();#(10000);gendata();
end
always #5 sclk = ~sclk;task gendata();integer i ;integer j ;beginfor(j = 0;j < 768;j = j+1)beginfor(i = 0;i < 1024;i = i+1)beginpi_flag = 1'b1;#10; pi_flag = 1'b0;#20; endpi_flag = 1'b0;#1000;endend
endtaskalways @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)cnt <= 2'd0;else if(pi_flag == 1'b1 && cnt == 2'd2)cnt <= 2'd0;else if(pi_flag == 1'b1)cnt <= cnt + 1'b1;else cnt <= cnt;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)rx_data <= 8'd0;else if(cnt == 2'd2 && pi_flag == 1'b1 && rx_data == 1024-1) rx_data <= 8'd0;else if(cnt == 2'd2 && pi_flag == 1'b1)rx_data <= rx_data + 1'b1;elserx_data <= rx_data;//sobel sobel_inst(
// //System Interfaces
// .sclk (sclk ),
// .rst_n (rst_n ),
// //Communication Interfaces
// .rx_data (rx_data ),
// .pi_flag (pi_flag ),
// .tx_data (tx_data ),
// .po_flag (po_flag )
//);conver_bit conver_bit_inst(//System Interfaces.sclk (sclk ),.rst_n (rst_n ),//Gigbit Interfaces.image_data (rx_data ),.image_data_en (pi_flag ),//Communication Interfaces.rgb_data (tx_data ),.rgb_data_en (po_flag )
);endmodule
仿真结果
我们进行相应的仿真测试,结果如下:
从上图中的关键数据可以发现我们完成了图像的中值滤波。
下板结果
原图像如下:
FPGA中值滤波处理之后的图像如下:
从上面的图像中,我们可以发现图像中的突变噪声被消除,但是图像的边缘也被取消一部分,从而证明了我们实验的正确性。
总结
创作不易,认为文章有帮助的同学们可以关注、点赞、转发支持。(txt文件、图片文件在群中)对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
基于FPGA的图像中值滤波原理与实现相关推荐
- 【FPGA教程案例44】图像案例4——基于FPGA的图像中值滤波verilog实现,通过MATLAB进行辅助验证
FPGA教程目录 MATLAB教程目录 -------------------------------------------------------------------------------- ...
- 图像中值滤波python代码_图像中值滤波FPGA实现
C语言实用数字图像处理.pdf6.34 MB05-11-13|19:30 FPGA实验报告-李炎东.doc633.66 kB16-01-14|10:28 中值滤波在红外成像引信中的应用及硬件实现.ca ...
- OpenCV图像处理专栏九 | 基于直方图的快速中值滤波算法
转载自:https://zhuanlan.zhihu.com/p/98092747 侵删 前言 这是OpenCV图像处理专栏的第9篇文章,主要介绍一个基于直方图的快速中值滤波算法,希望对大家有帮助. ...
- 中值滤波原理及其代码实现
本文主要是对高斯滤波,中值滤波原理进行简单介绍,随后用代码实现高斯噪声和椒盐噪声.以及用高斯滤波和中值滤波对这两种图像进行相关的处理. 高斯噪声:就是服从高斯正态分布的噪声,通常是因为高温或者是传感器 ...
- 中值滤波原理及其C++实现与CUDA优化
对于数字图像的去噪,前边我们讲了均值滤波算法与高斯滤波算法,此外很常见的还有中值滤波算法,这些滤波算法都属于空间滤波,即对于每一个像素点,都选取其周围矩形区域中的像素点来计算滤波值.最近在项目中要使用 ...
- matlab图像处理-中值滤波原理
中值滤波原理 中值滤波本质上是一种统计排序滤波器.对于原图像中某点(i,j),中值滤波以该点为中心的邻域内的所有像素的统计排序中值作为(i,j)点的响应. 中值不同于均值,是指排序队列中位于中 ...
- java 中值滤波_matlab图像处理-中值滤波原理(示例代码)
中值滤波原理 ??中值滤波本质上是一种统计排序滤波器.对于原图像中某点(i,j),中值滤波以该点为中心的邻域内的所有像素的统计排序中值作为(i,j)点的响应. ??中值不同于均值,是指排序队列中位于中 ...
- 采用灰度分组统计方法实现图像中值滤波
中值滤波是图像处理中常用的一种噪声滤波方法.传统的图像中值滤波代码采用排序方法实现,处理速度主要取决于排序算法,但无论什么排序算法,总离不开大量的元素比较.交换或移动,而这些恰好是当前计算机处理的&q ...
- 使用c语言实现图像中值滤波,图像处理之中值滤波介绍及C实现
原标题:图像处理之中值滤波介绍及C实现 1.中值滤波概述 中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号平滑处理技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值. ...
最新文章
- vue实战第一课:天气查询
- 异常和异常处理(windows平台)
- SQL语言之创建数据库其他对象(视图)
- 端计算(2)-android studio 的sdk,avd,grade及其它缓存配置
- 分支限界法实现最优装载c++_分支限界法
- discuz回贴通知插件实现-配置邮件服务器
- 2017级面向对象程序设计 作业二
- 使用proguard混淆java web项目代码
- ollyice的学习
- magento URL分析,查找修改相应文件
- css display:box 新属性
- LVS+ldirector实现负载均衡
- Commons-VFS 使用SFTP
- 注解(Annotation)自定义注解入门(转)
- H264 SPS分析
- 【图像几何】基于matlab GUI图像空间变换(仿射变换)【含Matlab源码 841期】
- 2022上海Java工资收入概览
- 十四届恩智浦智能车竞赛双车组-星夜兼程队2019回顾
- #2014蓝桥杯-4.史丰收速算--------根本看不懂
- 计算机技术在排水领域的应用,计算机软件在排水工程设计上的应用解析
热门文章
- A Crash Course on the Depths of Win32 Structured Exception
- 医械围城的觉醒时刻:从“乱世枭雄” 到“剩者为王”
- linux sdk 封装,集成方式-Linux开发集成-SDK开发集成-IM即时通讯-网易云信开发文档...
- 港科夜闻|叶玉如校长回应「香港创科发展蓝图」
- MATLAB基础-矩阵输入
- 全景相机行业重点企业竞争格局分析及市场销售规模前景预测
- 织物缝纫的一些知识总结
- 基于HTML+CSS实现的静态的电影网站【100010106】
- 负债累累怎样白手起家?
- 小程序云开发如何不使用它提供的模板