从matlab的bwmorph函数的'majority'参数中扩展的一种二值图像边缘光滑的实时算法。
在matlab的图像处理工具箱中,有一系列关于Binary Images的处理函数,都是以字母bw开头的,其中以bwmorph函数选项最为丰富,一共有'bothat'、'branchpoints'、'bridge'、'clean'、'close'等十几个方法,其中像骨骼化、细化等常见的功能也集成在这个函数里,同常规的写法一样,这些算法都是需要迭代的,因此,这个函数也有个迭代次数的参数。那么另外一些算子,比如clean、diag、remove等等其实都是基于3*3或者5*5领域的,而其中的'erode'、'open'也只是基于3*3的,因此和真正的常用的腐蚀和膨胀还有所不同,那个需要使用imopen或者imclose实现。实际上,这些基于3*3或者5*5的小算子,他们对于二值图基本上就是用一次结果接没有变换,几迭代次数多了也没有啥用。那几个图测试下其中几个算子的效果:

原图 Remove模式

Fill模式 Clean模式
这些效果都比较平淡,其中Remove的效果和bwperim非常类似,就是提取二值图的边缘。Fill的作用就是填充图像中面积为1的黑色封闭区域,Clean是填充面积为1的白色封闭区域,他们不管你循环迭代多少次,结果和循环1次都是一样的,因此,感觉作用有限。
另外,还有一个比较有意思的参数,即'majority’参数,matlab的帮助文档对其解释是:
Sets a pixel to 1 if five or more pixels in its 3-by-3 neighborhood are 1s; otherwise, it sets the pixel to 0.
即在3*3领域内,如果白色的像素多一点,即当前像素修改为白色,如果黑色的多一点,则修改为黑色。
这个参数呢,循环迭代次数还有点作用了,下面是迭代一次和迭代十次后的效果比较:

迭代1次 迭代10次
可以看到,迭代十次后的结果图像的边缘更为光滑,毛刺比较少。
对于这个选项,我觉得有点可扩展的空间。因为其他像Fill等选项,是个固定的Mask,而这个是有一定的自由度的,我们不一定非要限制他在3*3领域啊,任何领域应该都是可以的,只要取领域内统计像素多一点的作为结果,就可以了啊。甚至作为扩展,我们还不一定就正好取多一点的,我们取某个百分比的也是可以的嘛,这样就可以有2个参数了,比如说取样半径和百分比。
不过,如果扩展到任意半径,那么算法的优化就很有必要了,不然原始的RAW实现,速度会慢的吓人的。
这个优化其实也不是没有弄过,但是二值图有其特殊性,其数据只有2个情况,0和1或者说0和255,我们要统计其领域的Majority元素,没有必要排序,也没有必要统计0和1的独立数据个数,想一想,我们是不是只要把领域的所有数据都加起来,然后也同样的可以知道谁更多呢。比如说,半径为5,那么领域一共有25个数据,如果加起来总和大于12,那不就意味着1多一些,如果小于等于12,那就意味着0多一些。
如何快速的实现领域的像素相加呢,这不就是Boxblur要干的事情吗,Boxblur如何优化:积分图、懒惰算法等等一大堆资料可以利用的。
参考 : SSE图像算法优化系列十三:超高速BoxBlur算法的实现和优化(Opencv的速度的五倍)
仔细想一想,这个和我们以前研究过的中值模糊不就是同一个算法吗,那里也有半径和百分比一说,但是因为其特殊性,这里的不用使用传统的中值模糊来实现算法,速度得到了极大的提升。
这个算法呢,我觉得一个比较有用的场合就是,对于一些初步处理后的二值图,一般都有一些边缘毛刺或者不平滑的位置,对于后续的识别可能有着较多的干扰,如果使用高斯模糊或者其他的抗锯齿算法呢,都会改变图像为二值的图的属性,就变为了灰度图,这是不可以的,但是使用这个算法呢,就完全不会改变二值图的本质,同时又能平滑边缘。
当然,有一点需要注意,当半径较大时,这个算法会改变原有二值图的一些面积属性,比如白色整体变少等等,这个呢,恰好我们有一个百分比参数,可同通过同时控制半径和百分比来协调结果这个问题,比如对于上面的原始图像,其相关统计信息如下:
总像素个数为:293828
白色的像素个数为:34191
连续块:60个
图像的欧拉数为:59
当我们取半径为4,百分比为50时,其效果如下所示:

半径4,百分比50 半径4,百分比45
相关统计信息如下:
总像素个数为:293828
白色的像素个数为:32671
找到符合条件的连续块:58个
图像的欧拉数为:58
可见白色像素的数量有所下降,如果把百分比修改为45,则统计信息如下:
总像素个数为:293828
白色的像素个数为:34653
找到符合条件的连续块:59个
图像的欧拉数为:59
和原始图像的信息基本差不多了,但是很明显结果比原始图像更有利于后续的分析。
本文Demo下载地址: https://files.cnblogs.com/files/Imageshop/SSE_Optimization_Demo.rar,位于Binary->Processing->Majority。里面的所有算法都是基于SSE实现的。
如果想时刻关注本人的最新文章,也可关注公众号:

