2019-06-19 22:14:02 qq_15029743 阅读数 6142
  • OpenCV3.2 Java图像处理视频学习教程

    OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java OpenCV图像处理部分内容,包括Mat对象使用、图像读写、 基于常用核心API讲述基本原理、使用方法、参数、代码演示、图像处理思路与流程讲授。主要内容包括opencv像素操作、滤波、边缘提取、直线与圆检测、形态学操作与分水岭、图像金子塔融合重建、多尺度模板匹配、opencv人脸检测、OpenCV跟Tomcat使用实现服务器端图像处理服务。

    4123 人正在学习 去看看 贾志刚

       伴随着图像处理技术的发展,我们每天无时无刻都在接触着图像处理的一切,打开相机,设置美颜程度,伴随着快门键的按下,一张瘦脸磨皮的人像处理完成了。按下手机的解锁键,前置摄像头已经获取了你的人脸图像,并在你的脸上打上了若干个点,与数据库的信息进行比对,一次人像比对完成了。车辆行驶到单位校园门口,你的车牌已经被切割成一个个字母、数字与汉字,随着栏杆的抬起,又一次图像处理完成了。伴随着图像处理的广泛应用以及目前人工智能在图像领域的应用,更多的图像处理技术爆发式的增长,也更多的人投入到了这个领域的研究。作为一名行业从业者,如何学好图像处理就显得甚为棘手。博主作为一名“半路出家”的图像处理入门者,在这里也给各位读者分享一下一直以来的一些思考,因为本人水平有限,不妥之处还望见谅。

1、高山平顶上,尽是采樵翁。人人各怀刀斧意,未见山花映水红。        ——何权峰《眼界,决定你的世界》

        其实很多时候,我们都局限在自己的小平台里,沾沾自喜,而忽略了你身边技术的飞速发展,也许这种沉浸对于一些传统行业来说,淘汰一个人的速度是十几年甚至几十年,但是对于计算机领域来说,这一淘汰也许就是一瞬间,这也是为什么企业在招聘应届生事,一方面关注你的技能,但也非常关注你的学习能力(简单说就是你可以什么都不会,但你学的快不?但你愿意学不?),而这种学习能力往往是需要长时间培养锻炼的,举个例子:清华北大的学生永远不愁找不到工作,而去清华北大招聘的企业也往往最不看重你的专业,因为他们知道,这里有着国内学习能力最强的人。说的有点远了,回到刚刚的话题,其实给博主触动最深的还是看到了CSDN某大神的一篇博客《阿里巴巴(菜鸟) - 算法工程师(机器学习)提前批笔试面试总结》中面试环节面试官问的一个问题:介绍CVPR2018你最感兴趣一篇论文的工作?看到这里博主犹如当头一棒。自己也只是听说过CVPR,当然也会留意一些媒体的报道或者是推送,但是从来都没有认真的甚至说大致的浏览过每一年会议的文章内容甚至是会议目录。而自己也“井底之蛙”般的只能感叹自己也许将是接下来就被淘汰的那个。其实广一点说,我们的本科生或者研究生期间,可能你的实验室做的东西很low,亦或是你是一个“半路出家者”,或者我们的“出身”不是很好,这些都或多或少的会限制我们的眼界。但是我们自己不应该允许自己做那只“井底之蛙”,我们更应该关注或者说拥抱我们所处这个行业最新、最前沿的技术(比如2018CVPR的最佳论文《Taskonomy: Disentangling Task Transfer Learning》);关注我们这个领域的大牛(比如做计算机视觉我们一定绕不开李飞飞教授、做相机标定一定离不开张正友教授)。眼界决定我们的视野,这也是为什么很多顶尖的公司在招聘的时候一定会加上如下两条:1、所在实验室为国家重点实验室或者在国内顶尖的科研机构有过实习经历  2、在顶级会议发表过相关文章。会当凌绝顶,方能一览众山小!

这里,博主附上计算机视觉领域的CCF推荐会议:计算机视觉及图像处理领域会议,CCF推荐(A类,B类,C类),感兴趣的读者可以选取和你研究课题相关的较高水平的会议关注查看。

2、知其然与知其所以然。 ——《朱子语类》卷九《论知行》

        这里我们要说,很多人在从事图像处理工作的时候更多的是被动的被推着走,只知其然而不知其所以然,还是举个例子,我们都知道,图像处理的前期操作就是获取图像,而获取图像的一个重要途径就是通过相机获取图片,相机获取到的图片更多程度需要去标定矫正。好了,问题来了,很多人知道,我获取图像了,按照“前人所述”我需要进行相机标定,设置标定板、计算内外参数...一些列工作完成了,我们也得到了“前人所述”的内外参数,那接下来呢?我们怎么矫正呢?为什么要做矫正呢?不矫正对我的图像处理过程有什么影响呢?想必这个问题是很多读者没有考虑过的,博主也看了很多的博客,相机标定写内外参矩阵的大有人在,图像生动、推导详尽。但说获取这些参数只会该干什么的博客却是凤毛麟角。反观之,我们其实很多时候也都停留在这样的阶段,就是只知道,这个事情该这样,但是为什么要这样却知之甚少。

3、一门科学,只有当它成功地运用数学时,才能达到真正完善的地步。  ——马克思

        其实博主本人也是一个讨厌数学且数学不好的人,但是越是从事图像处理工作越深,越发觉得数学的重要性。数学也许就像是你的导师,你很多时候很讨厌,但是却绕不开。图像处理时我们会发现,图像在计算机内其实就是一个个矩阵,图像的处理很多时候就是数学变换,比如去噪(数学上的均值或者中值处理),比如放大缩小图像(数学上的插值和采样)等等,这里我们还是举一个例子:从事图像处理的人应该大部分都知道(最起码听说过)SIFT特征点检测算法,这里不展开论述,我们只拿其中的一个关键部分来说,SIFT算法中有两种方法,分别是:

a、使用LOG图像(高斯拉普拉斯变换图像):其步骤是:先将照片降采样,得到了不同分辨率下的图像金字塔。再对每层图像进行高斯卷积。这样一来,原本的图像金字塔每层只有一张图像,而卷积后,每层又增加了多张不同模糊程度下的照片。大概就是下图这样:

