在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. vagrant,VirtualBox -- 安装使用

    1.安装Oracle VM VirtualBox下载 http://download.virtualbox.org/virtualbox/5.2.44/ 2.安装vagrant https://www ...

  2. Ubuntu的一些软件源

    参考别人的,自己记录一下,怕丢失 修改方法:vim /etc/apt/sources.list,然后添加下面对应的代码区 台湾的官方源 deb http://tw.archive.ubuntu.com ...

  3. 场景实践:使用RDS和ECS搭建个人博客

    体验简介 本教程将使用一台基础环境为CentOS7.7的云服务器ECS实例, 搭配您已有的云数据库RDS实例,帮助您快速搭建属于自己的云上博客. 背景知识 本场景主要涉及以下云产品和服务: 阿里云关系 ...

  4. mongoDB 命令大全

    每日一句 There should be a better way to start a day than waking up every morning. 应该有更好的方式开始新一天, 而不是千篇一 ...

  5. 论文解读(AGE)《Adaptive Graph Encoder for Attributed Graph Embedding》

    论文信息 论文标题:Adaptive Graph Encoder for Attributed Graph Embedding论文作者:Gayan K. Kulatilleke, Marius Por ...

  6. 「ARC138E」Decreasing Subsequence(n logn 做法)

    考虑一张 \(n\) 个点的图(\(V=\{0,1,\cdots,n\}\)):点 \(i\) 连向 \(a_i-1\),即 \(\text{index}\) 连向 \(\text{value}\). ...

  7. 关于『HTML』:第三弹

    关于『HTML』:第三弹 建议缩放90%食用 盼望着, 盼望着, 第三弹来了, HTML基础系列完结了!! 一切都像刚睡醒的样子(包括我), 欣欣然张开了眼(我没有) 敬请期待Markdown语法系列 ...

  8. Spring AOP快速使用教程

    ​ Spring是方法级别的AOP框架,我们主要也是以某个类的某个方法作为连接点,用动态代理的理论来说,就是要拦截哪个方法织入对应的AOP通知.为了更方便的测试我们首先创建一个接口 public in ...

  9. Redis - 为什么 Redis 是单线程的?

    Redis中work线程是单线程的.也就是对于业务数据的操作是单线程的. Redis中存在多线程操作 异步关闭文件 异步将缓冲区冲洗到磁盘文件中 异步删除键值对 Redis是基于内存的,所以cpu不是 ...

  10. ngx_http_fastcgi_module 的那些事

    是什么? 顾名思义,是Nginx用来处理FastCGI的模块.FastCGI是什么?这个以后再讲,可以说的是现在LNMP架构里面,PHP一般是以PHP-CGI的形式在运行,它就是一种FastCGI,我 ...