从matlab的bwmorph函数的'majority'参数中扩展的一种二值图像边缘光滑的实时算法。的更多相关文章
- 痞子衡嵌入式:在IAR开发环境下将关键函数重定向到RAM中执行的三种方法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在IAR开发环境下将关键函数重定向到RAM中执行的三种方法. 嵌入式项目里应用程序代码正常是放在 Flash 中执行的,但有时候也需要将 ...
- 痞子衡嵌入式:MCUXpresso IDE下将关键函数重定向到RAM中执行的几种方法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是MCUXpresso IDE下将关键函数重定向到RAM中执行的几种方法. 前段时间痞子衡写了一篇 <在IAR开发环境下将关键函数重 ...
- 痞子衡嵌入式:在MDK开发环境下将关键函数重定向到RAM中执行的几种方法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在MDK开发环境下将关键函数重定向到RAM中执行的几种方法. 这个关键函数重定向到 RAM 中执行系列文章,痞子衡已经写过 <IA ...
- MATLAB filter2/conv2 函数在 Python 语言中的等价函数
MATLAB filter2 和 conv2 函数说明 在 MATLAB 中,filter2 函数实现二维数字滤波器.conv2 函数实现二维卷积. filter2(H, X, mode) 等价于 c ...
- 【原创】Matlab.NET混合编程技巧之直接调用Matlab内置函数
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 在我的上一篇文章[ ...
- Matlab.NET混合编程技巧之——直接调用Matlab内置函数(附源码)
原文:[原创]Matlab.NET混合编程技巧之--直接调用Matlab内置函数(附源码) 在我的上一篇文章[原创]Matlab.NET混编技巧之——找出Matlab内置函数中,已经大概的介绍了mat ...
- C#函数的默认参数——填坑记
昨天踩了一个坑.默认参数 + 增量发布的坑. 过程是这样的. 1. 有一个底层的方法,格式形如 void Test<T>(int p1, string p2, Func<T> ...
- 【matlab】设定函数默认参数
C++/java/python系列的语言,函数可以有默认值,通常类似如下的形式: funtion_name (param1, param2=default_value, ...) 到了matlab下发 ...
- 【原创】Matlab.NET混合编程技巧之找出Matlab内置函数
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 Matlab与.N ...
随机推荐
- Flask01 第一个flask项目
参考地址:https://github.com/miguelgrinberg/microblog/tree/v0.1 flask环境[苹果M1] 添加虚拟环境 python3 -m venv venv ...
- 3┃音视频直播系统之浏览器中通过 WebRTC 直播视频实时录制回放下载
一.录制分类 在音视频会议.在线教育等系统中,录制是一个特别重要的功能 录制一般分为服务端录制和客户端录制 服务端录制:优点是不用担心客户因自身电脑问题造成录制失败(如磁盘空间不足),也不会因录制时抢 ...
- TS 自学笔记(二)装饰器
TS 自学笔记(二)装饰器 本文写于 2020 年 9 月 15 日 上一篇 TS 文章已经是很久之前了.这次来讲一下 TS 的装饰器. 对于前端而言,装饰器是一个陌生的概念,但是对于 Java.C# ...
- Nvidia Triton使用教程:从青铜到王者
1 相关预备知识 模型:包含了大量参数的一个网络(参数+结构),体积10MB-10GB不等 模型格式:相同的模型可以有不同的存储格式(可类比音视频文件),目前主流有torch.tf.onnx和trt, ...
- awk应用场景之过滤举例
以/etc/passwd举例,passwd文本 [root@196 tmp]# cat /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bi ...
- 英语资源及其APP推荐
step1:记单词 a,说到背单词常规方法是拿着一本单词书一个一个往下背.该种方法不仅枯燥且效率极低. b,app辅助记忆.在此就我用过的两个app做简述.第一个是百词斩 百词斩:功能主打图片记忆,并 ...
- salesforce零基础学习(一百一十五)记一个有趣的bug
本篇参考:https://help.salesforce.com/s/articleView?language=en_US&type=1&id=000319486 page layou ...
- Java_选择结构
if单选择结构 if(布拉尔表达式){ //如果布拉尔表达式为true将执行的语句 } if双选择结构 if(布拉尔表达式){ //如果布拉尔表达式的值为true }else{ //如果布拉尔表达式的 ...
- Java添加条形码到PDF表格
条码的应用已深入生活和工作的方方面面.在处理条码时,常需要和各种文档格式相结合.当需要在文档中插入.编辑或者删除条码时,可借助于一些专业的类库工具来实现.本文,以操作PDF文件为例,介绍如何在编辑表格 ...
- 树莓派开发笔记(十七):树莓派4B+上Qt多用户连接操作Mysql数据库同步(单条数据悲观锁)
前言 安装了mysq数据库,最终时为了实现在一个树莓派上实现多用户多进程操作的同步问题,避免数据并发出现一些错误,本篇安装了远程服务并且讲述了使用Qt进行悲观锁for update操作,命令行进行 ...