b、使用(DOG图像):DOG即高斯差分。构造高斯差分图像的步骤是:在获得LOG图像后,用其相邻的图像进行相减,得到所有图像重新构造的金字塔就是DOG金字塔。大概就是下图这样子:

        好了,问题来了,这一数学上的改进,能有多大的差距呢?我们可以看到,就是这样一个“看似简单”的改进可以使我们的运算量小一个数量级!数学有多重要!

        也许上面的过程有一些读者没看明白,什么又是高斯卷积又是图像相减的,太麻烦,那我们再介绍一种非常“简单”的特征点检测算法(FAST) ,有多“简单”呢?这里先放一张图:

        为了让大家简单易懂,这里我们简单的说原理,可能与实际不相符,简单说,就是你要找特征点P,那我在p周边画个圈,设置一个阈值,如果有若干个点大于这一阈值,我们就理解为p是特征点(阈值为9就是FAST9,阈值为11就是FAST11)。惊不惊喜,意不意外,就是这么好理解,而且这一算法的速度快,效果也不差。其实这种方法博主更多的理解为是一种数学上的改进。而我们纵观众多划时代的文章、方法、算法,其实其本质大多为数学方法在各个领域上应用的改进。学好数理化,走遍天下都不怕,数学,可怕却重要! 

4、如果我能看得更远一点的话,是因为我站在巨人的肩膀上。  ——牛顿

        伴随着计算机网络的发展,开源的趋势化(强调专利的微软收购了Github并主动开源了众多代码),我们可以找到更多的资源与资料(BaiDu,Google一键直达),一个个的开放图形库和开放图形软件(最常见的OpenGL、OpenCV),我们有着比以往任何时候更多的资源,也有着比以往人更多的机会接触到科技的最前沿(顶级会议大部分都是开源的,我们可以随意下载),这里博主特别强调,大胆的去使用这些工具,抱着书本往死里啃,问周边同学或老师有效,但这样的时代终将过去,信息交互的年代,每一个人都是一个信息源(有点像众包的概念),站在巨人肩膀上引领科技进步的人也许不是你我,但是你我可以更容易找到这个世界上的巨人在哪里了,我们的获取信息的渠道更多了,我们身边的信息源更多了(比如MOOC,我们可以倾听最好的老师讲课),这里说点题外话,推荐一部纪录片《互联网时代》,当时博主看的热血沸腾!回到主题,不主动拥抱这个时代的人一定会被时代所抛弃。能活到最后的人一定不是闭门造车的,一定是那个敢于攀登,寻找巨人的人。

5、工欲善其事,必先利其器。  ——《论语·卫灵公》

这里其实博主还是老生常谈的强调你的编程能力,我们都知道,一切的图像处理的最终实现都是程序,更是算法(硬件处理也有硬件程序、算法),而编程能力就好比士兵的枪、老师的粉笔。再好的想法如果不能付诸于一行行“冰冷”的算法最后都只能是镜中花、水中月。而选择哪门语言作为你的“枪”这里博主就不再赘述,直接放上之前写的一篇博客的内容:

Python?JAVA?C/C++?
      其实实验室也会有一些师弟师妹问我这个问题,我该选一门什么语言呢?当然,我在这里不去评论哪门语言的优劣好坏,仅仅针对每一门语言在找工作时选择的机会跟大家做一些分享,首先,如果你需要找工作时自己能多一些机会和选择,那么仅仅会MATLAB或者Python可能还是远远不够的,毕竟找工作时需求量最大的依旧是JAVA\C\C++相关的工程师,如果你仅仅会MATLAB或者Pyrthon,那么你找工作时可能只能选择算法相关类的工作,而这类工作,我们都知道,和你竞争的往往都是一些大佬,算法岗也因为其相对的高工资和低劳动强度而成为近两年来淘汰人数最多的岗位之一。

      所以,这里强烈建议如果有可能,请抽出时间选择JAVA\C\C++其中一门语言进行系统化的学习(这里我们只谈最常见的,PHP,GO等语言博主没有学过,也没有具体了解,就不在这里献丑了),当然选择JAVA你还可以转向安卓开发,C\C++则更加偏底层一些。这一切的选择基础需要你综合衡量,博主特别讨厌一些鼓吹某某语言万能无敌之类的话,举个例子C++的确可以坐界面,但显然,做界面C++不是最好的选择,合适的才是最好的,不是么?

6、你看江面平如镜,要看水底万丈深。  ——谚语

        我们很多人,其实也包括博主本人都有这个问题,就是用一个东西的时候想的不够深入,直至其表,不知其里,还是举个例子,我们每个人都应该知道的边缘检测算法,博主相信,用起来不难,网上搜一下代码,一搜一大片,有一定程序基础的人都可以轻松实现,但是深入思考,我们知道他的原理么?这里,博主将所有人分为几个等级,大家可以以边缘检测算法作为作为自己的对照,看看自己停留在哪个级别:

a、还没入门的“行外汉”:什么是边缘检测算法?不会怎么办?问周边人吧!

b、已经入门的“小菜鸟”:emm,好像有印象,去网上搜一下现成的程序,改一下图片输入就行了!

c、有思考的“程序猿”:算法每一个参数什么意思啊?我改一下会怎样?

d、负责任的“熟练工”:这个算法的原理究竟是什么样的?怎么就找到边缘了?找个博客看看!

e、企业抢着要的“大牛”:算法原理我看懂了,自己手撕代码试一下!

f、“大佬、科研工作者”:数学公式可能需要自己推一下,看能不能改进!

看看,一个简单的边缘检测算法我们就可以看到不同人的不同水平,你的思维深度更多时候可以决定你的高度!

7、思考可以构成一座桥,让我们通向新知识。 ——普朗克

      小时候爸爸妈妈就教会我们多问一问为什么,那时候最喜欢看的书也是《十万个为什么》,但是越长大越发现自己丧失了这种质疑和思考能力,我们更多时候的想法是“哪有那么多为什么!”。做项目,搞科研其实更多时候需要我们这种问问题的能力,就好比之前的例子:相机标定,为什么要标定?其实道理大家都懂,做到的却太少了,包括博主本人,这里写出这条大家共勉!

