在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的速度的五倍)

13行代码实现最快速最高效的积分图像算法。

  仔细想一想,这个和我们以前研究过的中值模糊不就是同一个算法吗,那里也有半径和百分比一说,但是因为其特殊性,这里的不用使用传统的中值模糊来实现算法,速度得到了极大的提升。

  这个算法呢,我觉得一个比较有用的场合就是,对于一些初步处理后的二值图,一般都有一些边缘毛刺或者不平滑的位置,对于后续的识别可能有着较多的干扰,如果使用高斯模糊或者其他的抗锯齿算法呢,都会改变图像为二值的图的属性,就变为了灰度图,这是不可以的,但是使用这个算法呢,就完全不会改变二值图的本质,同时又能平滑边缘。

当然,有一点需要注意,当半径较大时,这个算法会改变原有二值图的一些面积属性,比如白色整体变少等等,这个呢,恰好我们有一个百分比参数,可同通过同时控制半径和百分比来协调结果这个问题,比如对于上面的原始图像,其相关统计信息如下:

      总像素个数为: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'参数中扩展的一种二值图像边缘光滑的实时算法。的更多相关文章

  1. 痞子衡嵌入式:在IAR开发环境下将关键函数重定向到RAM中执行的三种方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在IAR开发环境下将关键函数重定向到RAM中执行的三种方法. 嵌入式项目里应用程序代码正常是放在 Flash 中执行的,但有时候也需要将 ...

  2. 痞子衡嵌入式:MCUXpresso IDE下将关键函数重定向到RAM中执行的几种方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是MCUXpresso IDE下将关键函数重定向到RAM中执行的几种方法. 前段时间痞子衡写了一篇 <在IAR开发环境下将关键函数重 ...

  3. 痞子衡嵌入式:在MDK开发环境下将关键函数重定向到RAM中执行的几种方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在MDK开发环境下将关键函数重定向到RAM中执行的几种方法. 这个关键函数重定向到 RAM 中执行系列文章,痞子衡已经写过 <IA ...

  4. MATLAB filter2/conv2 函数在 Python 语言中的等价函数

    MATLAB filter2 和 conv2 函数说明 在 MATLAB 中,filter2 函数实现二维数字滤波器.conv2 函数实现二维卷积. filter2(H, X, mode) 等价于 c ...

  5. 【原创】Matlab.NET混合编程技巧之直接调用Matlab内置函数

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 在我的上一篇文章[ ...

  6. Matlab.NET混合编程技巧之——直接调用Matlab内置函数(附源码)

    原文:[原创]Matlab.NET混合编程技巧之--直接调用Matlab内置函数(附源码) 在我的上一篇文章[原创]Matlab.NET混编技巧之——找出Matlab内置函数中,已经大概的介绍了mat ...

  7. C#函数的默认参数——填坑记

    昨天踩了一个坑.默认参数 + 增量发布的坑. 过程是这样的. 1. 有一个底层的方法,格式形如 void Test<T>(int p1, string p2, Func<T> ...

  8. 【matlab】设定函数默认参数

    C++/java/python系列的语言,函数可以有默认值,通常类似如下的形式: funtion_name (param1, param2=default_value, ...) 到了matlab下发 ...

  9. 【原创】Matlab.NET混合编程技巧之找出Matlab内置函数

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 Matlab与.N ...

随机推荐

  1. 软件开发架构,网络编程简介,OSI七层协议,TCP和UDP协议

    软件开发架构 什么是软件开发架构 1.软件架构是一个系统的草图. 2.软件架构描述的对象是直接构成系统的抽象组件. 3.各个组件之间的连接则明确和相对细致地描述组件之间的通讯. 4.在实现阶段,这些抽 ...

  2. netty系列之:netty中常用的xml编码解码器

    目录 简介 XmlFrameDecoder XmlDecoder 总结 简介 在json之前,xml是最常用的数据传输格式,虽然xml的冗余数据有点多,但是xml的结构简单清晰,至今仍然运用在程序中的 ...

  3. MySQL(8) - MySQL的事务机制

    MySQL数据库的事务机制 1.1.事务的概念和特性 1.2.事务的隔离级别 repeatable read是mysql默认的事务隔离级别 #事务A #事务A,临时修改工资,未commit, STAR ...

  4. 关于我开发tinymce的自由表单、病历插件这件事

    项目地址:https://gitee.com/zhao-xuhang/tinymce 1.前期准备 这是个vue2项目所以要使用vue-cli (虽然开发tinymce插件和这个没关系) 1. 使用n ...

  5. 文件操作(Java)

    学习内容:文件操作        1.输入流:InputStream类是字节输入流的抽象类,常用的一些方法有: raed()方法:从输入流中读取数据的下一个字节 reset()方法:将输入指针返回到当 ...

  6. [C++STL] vector 容器的入门

    vector容器的入门 #include<vector> 创建vector容器的几种方式 数据类型可以是结构体,也能是另外一个容器 vector 的初始化: (1) 创建并声明大小 vec ...

  7. mac安装java环境

    1.java安装包获取: 链接:https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html 2.验证安装是否成 ...

  8. jQuery基础入门+购物车案例详解

    jQuery是一个快速.简洁的JavaScript代码库(或JavaScript框架).jQuery设计的宗旨是"write Less,Do More",即倡导写更少的代码,做更多 ...

  9. mybatis-plus分页插件

    package com.tanhua.server.config; import com.baomidou.mybatisplus.extension.plugins.PaginationInterc ...

  10. E104-BT01超低功耗蓝牙模块BLE4.0协议的片载系统解决方案

    1.E104-BT01简介 E104-BT01 是亿佰特设计生产的一款小体积的蓝牙模块,贴片型(引脚间距 1.27mm),自带高性能 PCB 板载天线.支持 BluetoothV4.0 标准,简单配置 ...