opencv源码之中值滤波medianBlur_SortNet解读

news2025/1/11 6:02:25

背景

中值滤波,最大值滤波,最小值滤波属于排序滤波,常用于图像去噪处理。

最大/小值滤波的处理比较好理解,就是逐个比较窗口内的每个数字,每次比较会根据所属任务保留最大值,或最小值。假设滑动窗口是3*3,则窗口内9个数进行8次比较,就能得到最大/小值滤波的一个结果。

中值滤波,顾名思义,指的是对窗口内的数取中值,作为滤波处理的结果。如果不考虑优化的实现思路,就是把窗口内所有元素进行排序,然后取中间的值,排序算法的时间复杂度最小的是nlog(n),也就是需要进行n*log(n)次比较,当n=9时候,对全部数据进行排序需要进行至少27次比较。

实际上,中值滤波只需要知道窗口内的中值是几,而不需要对全部数据进行排序,基于这样的考虑,就能减少比较的次数。

opencv源码解读

中值滤波在opencv的源码路径是:modules/imgproc/src/smooth.cpp中。源码附在最后了。

opencv的中值滤波实现支持3*3, 5*5的滤波尺寸。通过定义排序网络实现中值滤波。

排序网络的设计思想是定义两种比较器:一种是OP,OP算子实现的是传入两个数a,b, 通过OP比较器后将a,b中大的数赋值给b, 小的数赋值给a;另一中比较器是VOP,VOP则是指传入的va,vb是具有相同元素的向量,同OP一样,向量中元素一一对应相比较,大数存放在vb中,小数存放在va中。这种VOP是指计算机支持硬件加速的话,会打开useSIMD的开关,使用CPU指令集加速任务进度。

如下图,源码的核心是如下定义比较器,当窗口为3*3时候,只进行了19次比较,就得到了中值。为什么能这样呢?这里就用到了算法的思想。

简化后的算法问题是,给9个数,如何通过最少的比较次数,得到这9个数的中值。

关于比较次数的三分法理解

https://www.cnblogs.com/olivermahout/p/9346353.html介绍了采用三分法的原理,对于每一行进行比较,然后再通过一轮比较得到最终结果。对于9个数字取中位数一共只用到了21个两两比较器。

如下图

1,第一轮比较,9次。 A 1是指对第1行的3个数排序比较,A2是对第2行的3个数进行排序比较,A3是对第3行的3个数进行排序比较;

2, 第二轮比较,9次。B1汇聚了A1,A2,A3的最大值,B2汇聚了A1,A2,A3的中间值,B3汇聚了A1,A2,A3的最小值。将B1,B2,B3中的三个数进行比较。

3, 第三轮比较,3次。C汇聚了B1,B2,B3中的分别最小值,中间值,最大值。比较C中3个值的大小,输出中间值,就是这9个数的中值。

这里,你肯定好奇,为什么B1,B2,B3是这样取A1,A2,A3的比较结果,C这样取B1,B2,B3的比较结果呢?为什么这样设计得到的就是这9个数的中值呢?下面结合opencv的代码设计来解释。

关于比较次数的opencv设计理解

opencv的比较器比上面3分法的比较次数少了2次,9个数进行19次两两比较就能得到中值。但是实际的思路是一样。优化的点在于B1,B3中的比较分别是少了1次。

opencv的整体思路是进行了4轮比较(ps:不相关的数的比较可以设计并行执行):

第1轮,把三行数,每行内的3个数进行排序;

第2轮,排除掉9个数中的两个是中值的可能;

第3轮,排除掉剩余7个数中的4个是中值的可能;

第4轮,比较剩余的3个数,排除掉2个,找到中值。

推理如下:

理解前提:

  1. n是奇数,给n个数取中值,当确定某个数是大于(n+1)/2个数或者小于(n+1)/2个数时候,该数不可能是中值。

  1. op(a,b)的定义: 传入a,b的地址,比较a,b两个地址上的数,将较大的数放在b地址上,较小的数放在a地址上。

第1轮比较。这一轮比较,完成了3行数据,每行内的大小排列,即此时p0≤p1≤p2,p3≤p4≤p5,p6≤p7≤p8

op(p1, p2); op(p4, p5); op(p7, p8);

op(p0, p1);op(p3, p4); op(p6, p7);

op(p1, p2); op(p4, p5);op(p7, p8);

第2轮比较。这一轮比较,可以把p0, p8排除是中值的可能。

op(p0, p3); op(p5, p8);

P0: p0至少小于5个数,所以可排除可能。

P8: p0至少大于5个数,所以可排除可能。