8、亡羊补牢,犹未迟也。  ——《战国策·楚策四》

        可能很多人看到博主写了这么多会觉得可能自己再某个或者某些领域的欠缺有点大,有些失落甚至灰心丧气。其实博主需要在文章的最后和大家打打气,我们发现了问题和漏洞只要积极去改变,就会发现事情就会朝着好的方向发展。谁能想到《三体》作者刘慈欣若干年前还在水电站工作?又有谁能想到阿里云的头头是一个哲学博士呢?最后一句话赠与自己也赠与能看到这篇文章的读者们共勉:改变,从当下开始!

2016-11-21 01:17:25 cai13160674275 阅读数 406
  • OpenCV3.2 Java图像处理视频学习教程

    OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java OpenCV图像处理部分内容,包括Mat对象使用、图像读写、 基于常用核心API讲述基本原理、使用方法、参数、代码演示、图像处理思路与流程讲授。主要内容包括opencv像素操作、滤波、边缘提取、直线与圆检测、形态学操作与分水岭、图像金子塔融合重建、多尺度模板匹配、opencv人脸检测、OpenCV跟Tomcat使用实现服务器端图像处理服务。

    4123 人正在学习 去看看 贾志刚

a very good article for higher picture Handle

http://blog.csdn.net/huangli19870217/article/details/50754743

上面这个链接讲了很多高级的形态学算法,开操作,闭操作,顶帽,梯度,作用都很详细,下面只展示简单的腐蚀和膨胀



形态学处理:图像的膨胀和腐蚀
膨胀算法使图像扩大一圈。
腐蚀算法使二值图像减小一圈。
腐蚀:删除对象边界的某些像素
膨胀:给图像中的对象边界添加像素


#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;

int main(int argc, char** argv)
{
	Mat image;
	Mat image2;
	Mat image3;
	image=imread("/home/tgd/Videos/lane_pic/TSD-Lane-00000/TSD-Lane-00000-00000.png",3);
	Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
	dilate(image, image2, element);
	erode(image,image3,element);
	imshow("image",image);
	imshow("image2",image2);
	imshow("image3",image3);
	waitKey(0);
}




2018-09-18 15:36:10 yangsong95 阅读数 288
  • OpenCV3.2 Java图像处理视频学习教程

    OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java OpenCV图像处理部分内容,包括Mat对象使用、图像读写、 基于常用核心API讲述基本原理、使用方法、参数、代码演示、图像处理思路与流程讲授。主要内容包括opencv像素操作、滤波、边缘提取、直线与圆检测、形态学操作与分水岭、图像金子塔融合重建、多尺度模板匹配、opencv人脸检测、OpenCV跟Tomcat使用实现服务器端图像处理服务。

    4123 人正在学习 去看看 贾志刚

形态学图像处理的基本理论是数学形态学(Mathematical morphology)。数学形态学的语言是集合论,集合表示图像中的对象。

在形态学中,集合的反射和平移广泛用来表达基于 结构元(SE) 的操作:研究一幅图像中感兴趣特性所用的小集合或子图像。

特别注意结构元的原点。

  • 腐蚀

    腐蚀缩小或细化了二值图像中的物体。可以将腐蚀看成是形态学滤波操作,这种操作将小于结构元的图像细节从图像中滤除了。
    结构元B对A的腐蚀是一个用z平移的 令B包含在A中的 所有的点z的集合。

    具体操作为:让B在A上运行,以便B的原点访问A的每一个元素,来创建一个新集合。在B的每个原点位置,如果B完全被A包含,则将该位置标记为新集合的一个成员;否则,将该位置标记为非新集合的成员。

  • 膨胀

    z对结构元B关于原点的映像进行平移,B的映像和A至少有一个元素是重叠的,则B对A的膨胀是所有位移z的集合。

  • 开操作

    先腐蚀后膨胀。
    开操作一般会平滑物体的轮廓、断开较窄的狭颈并消除细的突出物。开操作一般会平滑物体的轮廓、断开较窄的狭颈并消除细的突出物。

  • 闭操作

    先膨胀后腐蚀。
    闭操作也会平滑轮廓的一部分,但与开操作相反,通常会弥合较窄的间断和细长的沟壑,消除小的孔洞,填补轮廓线中的断裂。

——Rafael C. Gonzalez等《数字图像处理》

2016-04-11 12:28:58 qq_20823641 阅读数 7936
  • OpenCV3.2 Java图像处理视频学习教程

    OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java OpenCV图像处理部分内容,包括Mat对象使用、图像读写、 基于常用核心API讲述基本原理、使用方法、参数、代码演示、图像处理思路与流程讲授。主要内容包括opencv像素操作、滤波、边缘提取、直线与圆检测、形态学操作与分水岭、图像金子塔融合重建、多尺度模板匹配、opencv人脸检测、OpenCV跟Tomcat使用实现服务器端图像处理服务。

    4123 人正在学习 去看看 贾志刚

         经过上一篇文章的《matlab GUI图像图像基础》,我们可以知道说是入门了GUI,对于GUI图像图形还可以调用函数形成,但是对于学习图像处理来说,感觉没有那个必要去学,会了基础,就可以自己GUI图像处理功能了,主要还是算法和功能,所以我就没有写函数调用创建GUI,然后直接写了一篇关于GUI图像处理(根据matlab GUI编写),里面包括打开文件、保存文件灰度转换 、傅立叶变换 、颗粒面积的分布、 二维三维化、 图像融合几个功能,相信他们看就会明白怎么创建自己的功能,让界面更加好看,功能更加的多。完全可以自己DIY一个。

        因为回调函数的代码比较长,所以上传到资源,可以下载下来,对比添加,下载地址http://download.csdn.net/user/qq_20823641

        还是想给一张总图,一个是界面图,一个是菜单,对于控件回调函数不再这里多说了,主要的功能添加基本都在菜单和子菜单上面。

                                    

现在说一下过程

1.     看图上的坐标轴和按钮,添加三个坐标轴,2个按钮,2个可编辑文本

2.     菜单编辑上增加,如图


3.     添加各自的回调函数,会的可以参考下载的代码添加,不会的可以看上一篇学习。



2019-05-11 08:31:12 Dujing2019 阅读数 1180
  • OpenCV3.2 Java图像处理视频学习教程

    OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java OpenCV图像处理部分内容,包括Mat对象使用、图像读写、 基于常用核心API讲述基本原理、使用方法、参数、代码演示、图像处理思路与流程讲授。主要内容包括opencv像素操作、滤波、边缘提取、直线与圆检测、形态学操作与分水岭、图像金子塔融合重建、多尺度模板匹配、opencv人脸检测、OpenCV跟Tomcat使用实现服务器端图像处理服务。

    4123 人正在学习 去看看 贾志刚

数字图像处理—形态学图像处理

同样的,暂时对书上已经写得很清楚的知识点不再重复赘述,主要做一些总结,思考以及知识点的梳理和扩展。

(一)预备知识

介绍一下形态学中的一些基本概念。

  1. 用数学形态学(也称图像代数)表示以形态为基础对图像进行分析的数学工具
  2. 基本思想是用具有一定形态的结构元素去度量和提取图像中的对应形状以达到对图像分析识别的目的
  3. 形态学图像处理的数学基础和所用语言是集合论
  4. 形态学图像处理的应用可以简化图像数据, 保持它们基本的形状特性,并除去不相干的结 构
  5. 形态学图像处理的基本运算有4个:膨胀、 腐蚀、开操作和闭操作

1.1 集合理论中的基本概念

介绍一下比较陌生的几个概念,其他的看书就好:

  1. 所有像素坐标的集合均不属于集合A,记为AcA^c,由下式给出:
    在这里插入图片描述
    这个集合称为集合A的补集

  2. 集合B的反射,定义为:

    即关于原集合原点对称 .

  3. 集合A平移到点z=(z1,z2),表示为(A)z,定义为:

1.2 二值图像、集合及逻辑算子

二值图像

二值图像(Binary Image),按名字来理解只有两个值,0和1,0代表黑,1代表白,或者说0表示背景,而1表示前景。其保存也相对简单,每个像素只需要1Bit就可以完整存储信息。如果把每个像素看成随机变量,一共有N个像素,那么二值图有2的N次方种变化,而8位灰度图有255的N次方种变化,8为三通道RGB图像有255255255的N次方种变化。也就是说同样尺寸的图像,二值图像保存的信息更少。二值图像(binary image),即图像上的每一个像素只有两种可能的取值或灰度等级状态,人们经常用黑白、B&W、单色图像表示二值图像。

二值图像集合

如果A和B是二值图像,那么C=A∪B仍是二值图像。这里,如 果 A 和B中相应的像素不是前景像素就是背景像素,那么 C中的这个像素就是前景像素。以第一种观点,函数 C由下式给出:
在这里插入图片描述
另一方面,运用集合的观点,C由下式给出:
在这里插入图片描述
集合运算

  1. A为图像集合,B为结构元素(集合)。
  2. 数学形态学运算时B对A进行操作。
  3. 结构元素要有1个原点(即结构元素参与形态学运算的参考点),可以是中心像素,原则上可选任何像素。
    注意:原点可以包含在结构元素中,也可以不包含在结构元素中,但运算的结果常不相同。

编码

f = imread('D:\数字图像处理\第九章学习\Fig0903(a).tif');
g = imread('D:\数字图像处理\第九章学习\Fig0903(b).tif');
subplot(2,3,1), imshow(f);title('(a)二值图像 A:');
subplot(2,3,2), imshow(g);title('(b)二值图像 B:');
subplot(2,3,3), imshow(~f);title('(c)A的补集~A:');
subplot(2,3,4), imshow(f|g);title('(d) A和B的并集 A|B:');
subplot(2,3,5), imshow(f&g);title('(e)A和B的交集 A & B:');
subplot(2,3,6), imshow(f&~g);title('(f)A和B的差集 A&~B');

代码运行效果如下
在这里插入图片描述
分析

图像(d)是 “ UTK”和 “ GT” 图像的并集,包括来自两幅图像的所有前景像素。相反,两幅图像的交集(图(e))显示了字母 “ UTK”和 “ GT”中重叠的像素。最后,集合的差集图像(图(f))显示了 “ UTK”中除去 “ GT” 像素后的字母。

(二)膨胀和腐蚀

2.1 膨胀

膨胀:膨胀是在二值图像中“加长”或“变粗”的操作。这种特殊的方式和变粗的程度由一个称为结构元素的集合控制。(实际就是将结构元素的原点与二值图像中的1重叠,将二值图像中重叠部分不是1的值变为1,完成膨胀)。

公式

A和B是两个集合,A被B膨胀定义为:

公式解释:

  1. B的反射进行平移与A的交集不为空。
  2. B的反射:相对于自身原点的映象。
  3. B的平移:对B的反射进行位移

图解

      

(a)集合A    (b)结构元素B (黑色为原点所在)

      

(c)结构元素B的映像    (d)图中两种阴影部分(深色为扩大的部分)合起来为A+B

注意

  1. 膨胀运算只要求结构元素的原点在目标图像的内部平移,换句话说,当结构元素在目标图像上平移时,允许结构元素中的非原点像素超出目标图像的范围
  2. 膨胀运算具有扩大图像和填充图像中比结果元素小的成分的作用,因此在实际应用中可以利用膨胀运算连接相邻物体和填充图像中的小孔和狭窄的缝隙

膨胀举例

膨胀函数

D = imdilate(A,B)

图像膨胀的应用:桥接文字裂缝

编码:

A = imread('D:\数字图像处理\第九章学习\Fig0906(a).tif');
B = [0 1 0; 1 1 1; 0 1 0];   %指定结构元素由0和1组成的矩阵
A2 = imdilate(A, B);    %二值图像
subplot(1,2,1), imshow(A);title('(a)包括断开文本的输入图像:');
subplot(1,2,2), imshow(A2);title('(b)膨胀后图像:');

在这里插入图片描述
图片中字体的加粗,且填充了字母中的小孔和狭窄的缝隙。

2.2 结构元的分解

公式
在这里插入图片描述
公式理解

B膨胀A等同于B1先膨胀A,再用B2膨胀之前的结果。

举例