第3轮比较。这一轮比较:把P1, P3, P5, P7排除是中值的可能。

op(p4, p7);op(p3, p6);op(p2, p5);

op(p1, p4);

op(p4, p7);

P1: 在前2轮比较中,P2, P5至少大于P1,P4,P7这三个数的两个,这一轮中P1又是P1,P4,P7三个数中的最小数,所以P1小于至少4个数(P2, P5,P4,P7)。排除P1是中值的可能。

P3: 在前2轮比较中,P3小于P4,P5或者P1, P2,这一轮中,P3又是P3, P6,P7中的最小值,所以P3至少小于4个数(P6, P7,(P4,P5)或(P1,P2))。排除P3是中值的可能。

P5: 在前2轮比较中,P5大于P4,P3或者P6, P7,而P2大于P1,至此,P2,P5至少大于3个数了。 这一轮中,P5又是P2, P5中的最大值,所以P5至少大于4个数(P1, P2,(P4,P3)或(P6,P7))。排除P5是中值的可能。

P7: 在前2轮比较中,至少P1,P4,P7这三个数的两个大于P3, P6,这一轮中P7又是P1,P4,P7三个数中的最大数,所以P7大于至少4个数(P1, P3,P4,P6)。排除P7是中值的可能。

第4轮比较。这一轮比较中,3个数找到中间值,需要进行2次比较。得到P4就是中值。

op(p4, p2); op(p6, p4); op(p4, p2);

最后

对于窗口是5*5的中值滤波,比较次数更多,但是实现思想和3*3是一样的。

怎么样,可能这就是算法优化的极致了吧,能少比较1次也是好的。*^ ^*

Opencv源码

放上opencv的源码,不用再辛苦去找了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/146293.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

固体物理分子模拟实验(二)MPI的安装

固体物理分子模拟实验(二)MPI的安装 文章目录固体物理分子模拟实验(二)MPI的安装前言一、MPI是什么?二、安装步骤(Ubuntu22.04mpich-4.0.2)1、下载mpich解压包2、安装前置组件3、文件配置&#…

【一文讲通】如何检测数据满足同分布

1 统计指标的方法1.1群体稳定性指标(Population Stability Index,PSI)群体稳定性指标(Population Stability Index,PSI), 衡量未来的样本(如测试集)及训练样本评分的分布…

【Linux】基础开发工具使用 --- vim

目录 前言 vim的基本概念 具体操作 插入模式 命令模式下的指令 底行模式下的指令 vim的配置 前言 🍧了解了 Linux 的一些基本的指令之后若要在 Linux 上进行程序的编写,除了 nano 以外,我们还可以选择 vim 进行编写。而 vim 是 vi 升级…

OJ万题详解––孤独的照片(C++详解)

题目 题目描述 Farmer John 最近购入了 N 头新的奶牛(),每头奶牛的品种是更赛牛(Guernsey)或荷斯坦牛(Holstein)之一。 奶牛目前排成一排,Farmer John 想要为每个连续不少于三头奶牛的序列拍摄一张照片。 然…

0107-JAVA和JDK的区别

前言 因为工作需要现在也不得不接触后端java语言,对于java和jdk一直存在疑惑,今天就详细总结一下 1.什么是java 人话就是java是一门后端脚本语言和PHP一样 2.什么是jdk JDK的全称是Java Development Kit,直译就是:Java开发工…

真实地址查询——DNS

通过浏览器解析 URL 并生成 HTTP 消息后,需要委托操作系统将消息发送给 Web 服务器。但在发送之前,还有一项工作需要完成,那就是查询服务器域名对应的 IP 地址,因为委托操作系统发送消息时,必须提供通信对象的 IP 地址…

java 基础 - 泛型

泛型 术语中文含义举例Parameterized type参数化的类型ListActual typeparameter实际类型参数StringGeneric type泛型类型ListFormal typeparameter形式类型参数 EUnbounded wildcard type无限制通配符类型List<?>Raw type原始类型ListBounded type parameter有限制类型…

Vue--》Vue3给数据共享增添的改变

目录 数据共享 父向子共享数据 子向父共享数据 父子组件间数据双向同步 兄弟组件共享数据 后代组件共享数据 使用Vue3的setup函数实现后代数据共享 数据共享 在项目开发中&#xff0c;组件之间的关系分为如下3种&#xff1a;父子关系、兄弟关系、后代关系。 父向子共享…

FPGA学习笔记(十二)IP核之FIFO的学习总结