下面是由1组成的5x5数组的膨胀:
在这里插入图片描述
这个结构元能够分解为值为 1 的 5 元素行矩阵和值为 1 的 5 元素列矩阵:

在这里插入图片描述
分析

在原结构元中,元素个数为 25; 但在行列分解后,总元素数目仅为 10。这意味着首先用 行结构元膨胀,再用列结构元膨胀,能够比 5x5 的数组膨胀快 2.5 倍。在实践中,速度的增长稍微慢一些,因为在每个膨胀运算中总有些其他开销。然而,由分解执行获得的速度方面的增 长仍然有很大意义。

2.3 strel函数

工具箱函数 strel 用于构造各种形状和大小的结构元。

基本语法

se = strel(shape, parameters)

shape用于指定希望形状的字符串,parameters是描述形状信息的参数列表。

具体例子参考课本,是基础语法。

2.4 腐蚀

腐蚀:与膨胀相反,对二值图像中的对象进行“收缩”或“细化”。(实际上将结构元素的原点覆盖在每一个二值图像的1上,只要二值图像上有0和结构元素的1重叠,那么与原点重叠的值为0)同样由集合与结构元素完成。

公式

A和B是两个集合,A被B腐蚀定义为:

公式解释:

  1. A被 B 腐蚀是包含在A中的B由z平移的所有点z的集合。
  2. B包含在A中的声明相当于B不共享A背景的任何元素。

图解
     

(a)集合A(阴影部分)   (b)结构元素B(阴影部分,深色部分为原点)(c)阴影部分合起来为A-B

注意

  1. 当结构元素中原点位置不为1(也即原点不属于结构元素时),也要把它看作是1,也就是说,当在目标图像中找与结构元素B相同的子图像时,也要求子图像中与结构元素B的原点对应的那个位置的像素的值是1。
  2. 腐蚀运算要求结构元素必须完全包括在被腐蚀图像内部:换句话说,当结构元素在目标图像上平移时,结构元素中的任何元素不能超过目标图像范围。
  3. 腐蚀运算的结果不仅与结构元素的形状选取有关,而且还与原点位置的选取有关
  4. 腐蚀运算具有缩小图像和消除图像中比结构元素小的成分的作用,因此在实际应用中,可以利用腐蚀运算去除物体之间的粘连,消除图像中的小颗粒噪声

腐蚀举例

腐蚀函数

A2 = imerode(A, se)

图像腐蚀应用:消除图像细节部分

编码:

f = imread('D:\数字图像处理\第九章学习\Fig0908(a).tif');
se = strel('disk', 10);
g = imerode(f, se);
se = strel('disk', 5);
g1 = imerode(f, se);
g2 = imerode(f, strel('disk', 20));
subplot(2,2,1), imshow(f);title('(a)原始图像的尺寸为480x480像素:');
subplot(2,2,2), imshow(g);title('(b)用半径为10的圆形腐蚀:');
subplot(2,2,3), imshow(g1);title('(c)用半径为5的圆形腐蚀:');
subplot(2,2,4), imshow(g2);title('(d)用半径为20的圆形腐蚀');

分析

假设要除去图a中的细线,但想保留其他结构,可以选取足够小的结构元来匹配中心方块,但较粗的边缘线因太大而无法匹配全部线。图b几乎成功去掉了模板中的细线,图c中一些引线还没有去掉,图d中引线都被去掉了,但是边缘引线也丢失了,所以选取合适的结构元很重要。

(三) 膨胀与腐蚀的结合

3.1 开操作和闭操作

开操作

  1. 使图像的轮廓变得光滑,断开狭窄的间断和消除细的突出物。
  2. 使用结构元素B对集合A进行开操作,定义为:

    先用B对A腐蚀,然后用B对结果膨胀。
  3. 与开操作等价的数学表达式为:
  4. A o B 的边界通过B中的点完成。
  5. B在A的边界内转动时,B中的点所能到达的A的边界的最远点。
  6. A o B 是 A的子集合。
  7. 如果C是D的子集,则 C o B是 D o B的子集。
  8. (A o B) o B = A o B

闭操作

  1. 同样使图像的轮廓变得光滑,但与开操作相反,它能消除狭窄的间断和长细的鸿沟,消除小的孔洞,并填补轮廓线中的裂痕。
  2. 使用结构元素B对集合A进行闭操作,定 义为:

    先用B对A膨胀,然后用B对结果腐蚀。
  3. A . B的边界通过B中的点完成 。
  4. B在A的边界外部转动 :
  5. A 是 A . B的子集合。
  6. 如果C 是 D 的子集 , 则C . B 是 D . B的子集。
  7. (A . B) . B = A . B

工具箱函数

开操作:

C = imopen(A, B)

闭操作:

C = imclose(A, B)

A为二值图像,B为0,1矩阵组成,并且是指定结构元素。

函数imopen 和 imclose 的应用

编码:

f = imread('D:\数字图像处理\第九章学习\Fig0910(a).tif');
se = strel('square', 40);
fo = imopen(f, se);
fc = imclose(f, se);
foc = imclose(fo, se);
subplot(2,2,1), imshow(f), title('(a)原图');
subplot(2,2,2), imshow(fo), title('(b)开操作');
subplot(2,2,3), imshow(fc), title('(c)闭操作');
subplot(2,2,4), imshow(foc), title('(d) (b)的闭操作结果');

分析

  1. 图(a)中的图像设计了一些用于演示开操作和闭操作的特征,比如细小突起、细的桥接点、几个弯口、孤立的小洞、 小的孤立物和齿状边缘。
  2. 图 (b)显示了结果。注意,从图中可以看出,细的突出和外部点的边缘的不规则部分被去除掉了,细的桥接和小的孤立物也被去除了。
  3. 图 ©中的结果: 这里,细的弯口、内部的不规则边缘和小洞都被去除了。先做开操作的闭操作的结果有平滑效果.
  4. 图 (d)显示了平滑过的物体。

噪声滤波器

先开操作再闭操作,构成噪声滤波器。

编码:

f = imread('D:\数字图像处理\第九章学习\Fig0911(a).tif');
se = strel('square', 6);
fo = imopen(f, se);
foc = imclose(fo, se);
subplot(1,3,1), imshow(f), title('(a)带噪声的指纹图像');
subplot(1,3,2), imshow(fo), title('(b)图像的开操作');
subplot(1,3,3), imshow(foc), title('(c)先用开操作,再用闭操作');

在这里插入图片描述
分析

  1. 图(a)是受噪声污染的指纹二值图像,噪声为黑色背景上的亮元素和亮指纹部分的暗元素。
  2. 图(b)所示的图像。发现,对图像进行开操作可以去除噪声点,但是这种处理在指纹的纹脊上又引入一些缺口
  3. 图( c )显示了最终结果。在这个结果中,大多数噪声被消除了,开运算的闭运算可以给指纹填充缺口,但是指纹纹路并没有完全恢复 。

3.2 击中或击不中变换

击中击不中变换(HMT),HMT变换可以同时探测图像的内部和外部。研究解决目标图像识别模式识别等领域,在处理目标图像和背景的关系上能够取得更好的效果。

作用:形状检测的基本工具。

公式

A中对B进行的匹配(击中)表示为:

B1是由与一个对象相联系的B元素构成的集合,B1是由与一个对象相联系的B元素构成的集合。

图解

工具箱函数

C = bwhitmiss(A, B1, B2)

其中的 C为结果,A为输入图像,B1、B2表示结构元素。

定位图像中物体左上角的像素

编码:

f = imread('D:\数字图像处理\第九章学习\Fig0913(a).tif');
B1 = strel([0 0 0;0 1 1; 0 1 0]);
B2 = strel([1 1 1;1 0 0;1 0 0]);
g = bwhitmiss(f,B1,B2);
subplot(1,2,1), imshow(f), title('(a)原始图像');
subplot(1,2,2), imshow(g), title('(b)击中、击不中变换的结果');

分析

  1. 图(a)显示了包括各种尺寸的正方形图像。我们要定位有东、南相邻像素(这些 “击中”)和没有东北、北、西北、西和西南相邻像素(这些 “击不中”)的前景像素。这些要求导致以下B1,B2两个结构元。这两个结构元都不包括东南邻域像素,这称为不关心像素。用函数 bwhitmiss 来计算变换。
  2. 图 (b)中的每个单像素点都是图 (a)中物体左上角的像素。图 (b)中是放大后的像素,以便更清晰。bwhitmiss的替代语法可以把Bl 和 B2 组合成间隔矩阵。只要 B1等于 1 或-1,B2 等于 1, 间隔矩阵就等于 1。对于不关心像素,间隔矩阵等于 0。

3.3 bwmorph函数

工具箱函数 bwmorph 执行许多以膨胀、腐蚀和查找表运算相结合为基础的形态学操作, 调用语法为:

g = bwmorph(f, operation, n);

f 是输入的二值图像,operation 是指定所希望运算的字符串,n 是指定重复次数的正整数。

细化

f = imread('D:\数字图像处理\第九章学习\Fig0911(a).tif');
g1 = bwmorph(f, 'thin',1);
g2 = bwmorph(f, 'thin',2);
ginf = bwmorph(f,'thin', Inf);
subplot(1,4,1),imshow(f);title('(a)指纹图像:');
subplot(1,4,2),imshow(g1);title('(b)细化一次后的指纹图像:');
subplot(1,4,3),imshow(g2);title('(c)细化两次后的图像:');
subplot(1,4,4),imshow(ginf);title('(d)一直细化到稳定状态的图像:');

在这里插入图片描述
骨骼化

f = imread('D:\数字图像处理\第九章学习\Fig0916(a).tif');
fs = bwmorph(f,'skel',Inf);
for k = 1:5
    fa = fs & ~endpoints(fs);
end
subplot(1,3,1),imshow(f);title('(a)骨头图像:');
subplot(1,3,2),imshow(fs);title('(b)使用函数 bwmorph 得到的骨豁:');
subplot(1,3,3),imshow(fa);title('(c)使用函数 endpoint 裁剪后的骨豁:');

在这里插入图片描述
分析:骨骼化(Gonzalez和 Woods[2008])是另一种减少二值图像中的物体为一组细“笔画”的方法, 这些细骨豁仍保留原始物体形状的重要信息。当 operation 置为 'skel '时,函数 bwmorph 执行骨骼化。令 f 代表图(a)中类似骨头的图像,为了计算骨骼,调用 bwmorph, 令 n=Inf,图(b)显示了骨骼化的结果,与物体的基本形状相似。骨骼化和细化经常产生短的无关的“毛刺” ,有时这被叫做寄生成分。清除(或除去)这些“毛刺”的处理称为裁剪。方法是反复确认并去除端点。通过 5 次去除端点的迭代,得以后处理骨骼化图像 fs,图(c )显示了结果。

(四)标记连通分量

工具箱函数

[L, num] = bwlabel (f, conn)

f 是输入二值图像,coon指定希望的连接方式(不是4连接就是8连接),输出L叫做标记矩阵,函数num则给出找到的连通分量总数。

计算和显示连通分量的质心:

f = imread('D:\数字图像处理\第九章学习\Fig0917(a).tif');
imshow(f);title('(a)标注连通分量原始图像:');
[L,n]=bwlabel(f);        %L为标记矩阵,n为找到连接分量的总数
[r,c]=find(L==3);        %返回第3个对象所有像素的行索引和列索引 
rbar=mean(r);
cbar=mean(c);
figure,imshow(f);title('(b)标记所有对象质心后的图像:');
hold on            %保持当前图像使其不被刷新
for k=1:n
   [r,c]=find(L==k);
   rbar=mean(r);
   cbar=mean(c);
   plot(cbar,rbar,'Marker','o','MarkerEdgeColor','k',...
        'MarkerFaceColor','k','MarkerSize',10);
   plot(cbar,rbar,'Marker','*','MarkerFaceColor','w'); %其中的marker为标记
end

(五)形态学重建

概述:重构是一种涉及到两幅图像和一个结构元素的形态学变换。一幅图像,即标记,是变换的开始点。另一幅图像是掩膜,用来约束变换过程。结构元素用于定义连接性。