系列文章目录 一、FPGA学习笔记&#xff08;一&#xff09;入门背景、软件及时钟约束 二、FPGA学习笔记&#xff08;二&#xff09;Verilog语法初步学习(语法篇1) 三、FPGA学习笔记&#xff08;三&#xff09; 流水灯入门FPGA设计流程 四、FPGA学习笔记&#xff08;四&…

机器人/人工智能/就业形势2023

机器人/人工智能/就业形势2022https://blog.csdn.net/ZhangRelay/article/details/124441772机器人人工智能课程需求和就业趋势-2022-https://blog.csdn.net/ZhangRelay/article/details/127087308如上已成往事。2023年如何呢&#xff1f;之前文章都过于简洁&#xff0c;很多朋…

浅谈 MySQL 的 Undo log 日志

undo log 存储在类型为 FIL_PAGE_UNDO_LOG 页中。 可以从系统表空间中分配空间&#xff0c;也可以从 undo tablespace 中分配空间。 FIL_PAGE_UNDO_LOG 类型页主要分为四部分&#xff1a; File Header&#xff0c;所有页都有的结构Undo Page Header TRX_UNDO_PAGE_TYPE&#x…

十一、docker相关问题解决方案

&#x1f33b;&#x1f33b;一、创建tomcat失败报348 问题二、端口监听问题&#xff0c;没安装命令三、非正常关闭电脑导致虚拟机无法启动一、创建tomcat失败报348 问题 创建失败问题&#xff1a; docker: Error response from daemon: OCI runtime create failed: container…

通用vue组件化搜索组件页面

一、组件化封装 1.首先创建一个form文件夹&#xff0c;将搜索框组件的内容全部写在这个里面&#xff0c;然后再在需要的页面直接引入相应的组件即可 2.首先先在goods.vue文件里面写对应的文本数组formItems&#xff0c;将所定义的类型IFormItem引用进去&#xff0c;这个里面写…

coresight(五) rom table

五、 rom table 在一个soc中&#xff0c;有多个coresight组件&#xff0c;但是软件怎么去识别这些coresight组件&#xff0c;去获取这些coresight组件的信息了&#xff1f;这个时候&#xff0c;就需要靠coresight组件中&#xff0c;一个重要的组件&#xff0c;这个组件就是rom …

CMD有哪些有趣的命令?

程序员宝藏库&#xff1a;https://gitee.com/sharetech_lee/CS-Books-Store 用惯Linux和macOS的同学都会对各种各样强大的命令印象深刻&#xff0c;然而再转向Windows时就开始不屑一顾&#xff0c;认为Windows上没有Linux上那些超级便捷好用的命令。 其实&#xff0c;Windows下…

ROS安装及rosdep update问题解决

ROS安装&#xff1a; 参考链接&#xff1a;详细介绍如何在ubuntu20.04中安装ROS系统&#xff0c;以及安装过程中出现的常见错误的解决方法&#xff0c;填坑&#xff01;&#xff01;&#xff01;_慕羽★的博客-CSDN博客_ubuntu20.04安装ros rosdep update问题解决&#xff1a…

Linux Shell 脚本编程基础

Shell是一个命令解释器,它解释由用户输入的命令并且把它们送到内核,不仅如此,Shell有自己的编程语言用于对命令的编辑,它允许用户编写由shell命令组成的程序.Shel编程语言具有普通编程语言的很多特点,比如它也有循环结构和分支控制结构等,用这种编程语言编写的Shell程序与其他应…

Selenium用法详解【窗口表单切换】【JAVA爬虫】

简介本文主要讲解java 代码利用Selenium如何实现控制浏览器进行窗口切换和页面内的不同表单之间的切换操作。切换操作窗口切换在 selenium 操作页面的时候&#xff0c;可能会因为点击某个链接而跳转到一个新的页面&#xff08;打开了一个新标签页&#xff09;&#xff0c;这时候…

电子词典流程图

简易流程&#xff1a; 详细介绍 服务端&#xff08;TCP并发&#xff09; 一.分支线程负责处理客户端发送的信息 1.登陆与注册信息 登陆&#xff08;l&#xff09;;注册&#xff08;e&#xff09; (1)登陆根据接收的用户名&#xff0c;密码在用户注册表中遍历是否符合&#xff…

ORB-SLAM2 --- ORBmatcher::SearchBySim3函数

目录 1.函数作用 2.函数流程 3.函数解析 3.1 准备工作&#xff1a;内参&#xff0c;计算Sim3的逆 3.2 记录已经匹配的特征点 3.3 通过Sim变换&#xff0c;寻找 pKF1 中特征点和 pKF2 中的新的匹配 3.4 通过Sim变换&#xff0c;寻找 pKF2 中特征点和 pKF1 中的新的匹…