定义:若G是掩膜,f为标记,则从f重构g可以记为RgR_g(f),由下列的迭代过程定义:

  1. 将h1初始化为标记图像f。
  2. 创建结构元素 :B = ones(3)。
  3. 重复

    直到

    其中,标记f必须是g的一个子集。

函数

out = imreconstruct(marker,mask)

masker是标记,mask是掩膜。

5.1 通过重建进行开操作

在形态学开操作中,腐蚀典型地去除小的物体,且随后的膨胀趋向于恢复保留的物体形状。 然而,这种恢复的精确度取决于形状和结构元之间的相似性。本节讨论的方法,通过重建进行开操作能准确地恢复腐蚀之后的物体形状。用结构元B对图像 G通过重建进行开操作可定义为 :
在这里插入图片描述

f = imread('D:\数字图像处理\第九章学习\Fig0917(a).tif');
subplot(3,2,1),imshow(f);title('(a)重构原始图像');
fe=imerode(f,ones(51,1));%竖线腐蚀
subplot(3,2,2),imshow(fe);title('(b)使用竖线腐蚀后的结果');
fo=imopen(f,ones(51,1));%竖线做开运算
subplot(3,2,3),imshow(fo);title('(c)使用竖线做开运算结果');
fobr=imreconstruct(fe,f);%fe做标记
subplot(3,2,4),imshow(fobr);title('(d)使用竖线做重构开运算');
ff=imfill(f,'holes');%对f进行孔洞填充
subplot(3,2,5),imshow(ff);title('(e)对f填充孔洞后的图像');
fc=imclearborder(f,8);%清除边界,2维8邻接
subplot(3,2,6),imshow(fc);title('(f)对f清除边界后的图像');

在这里插入图片描述
分析

  1. 传统开运算中,腐蚀去除掉小对象,随后的膨胀恢复原始对象形状,但受元素结构影响,恢复的往往不是很精确。
  2. 重构则能精确恢复原始图像。

5.2 填充孔洞

令I表示二值图像,假设我们选择标记图像F,除了图像边缘外,其余部分都为 0, 边缘部分设值为 1-I:
在这里插入图片描述
函数

g = imfill(f,‘holes’);

5.3 清除边界物体

定义标记图像F为:
在这里插入图片描述
其中,/是原始图像,然后以/作为模板图像,重建
在这里插入图片描述
得到一幅图像H, 其中仅包含与边界接触的物体。

函数

g = imclearborder(f,conn)

f 是输入图像,g 是结果。conn 的值不是 4 就是 8(默认)。 物体更亮且与图像边界相连接的结构。

(六)灰度级形态学

6.1 膨胀和腐蚀

灰度图像的形态学梯度定义为膨胀运算与腐蚀运算的结果之间的差值。

膨胀定义

  1. 使用结构元素b对f的灰度膨胀定义为:

    其中,DfD_fDbD_b分别是f和b的定义域,f和b是函数而不是二值形态学情况中的集合。

  2. 当结构元素b是平坦的,即b(x,y)在其定义域内都为0时:
    在这里插入图片描述

腐蚀定义

  1. 使用结构元素b对f的灰度腐蚀定义为:
    在这里插入图片描述
    其中,DfD_fDbD_b分别是f和b的定义域。

  2. 当结构元素b是平坦的,即b(x,y)在其定义域内都为0时:
    在这里插入图片描述

膨胀和腐蚀操作

编写代码:

f = imread('D:\数字图像处理\第九章学习\Fig0923(a).tif');
se=strel('square',3);  %构造了一个平坦的3x3的结构元素
gd=imdilate(f,se);    %对原图像进行膨胀操作
ge=imerode(f,se);     %对原图像进行腐蚀操作
morph_grad=imsubtract(gd,ge); %从膨胀的图像中减去腐蚀过得图像产生一个形态学梯度。
subplot(3,2,1);imshow(f,[]);title('(a)原始图像');
subplot(3,2,2),imshow(gd,[]);title('(b)膨胀的图像');
subplot(3,2,3),imshow(ge,[]);title('(c)腐蚀的图像');
subplot(3,2,4),imshow(morph_grad,[]);title('(d)形态学梯度');

在这里插入图片描述
分析

  1. 膨胀得到的图像比原图像更明亮,并且减弱或消除小的,暗的细节部分。即比原图像模糊。
  2. 腐蚀得到的图像更暗,并且尺寸小,明亮的部分被削弱 。

6.2 开操作和闭操作

图像开运算

  1. 在灰度图像中,开操作的表达式与二值图像拥有相同的形式。
  2. 把一幅图像看做是一个三维表明,其亮度值代表xy平面上的高度值,则当结构元素b在f下面活动时,结构元素的任何部分的最高值构成了开运算的结果。
  3. 先进行腐蚀操作可以除去小的亮的图像细节,但这样会使图像变暗,接下来进行膨胀操作增强图像的整体亮度。

图像闭运算

  1. 在灰度图像中,闭操作的表达式与二值图像拥有相同的形式。
  2. 当结构元素b在f的上面活动时,结构元素的任何部分的最低值构成了闭运算的结果 。
  3. 先通过膨胀操作除去图像中的暗细节,同时增加图像的亮度,接下来对图像进行腐蚀,而不会将膨胀操作除去的部分重新引入图像中。

用开操作和闭操作做形态学平滑

f = imread('D:\数字图像处理\第九章学习\Fig0925(a).tif');
subplot(3,2,1),imshow(f);  
title('(a)木钉图像原图');   
se=strel('disk',5);     %disk其实就是一个八边形  
fo=imopen(f,se);        %经过开运算  
subplot(3,2,2),imshow(f);  
title('(b)使用半径5的disk开运算后的图像');   
foc=imclose(fo,se);  
subplot(3,2,3),imshow(foc);  
title('(c)先开后闭的图像'); 
focd=imclose(f,se);  
subplot(3,2,4),imshow(focd);  
title('(d)原始图像的闭操作'); 
foce=imopen(focd,se);  
subplot(3,2,5),imshow(foce);  
title('(e)先闭后开的图像'); 
fasf=f;  
for i=2:5  
    se=strel('disk',i);  
    fasf=imclose(imopen(fasf,se),se);  
end  
subplot(3,2,6),imshow(fasf);  
title('(f)使用开闭交替滤波后图像'); 


在这里插入图片描述
分析

  1. 图 (b)显示了开操作的图像 fo, 在这里,我们看到,亮区域己经被调低了(平滑),木钉上的暗条文几乎没有受影响。
  2. 图 (c )显示了开操作的闭操作 foe。现在我们注意到,暗区域已经被平滑得很好了,结果是整个图像得到全部平滑。这种过程通常叫做开-闭滤波。先开运算后闭运算构成噪声滤波器,用来平滑图像并去除噪声。
  3. 图 (d)显示了原始图像的闭操作结果。木钉上的暗条文已经被平滑掉了,主要留下了亮的细节(注意背景中的亮条文)。
  4. 图 (e)显示了这些条文的平滑和木钉表面的进一步平滑效果。最终结果是原始图像得到全部平滑。
  5. 图(f)是交替顺序滤波,交替顺序滤波的一种形式是用不断增大的一系列结构元执行开-闭滤波,刚开始用小的结构元,增加大小,直到与图 (b)和©中结构元的大小相同为止。交替顺序滤波与单个开-闭滤波相比,处理图像更平滑一些。

非均匀背景的补偿

f = imread('D:\数字图像处理\第九章学习\Fig0926(a).tif');
g = f>=(255*graythresh(f));
se=strel('disk',100);
fo=imopen(f,se);
f2=imsubtract(f,fo); 
g1 = f2>=(255*graythresh(f2));
subplot(2,3,1),imshow(f);  
title('(a)原始图像');  
subplot(2,3,2),imshow(g);  
title('(b)经过阈值处理后的图像');   
subplot(2,3,3),imshow(f);  
title('(c)原图开运算后的图像');  
subplot(2,3,4),imshow(f2);  
title('(d)原图减去开运算');  
subplot(2,3,5),imshow(g1);  
title('(e)最终结果');  

在这里插入图片描述
分析

  1. 图 (a) :显示了一幅米粒的图像f,图像下部的背景比上部的黑。这样的话,对不平坦的亮度进行阈值处理会很困难。
  2. 图 (b) "是阈值处理方案,图像顶端的米粒被很好地从背景中分离开来,但是图像底部的米粒没有从背景中正确地提取出来。
  3. 图(c ):对图像进行开操作,可以产生对整个图像背景的合理估计。
  4. 图(d) :把图(c )从原始图像中减去,生成一幅拥有合适的均勾背景的米粒图像.
  5. 图(e):显示了新的经阈值处理后的图像。注意,改进效果超过了图 (b)。

粒度测定 :

颗粒分析:形态学技术可以用与间接地度量颗粒的大小分布,但不能准确地识别每一个颗粒。对于形状规则且亮于背景大的颗粒,基本方法是应用不断增大尺寸的形态学开运算。

f = imread('D:\数字图像处理\第九章学习\Fig0926(a).tif');
sumpixels=zeros(1,36);  
for k=0:35  
    se=strel('disk',k);  
    fo=imopen(f,se);  
    sumpixels(k+1)=sum(fo(:));  
end    
%可以看到,连续开运算之间的表面积会减少  
plot(0:35,sumpixels),xlabel('k'),ylabel('surface area');  
title('(a)表面积和结构元素半径之间的关系');  
figure,plot(-diff(sumpixels));%diff()函数为差分或者近似倒数,即相邻2个之间的差值  
xlabel('k'),ylabel('surface area reduction');  
title('(b)减少的表面积和结构元素半径之间的关系'); 

分析

  1. (a)连续开运算之间的表面积会减小。
  2. (b)图峰值表明出现了大量的有着这种半径的对象。

6.3 重建

重建

  1. h极小值变换:标记图像是由掩膜挑选ing减去常量所得。
  2. 开运算重建:先腐蚀后重建。
  3. 闭运算重建:对图像求补、计算其开操作重建并对结果求补。

重建移去复杂的背景

f = imread('D:\数字图像处理\第九章学习\Fig0930(a).tif');
subplot(3,3,1),imshow(f);  
title('(a)原图像');    
f_obr=imreconstruct(imerode(f,ones(1,71)),f);  
subplot(3,3,2),imshow(f_obr);  
title('(b)重建的开操作');   
f_o=imopen(f,ones(1,71));    
subplot(3,3,3),imshow(f_o);  
title('(c)开操作');    
f_thr=imsubtract(f,f_obr);    %顶帽重构
subplot(3,3,4),imshow(f_thr);  
title('(d)重建的顶帽操作');  
f_th=imsubtract(f,f_o)    %标准顶帽运算,方便比较
subplot(3,3,5),imshow(f_th);  
title('(e)顶帽操作');  
g_obr=imreconstruct(imerode(f_thr,ones(1,11)),f_thr);  
subplot(3,3,6),imshow(g_obr);  
title('(f)用水平线对(b)经开运算后重建图');   
g_obrd=imdilate(g_obr,ones(1,2));  
subplot(3,3,7),imshow(g_obrd);  
title('(g)使用水平线对(f)进行膨胀');  
f2=imreconstruct(min(g_obrd,f_thr),f_thr);  
subplot(3,3,8),imshow(f2);  
title('(h)最后的重建结果');  

在这里插入图片描述
分析

为了消除每个键盘上方的水平反射光,利用这些反射比图像中任何文本字符都要宽的这个事实。用长水平线的结构元执行重建的开操作,重建的开操作(f_obr) 显示于图(b)中。为了进行对比,图(c )显示了标准的开操作 (f_o) 。重建的开操作在提取水平的相邻键之间的背景方面的确较好。从原始图像中减去重建的开操作被称为顶帽重建 , 结果示于图 (d)中。消除图 (d)中键右边的垂直反射光。这可以通过用短的水平线执行重建的开操作来完成,在这个结果中(见图 (f)),垂直的反射光不见了。但是,包括字母的垂直的细笔画也不见了。我们利用了那些已被错误消除的字母非常接近第一次膨胀(见图 (g))后还存在的其他字符这一事实,以 f_thr 作为模板,以 min(g_obrd,f_thr) 作为标记,图 (h)显示了最后的结果。注意,背景上键盘的阴影和反射光都成功去除了。

没有更多推荐了,返回首页