精华内容
下载资源
问答
  • 观察GDM小鼠模型老年期的糖代谢水平及其胰岛的形态学改变.doc
  • 大剂量辛伐他汀导致大鼠骨骼肌形态学改变 ,温冰,,他汀类药物因其有效降低胆固醇的作用成为目前临床上应用最广泛的降脂药,但他汀类药物相关临床不良反应报告在逐渐增多,其中以肌
  • 形态学——图形学形态学处理

    千次阅读 2018-05-05 11:50:29
    4.形态学:在特殊领域运算形式——结构元素(Sturcture Element),在每个像素位置上与二值图像对应的区域进行特定的逻辑运算。运算结构是输出图像的相应像素。运算效果取决于结构元素大小内容以及逻辑运算性质。...

    4.形态学:在特殊领域运算形式——结构元素(Sturcture Element),在每个像素位置上与二值图像对应的区域进行特定的逻辑运算。运算结构是输出图像的相应像素。运算效果取决于结构元素大小内容以及逻辑运算性质。形态学,即数学形态学(mathematical Morphology),是图像处理中应用最为广泛的技术之一,主要用于从图像中提取对表达和描绘区域形状有意义的图像分量,使后续的识别工作能够抓住目标对象最为本质〈最具区分能力-most discriminative)的形状特征,如边界和连通区域等。同时像细化、像素化和修剪毛刺等技术也常应用于图像的预处理和后处理中,成为图像增强技术的有力补充。

    膨胀、腐蚀、开、闭运算是数学形态学最基本的变换。

    结构元素:简单地定义为像素的结构(形状)以及一个原点(又称为锚点),使用形态学滤波涉及对图像的每个像素应用这个结构元素,当结构元素的原点与给定的像素对齐时,它与图像相交部分定义了一组进行形态学运算的像素。原则上,结构元素可以是任何形状,但通常使用简单的形状,比如方形、圆形和菱形,而原点位于中心位置(基于效率的考虑)。设有两幅图像A, S。若A是被处理的对象, 而S是用来处理A的, 则称S为结构元素。结构元素通常都是一些比较小的图像, A与S的关系类似于滤波中图像和模板的关系.

    腐蚀和膨胀两个滤波操作也运算在每个像素周围像素集合上(邻域),这是由结构元素定义的。当应用到一个给定的像素时,结构元素的锚点与该像素的位置对齐,而所有与他相交的像素都被包括在当前像素集合中。腐蚀替换当前像素为像素集合中找到的最小的像素值,而膨胀则替换为像素集合中找到的最大像素值。当然,对于二值图像,每个像素只能被替换为白色像素或黑色像素

    腐蚀和膨胀的主要功能:1)消除噪声(2)分割出独立的图像元素,在图像中连接相邻的元素(3)寻找图像中的极大值或者极小值区域(4)求出图像的梯度。

    4.1、膨胀(dilate):膨胀就是求局部最大值的操作。从数学角度来说,就是将图像与核进行卷积,计算核B覆盖区域的像素点的最大值,并把这个最大值赋值给参考点指定的元素。这样就会使图像中的高亮区域逐渐增长。模板和输入图像对应位置的元素只要有一个与的结果不为0,则结果不为0.给图像中的对象边界添加元素。用3x3的结构元素,扫描二值图像中的每一个像素,用结构元素与其覆盖的二值图像做与运算,如果都为0,则结果图像中值为0,否则为1。结果:输入图像中的前景对象扩大一圈。

    膨胀的作用和腐蚀相反, 膨胀能使物体边界扩大, 具体的膨胀结果与图像本身和结构元素的形状有关。膨胀常用于将图像中原本断裂开来的同一物体桥接起来, 对图像进行二值化之后, 很容易使一个连通的物体断裂为两个部分, 而这会给后续的图像分析(如要基于连通区域的分析统计物体的个数〉造成困扰,此时就可借助膨胀桥接断裂的缝隙

    4.2、腐蚀(erode):腐蚀和膨胀是相反的操作,腐蚀是求局部最小值的操作。腐蚀操作会使图像中的高亮区逐渐减小。模板和输入图像中对应位置的元素相与的结果全不为0时,结果才为0。删除对象边界的某些像素。用3x3的结构元素,扫描二值图像的每一个像素,用结构元素与其覆盖的二值图像做与运算,如果都为1,则结果图像中值为1,否则为0.结果:前景对象减小一圈。

    随着腐蚀结构元素的逐步增大,小于结构元素的物体相继消失。由于腐蚀运算具有上述的特点,可以用于滤波。选择适当大小和形状的结构元素,可以滤除掉所有不能 完全包含结构元素的噪声点。然而,利用腐蚀滤除噪声有一个缺点,即在去除噪声点的同时,对图像中前景物体的形状也会有影响,但当我们只关心物体的位置或者个数时,则影响不大。

    4.3、开运算:开运算是先腐蚀后膨胀。主要用于消除小物体,在纤细点处分离物体,并且在平滑较大物体的边界的同时不明显改变其面积,同时抑制比结构元小的亮细节。

    4.4、闭运算:是先膨胀后腐蚀。用来填充物体内细小空洞、连接邻近物体、平滑其边界的同时并不明显改变其面积,同时抑制比结构元小的暗细节。

    4.5、形态学梯度:就是将膨胀土和腐蚀图相减。对二值化图像进行这一操作可以将边缘突出来,可以使用形态学梯度来保留物体的边缘轮廓。

    4.6、顶帽变换:就是用源图像减去开运算图像。因为开运算带来的结果是放大了裂缝或者局部低亮度的区域。因此,从原图中减去开运算后的图,得到的效果图突出了比原图轮廓周围区域更明亮的区域。顶帽一般用于校正不均匀光照的影响(补充:均匀光照在从背景中提取目标的处理中扮演核心的角色)。

    4.7、黑帽变换:就是用闭运算减去源图像。黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域。黑帽运算一般用来分离比邻近点暗一些的斑块。

    4.8、为什么开运算可以去除目标外的孤立点?

    目标外的孤立点是和目标像素值一样的点,而非背景像素点,即为1而非0(0表示选取的空洞或背景像素值)。

    使用腐蚀,背景扩展,该孤立点被腐蚀掉,但是腐蚀会导致目标区域缩小一圈,因此需要再进行膨胀操作,将目标区域扩展回原来大小。所以,要使用开运算去除目标外的孤立点。

    4.9、为什么闭运算可以去除目标内的孔?

    目标内的孔,属于周围都是值为1,内部空洞值为0.目的是去除周围都是1的像素中间的0值。

    闭运算首先进行膨胀操作,目标区域扩张一圈,将目标区域的0去除,但是目标区域同时也会向外扩张一圈,因此需要使用腐蚀操作,使得图像中的目标区域恢复到之前的大小。

     

    展开全文
  • 目的:探讨骨髓细胞形态学改变及其对临床的诊断意义。方法:回顾性分析1231例患者的骨髓检查,并对其细胞化学染色结果进行分析。结果:按细胞形态及细胞化学染色可将1231例的患者分为,急性非淋巴细胞性白血病占11.9%,...
  • 形态学处理

    千次阅读 2018-11-18 21:21:45
    形态学操作是基于形状的一系列图像处理操作。 文章目录形态学操作集合获取形态学运算的卷积核膨胀腐蚀形态学处理效果对比 形态学操作集合 膨胀(Dilate) 对图像中的高亮部分进行膨胀,是求局部最大值的操作,可以...

    形态学操作是基于形状的一系列图像处理操作。

    形态学操作集合

    膨胀(Dilate)
    对图像中的高亮部分进行膨胀,是求局部最大值的操作,可以消除一些细小的暗点和暗线。

    腐蚀(erode)
    对原图中的高亮部分进行腐蚀,是求局部最小值的操作,可以消除一些细小的亮点和亮线。

    形态学梯度(Morphological Gradient)
    是膨胀图与腐蚀图之差, 可以用来保留物体的边缘轮廓。

    开运算(Opening Operation)
    先腐蚀后膨胀,在消除一些细小的亮点和亮线、平滑较大物体的边界的同时并不明显改变其面积。

    闭运算(Closing Operation)
    先膨胀后腐蚀,在消除一些细小的暗点和暗线的同时并不明显改变其面积。

    顶帽运算(Top Hat)
    原图与开运算的结果图之差,可以分离比邻近点亮一些的斑块。

    黑帽运算(Black Hat)
    闭运算的结果图与原图之差,可以分离比邻近点暗一些的斑块。

    获取形态学运算的卷积核

    一般使用 getStructuringElemen() 函数,返回指定形状和尺寸的形态学卷积核。

    函数原型:

    def getStructuringElement(shape, ksize, anchor=None)
    

    参数:

    • shape:表示卷积核的形状,有如下三种:

      矩形:MORPH_RECT = 0

      交叉形::MORPH_CROSS = 1

      椭圆形::MORPH_ELLIPSE = 2

    • ksize:表示卷积核的尺寸

    • anchor:表示卷积核锚点的位置,有默认值Point(-1,-1),表示锚点位于中心。且需要注意,十字形卷积核的形状唯一依赖于锚点的位置。而在其他情况下,锚点只是影响了形态学运算结果的偏移。

    使用矩形卷积核进行形态学处理:

    使用交叉形卷积核进行形态学处理:

    使用椭圆形卷积核进行形态学处理:

    膨胀

    函数原型:

    def dilate(src, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None)
    

    参数:

    • src:输入图像,即源图像,通道数量任意

    • kernel:膨胀操作的核,可以使用getStructuringElement()函数获取

    • dst:输出的目标图像

    • anchor:锚的位置,其有默认值(-1,-1),表示锚位于中心

    • iterations:迭代使用erode()函数的次数,默认值为1

    • borderType:用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT

    • borderValue:当边界为常数时的边界值,有默认值morphologyDefaultBorderValue()

    腐蚀

    函数原型:

    def erode(src, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None)
    

    参数:

    • src:输入图像,即源图像,通道数量任意

    • kernel:膨胀操作的核,可以使用getStructuringElement()函数获取

    • dst:输出的目标图像

    • anchor:锚的位置,其有默认值(-1,-1),表示锚位于中心

    • iterations:迭代使用erode()函数的次数,默认值为1

    • borderType:用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT

    • borderValue:当边界为常数时的边界值

    形态学处理

    函数原型:

    def morphologyEx(src, op, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None)
    

    参数:

    • src:输入图像,即源图像,通道数量任意

    • op:表示形态学运算的类型,可以是如下之一的标识符:

      MORPH_OPEN – 开运算(Opening operation)

      MORPH_CLOSE – 闭运算(Closing operation)

      MORPH_GRADIENT -形态学梯度(Morphological gradient)

      MORPH_TOPHAT - “顶帽”(“Top hat”)

      MORPH_BLACKHAT - “黑帽”(“Black hat“)

    • kernel:膨胀操作的核,可以使用getStructuringElement()函数获取

    • dst:输出的目标图像

    • anchor:锚的位置,其有默认值(-1,-1),表示锚位于中心

    • iterations:迭代使用erode()函数的次数,默认值为1

    • borderType:用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT

    • borderValue:当边界为常数时的边界值

    效果对比

    使用 5 × 5 5 \times 5 5×5的卷积核进行形态学处理:

    使用 9 × 9 9 \times 9 9×9的卷积核进行形态学处理:

    import cv2
    
    def process(x):
        k = cv2.getTrackbarPos('ksize', 'process')
        MorphShapes = cv2.getTrackbarPos('MorphShapes', 'process')
    
        if k % 2 == 0:
            return
    
        kernel = cv2.getStructuringElement(MorphShapes,(k, k))
    
        dilate = cv2.dilate(gray, kernel)
        close = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel)
        erode = cv2.erode(gray, kernel)
        open_o = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)
        gradient = cv2.morphologyEx(gray, cv2.MORPH_GRADIENT, kernel)
        top_hat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, kernel)
        black_hat = cv2.morphologyEx(gray, cv2.MORPH_BLACKHAT, kernel)
    
        cv2.imshow('dilate', dilate)
        cv2.imshow('close', close)
        cv2.imshow('erode', erode)
        cv2.imshow('open', open_o)
        cv2.imshow('gradient', gradient)
        cv2.imshow('top_hat', top_hat)
        cv2.imshow('black_hat', black_hat)
    
    MorphShapes = 0
    ksize = 3
    
    cv2.namedWindow('process')
    img = cv2.imread("./91_frame.png")
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    cv2.imshow('process', img)
    
    cv2.createTrackbar('ksize', 'process', ksize, 25, process)
    cv2.createTrackbar('MorphShapes', 'process', MorphShapes, 2, process)
    
    process(0)
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    

    经过形态学处理之后的边缘检测效果对比:

    原图 / 膨胀后边缘检测
    边缘检测 / 闭运算后边缘检测

    展开全文
  • 上篇文章中,我们重点了解了腐蚀和膨胀这两种最基本的形态学操作,而运用这两个基本操作,我们可以实现更高级的形态学变换。 所以,本文的主角是OpenCV中的morphologyEx函数,它利用基本的膨胀和腐蚀技术,来执行...


    本系列文章由@浅墨_毛星云 出品,转载请注明出处。  

    文章链接: http://blog.csdn.net/poem_qianmo/article/details/23184547

    作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442

    知乎:http://www.zhihu.com/people/mao-xing-yun

    邮箱: happylifemxy@163.com

    写作当前博文时配套使用的OpenCV版本: 2.4.8

     

    上篇文章中,我们重点了解了腐蚀和膨胀这两种最基本的形态学操作,而运用这两个基本操作,我们可以实现更高级的形态学变换。

    所以,本文的主角是OpenCV中的morphologyEx函数,它利用基本的膨胀和腐蚀技术,来执行更加高级的形态学变换,如开闭运算、形态学梯度、“顶帽”、“黑帽”等等。

     先上几张示例程序的截图吧:


    有没有很熟悉这张图?没错,这就是最近热映的电影Captain America~

    下面这张图的效果就有些凶残了:

    OK,截图先看到这里。在正文之前先来唠唠和主题相关的事情。


    第一件事,OpenCV最新版本更新到了2.4.9。


    在写这篇博文的两天之前(4月25日上午),OpenCV官网页面显示最新版本还是2.4.8,但是通过浅墨细心地发现,文档页面的标题已经悄悄而低调地改成了2.4.9.所以我们当时应该可以去断定,OpenCV2.4.9应该马上就要和我们见面了。

     

    果然,OpenCV2.4.9就在两天后(4月27日),正式在OpenCV官方网站上上线了。现在转到OpenCV的官方主页,赫然发现最新版本已然显示为2.4.9:

    这是OpenCV的官方主页传送门:http://opencv.org/

    大家可以自己前去看看以及下载最新版本的OpenCV。如果不出意外的话呢,下次文章我们就将紧跟时代,用上最新版本的OpenCV2.4.9进行讲解和程序的书写,所以,大家在看这篇文章之后呢,可以去下载当前最新的2.4.9版本并装上配置好。




    第二件事,是浅墨想跟大家做一个关于OpenCV系列文章的书写内容和风格的思想汇报。


    是这样的,浅墨发现最近几期写出来的文章有些偏离自己开始开这个专栏的最初的愿望——原理和概念部分占的比重有些大,有些弱化OpenCV实际的使用。

    写这些博文的初心是教大家如何使用OpenCV来写代码,原理部分我想很多朋友应该多少都懂,就算某些同学对某些概念有些模糊,大家也完全可以带着关键词句去google或者百度。

    浅墨的想法是,以后的专栏文章原理部分尽量从简,“深入”的源码剖析部分也是从简,重点突出“浅出”部分,让大家快速上手OpenCV函数的使用,这样浅墨的工作量也会小很多,更新也会更勤。

    PS:浅墨其实每次在写图像处理原理部分的时候都特纠结,因为浅墨其实感兴趣的和大家一样,也是如何写代码,而不是那些多多少少让人提不起兴趣来的图像处理公式和概念。这往往就照成了博文更新的拖延症。

    所以呢,在浅墨以后写的OpenCV文章中,原理和深入部分我们就点到为止,文章的拳头内容是“浅出”部分,重点教大家如何快速上手OpenCV API。我想这也是大家一直期待和想要看到的浅墨出品的文章的样子吧。:)

    OK,大概就是这些。我们开始今天的正题。






    一、理论与概念讲解——从现象到本质



    首先呢,要知道形态学的高级形态,往往都是建立在腐蚀和膨胀这两个基本操作之上的。而关于腐蚀和膨胀,概念和细节以及相关代码可以看浅墨之前写的这篇文章:


    【OpenCV入门教程之十】 形态学图像处理(一):膨胀与腐蚀


    对膨胀和腐蚀心中有数了,接下来的高级形态学操作,应该就不难理解。

    另外,为了下面对比和演示以及理解的方便,浅墨自己制作了一张毛笔字图,这里先上原图:

     

     OK,我们开始讲解。





    1.1 开运算(Opening Operation)

     



    开运算(Opening Operation),其实就是先腐蚀后膨胀的过程。其数学表达式如下:




    开运算可以用来消除小物体、在纤细点处分离物体、平滑较大物体的边界的同时并不明显改变其面积。效果图是这样的:

    实际效果图:

     




    1.2 闭运算(Closing Operation)


    先膨胀后腐蚀的过程称为闭运算(Closing Operation),其数学表达式如下:

     

    闭运算能够排除小型黑洞(黑色区域)。效果图如下所示:

     

    实际效果图:





    1.3 形态学梯度(MorphologicalGradient)


    形态学梯度(Morphological Gradient)为膨胀图与腐蚀图之差,数学表达式如下:

     

    对二值图像进行这一操作可以将团块(blob)的边缘突出出来。我们可以用形态学梯度来保留物体的边缘轮廓,如下所示:

     

    实际素材效果图:





    1.4 顶帽(Top Hat)


    顶帽运算(Top Hat)又常常被译为”礼帽“运算。为原图像与上文刚刚介绍的“开运算“的结果图之差,数学表达式如下:

    因为开运算带来的结果是放大了裂缝或者局部低亮度的区域,因此,从原图中减去开运算后的图,得到的效果图突出了比原图轮廓周围的区域更明亮的区域,且这一操作和选择的核的大小相关。

    顶帽运算往往用来分离比邻近点亮一些的斑块。当一幅图像具有大幅的背景的时候,而微小物品比较有规律的情况下,可以使用顶帽运算进行背景提取。

    如下所示:

    素材效果图:

     

     



    1.5 黑帽(Black Hat)



    黑帽(Black Hat)运算为”闭运算“的结果图与原图像之差。数学表达式为:


    黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,且这一操作和选择的核的大小相关。

    所以,黑帽运算用来分离比邻近点暗一些的斑块。非常完美的轮廓效果图:

     

    实际素材效果图:





     

    二、深入——OpenCV源码分析溯源




    本文的主角是OpenCV中的morphologyEx函数,它利用基本的膨胀和腐蚀技术,来执行更加高级的形态学变换,如开闭运算,形态学梯度,“顶帽”、“黑帽”等等。这一节我们来一起看一下morphologyEx函数的源代码。

    //-----------------------------------【erode()函数中文注释版源代码】----------------------------  
    //   说明:以下代码为来自于计算机开源视觉库OpenCV的官方源代码  
    //   OpenCV源代码版本:2.4.8  
    //   源码路径:…\opencv\sources\modules\imgproc\src\morph.cpp  
    //   源文件中如下代码的起始行数:1369行  
    //   中文注释by浅墨  
    //--------------------------------------------------------------------------------------------------------   
    void cv::morphologyEx( InputArray _src,OutputArray _dst, int op,
                           InputArray kernel, Pointanchor, int iterations,
                           int borderType, constScalar& borderValue )
    {
    //拷贝Mat数据到临时变量
       Mat src = _src.getMat(), temp;
       _dst.create(src.size(), src.type());
       Mat dst = _dst.getMat();
     
    //一个大switch,根据不同的标识符取不同的操作
       switch( op )
        {
       case MORPH_ERODE:
           erode( src, dst, kernel, anchor, iterations, borderType, borderValue );
           break;
       case MORPH_DILATE:
           dilate( src, dst, kernel, anchor, iterations, borderType, borderValue );
           break;
       case MORPH_OPEN:
           erode( src, dst, kernel, anchor, iterations, borderType, borderValue );
           dilate( dst, dst, kernel, anchor, iterations, borderType, borderValue );
           break;
       case CV_MOP_CLOSE:
           dilate( src, dst, kernel, anchor, iterations, borderType, borderValue );
           erode( dst, dst, kernel, anchor, iterations, borderType, borderValue );
           break;
       case CV_MOP_GRADIENT:
           erode( src, temp, kernel, anchor, iterations, borderType, borderValue );
           dilate( src, dst, kernel, anchor, iterations, borderType, borderValue );
           dst -= temp;
           break;
       case CV_MOP_TOPHAT:
           if( src.data != dst.data )
               temp = dst;
           erode( src, temp, kernel, anchor, iterations, borderType, borderValue );
            dilate( temp, temp, kernel, anchor,iterations, borderType, borderValue );
           dst = src - temp;
           break;
       case CV_MOP_BLACKHAT:
           if( src.data != dst.data )
               temp = dst;
           dilate( src, temp, kernel, anchor, iterations, borderType, borderValue);
           erode( temp, temp, kernel, anchor, iterations, borderType, borderValue);
           dst = temp - src;
           break;
       default:
           CV_Error( CV_StsBadArg, "unknown morphological operation" );
        }
    }

    看上面的源码可以发现,其实morphologyEx函数其实就是内部一个大switch而已。根据不同的标识符取不同的操作。比如开运算MORPH_OPEN,按我们上文中讲解的数学表达式,就是先腐蚀后膨胀,即依次调用erode和dilate函数,为非常简明干净的代码。

     




     


    三、浅出——API函数快速上手

     



    3.1 morphologyEx函数详解



    上面我们已经讲到,morphologyEx函数利用基本的膨胀和腐蚀技术,来执行更加高级形态学变换,如开闭运算,形态学梯度,“顶帽”、“黑帽”等等。这一节我们来了解它的参数意义和使用方法。

    C++: void morphologyEx(
    InputArray src,
    OutputArray dst,
    int op,
    InputArraykernel,
    Pointanchor=Point(-1,-1),
    intiterations=1,
    intborderType=BORDER_CONSTANT,
    constScalar& borderValue=morphologyDefaultBorderValue() );

    • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。图像位深应该为以下五种之一:CV_8U, CV_16U,CV_16S, CV_32F 或CV_64F。
    • 第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。
    • 第三个参数,int类型的op,表示形态学运算的类型,可以是如下之一的标识符:
      • MORPH_OPEN – 开运算(Opening operation)
      • MORPH_CLOSE – 闭运算(Closing operation)
      • MORPH_GRADIENT -形态学梯度(Morphological gradient)
      • MORPH_TOPHAT - “顶帽”(“Top hat”)
      • MORPH_BLACKHAT - “黑帽”(“Black hat“)

    另有CV版本的标识符也可选择,如CV_MOP_CLOSE,CV_MOP_GRADIENT,CV_MOP_TOPHAT,CV_MOP_BLACKHAT,这应该是OpenCV1.0系列版本遗留下来的标识符,和上面的“MORPH_OPEN”一样的效果。

     

    • 第四个参数,InputArray类型的kernel,形态学运算的内核。若为NULL时,表示的是使用参考点位于中心3x3的核。我们一般使用函数 getStructuringElement配合这个参数的使用。getStructuringElement函数会返回指定形状和尺寸的结构元素(内核矩阵)。关于getStructuringElement我们上篇文章中讲过了,这里为了大家参阅方便,再写一遍:

    其中,getStructuringElement函数的第一个参数表示内核的形状,我们可以选择如下三种形状之一:

      • 矩形: MORPH_RECT
      • 交叉形: MORPH_CROSS
      • 椭圆形: MORPH_ELLIPSE

    而getStructuringElement函数的第二和第三个参数分别是内核的尺寸以及锚点的位置。

    我们一般在调用erode以及dilate函数之前,先定义一个Mat类型的变量来获得getStructuringElement函数的返回值。对于锚点的位置,有默认值Point(-1,-1),表示锚点位于中心。且需要注意,十字形的element形状唯一依赖于锚点的位置。而在其他情况下,锚点只是影响了形态学运算结果的偏移。

    getStructuringElement函数相关的调用示例代码如下:

    int g_nStructElementSize = 3; //结构元素(内核矩阵)的尺寸
     
    //获取自定义核
    Mat element =getStructuringElement(MORPH_RECT,
           Size(2*g_nStructElementSize+1,2*g_nStructElementSize+1),
           Point(g_nStructElementSize, g_nStructElementSize ));


    调用这样之后,我们便可以在接下来调用erode、dilate或morphologyEx函数时,kernel参数填保存getStructuringElement返回值的Mat类型变量。对应于我们上面的示例,就是填element变量。

    • 第五个参数,Point类型的anchor,锚的位置,其有默认值(-1,-1),表示锚位于中心。
    • 第六个参数,int类型的iterations,迭代使用函数的次数,默认值为1。
    • 第七个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_ CONSTANT。
    • 第八个参数,const Scalar&类型的borderValue,当边界为常数时的边界值,有默认值morphologyDefaultBorderValue(),一般我们不用去管他。需要用到它时,可以看官方文档中的createMorphologyFilter()函数得到更详细的解释。

    其中的这些操作都可以进行就地(in-place)操作。且对于多通道图像,每一个通道都是单独进行操作。

     OK,讲解完毕,下面就是使用的范例。



    高能预警!高能预警!高能预警!

    一大波示例代码正在逼近。

    为了方便大家需要的时候随时取用。下面我们依次列举出开运算,闭运算,形态学梯度,顶帽,黑帽,腐蚀,膨胀的效果实现简化版完整代码。

    其实说白了,这些代码基本上内容一致,其实就是改一下morphologyEx里面的第三个标识符参数而已。核都是选的MORPH_RECT,矩形元素结构。

    另外,通过看源码我们发现,最基本的腐蚀和膨胀操作也可以用morphologyEx函数来实现,他们由morphologyEx函数源码中switch的前两个case来实现(虽然在case体内就是简单地各自调用了一下erode和dilation函数,但还是有写出来的必要)。所以在这里,我们也用morphologyEx再重新来实现一遍他们。

    按着顺序来列出吧,就直接列详细注释好的代码和运行结果了。

     




    3.2 开运算示例程序


    OpenCV中调用morphologyEx函数进行开运算操作的示例程序如下:

    //-----------------------------------【头文件包含部分】---------------------------------------
    //            描述:包含程序所依赖的头文件
    //----------------------------------------------------------------------------------------------
    #include <opencv2/opencv.hpp>
    #include<opencv2/highgui/highgui.hpp>
    #include<opencv2/imgproc/imgproc.hpp>
     
    //-----------------------------------【命名空间声明部分】---------------------------------------
    //            描述:包含程序所使用的命名空间
    //-----------------------------------------------------------------------------------------------
    using namespace cv;
    //-----------------------------------【main( )函数】--------------------------------------------
    //            描述:控制台应用程序的入口函数,我们的程序从这里开始
    //-----------------------------------------------------------------------------------------------
    int main( )
    {
           //载入原始图  
           Mat image = imread("1.jpg");  //工程目录下应该有一张名为1.jpg的素材图
           //创建窗口  
           namedWindow("【原始图】开运算"); 
           namedWindow("【效果图】开运算"); 
           //显示原始图 
           imshow("【原始图】开运算", image); 
           //定义核
           Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); 
           //进行形态学操作
           morphologyEx(image,image, MORPH_OPEN, element);
           //显示效果图 
           imshow("【效果图】开运算", image); 
     
           waitKey(0); 
     
           return 0; 
    }

    运行效果图:







    3.3 闭运算示例程序



    OpenCV中调用morphologyEx函数进行闭运算操作的示例程序如下:


    //-----------------------------------【头文件包含部分】---------------------------------------
    //            描述:包含程序所依赖的头文件
    //----------------------------------------------------------------------------------------------
    #include <opencv2/opencv.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include<opencv2/imgproc/imgproc.hpp>
     
    //-----------------------------------【命名空间声明部分】---------------------------------------
    //            描述:包含程序所使用的命名空间
    //-----------------------------------------------------------------------------------------------
    using namespace cv;
    //-----------------------------------【main( )函数】--------------------------------------------
    //            描述:控制台应用程序的入口函数,我们的程序从这里开始
    //-----------------------------------------------------------------------------------------------
    int main( )
    {
           //载入原始图  
           Mat image = imread("1.jpg");  //工程目录下应该有一张名为1.jpg的素材图
           //创建窗口  
           namedWindow("【原始图】闭运算"); 
           namedWindow("【效果图】闭运算"); 
           //显示原始图 
           imshow("【原始图】闭运算", image); 
           //定义核
           Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); 
           //进行形态学操作
           morphologyEx(image,image, MORPH_CLOSE, element);
           //显示效果图 
           imshow("【效果图】闭运算", image); 
     
           waitKey(0); 
     
           return 0; 
    }

    运行效果图:





    3.4 形态学梯度示例程序



    OpenCV中调用morphologyEx函数进行形态学梯度操作的示例程序如下:

    //-----------------------------------【头文件包含部分】---------------------------------------
    //            描述:包含程序所依赖的头文件
    //----------------------------------------------------------------------------------------------
    #include <opencv2/opencv.hpp>
    #include<opencv2/highgui/highgui.hpp>
    #include<opencv2/imgproc/imgproc.hpp>
     
    //-----------------------------------【命名空间声明部分】---------------------------------------
    //            描述:包含程序所使用的命名空间
    //-----------------------------------------------------------------------------------------------
    using namespace cv;
    //-----------------------------------【main( )函数】--------------------------------------------
    //            描述:控制台应用程序的入口函数,我们的程序从这里开始
    //-----------------------------------------------------------------------------------------------
    int main( )
    {
           //载入原始图  
           Mat image = imread("1.jpg");  //工程目录下应该有一张名为1.jpg的素材图
           //创建窗口  
           namedWindow("【原始图】形态学梯度"); 
           namedWindow("【效果图】形态学梯度"); 
           //显示原始图 
           imshow("【原始图】形态学梯度", image); 
           //定义核
           Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); 
           //进行形态学操作
           morphologyEx(image,image, MORPH_GRADIENT, element);
           //显示效果图 
           imshow("【效果图】形态学梯度", image); 
     
           waitKey(0); 
     
           return 0; 
    }

    运行效果图:






    3.5 顶帽运算(Top Hat)示例程序



    OpenCV中调用morphologyEx函数进行顶帽运算操作的示例程序如下:

    //-----------------------------------【头文件包含部分】---------------------------------------
    //            描述:包含程序所依赖的头文件
    //----------------------------------------------------------------------------------------------
    #include <opencv2/opencv.hpp>
    #include<opencv2/highgui/highgui.hpp>
    #include<opencv2/imgproc/imgproc.hpp>
     
    //-----------------------------------【命名空间声明部分】---------------------------------------
    //            描述:包含程序所使用的命名空间
    //-----------------------------------------------------------------------------------------------
    using namespace cv;
    //-----------------------------------【main( )函数】--------------------------------------------
    //            描述:控制台应用程序的入口函数,我们的程序从这里开始
    //-----------------------------------------------------------------------------------------------
    int main( )
    {
           //载入原始图  
           Mat image = imread("1.jpg");  //工程目录下应该有一张名为1.jpg的素材图
           //创建窗口  
           namedWindow("【原始图】顶帽运算"); 
           namedWindow("【效果图】顶帽运算"); 
           //显示原始图 
           imshow("【原始图】顶帽运算", image); 
           //定义核
           Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); 
           //进行形态学操作
           morphologyEx(image,image, MORPH_TOPHAT, element);
           //显示效果图 
           imshow("【效果图】顶帽运算", image); 
     
           waitKey(0); 
     
           return 0; 
    }

    运行效果图:




    3.6 黑帽运算(BlackHat)示例程序


    OpenCV中调用morphologyEx函数进行黑帽运算操作的示例程序如下:

    //-----------------------------------【头文件包含部分】---------------------------------------
    //            描述:包含程序所依赖的头文件
    //----------------------------------------------------------------------------------------------
    #include <opencv2/opencv.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include<opencv2/imgproc/imgproc.hpp>
     
    //-----------------------------------【命名空间声明部分】---------------------------------------
    //            描述:包含程序所使用的命名空间
    //-----------------------------------------------------------------------------------------------
    using namespace cv;
    //-----------------------------------【main( )函数】--------------------------------------------
    //            描述:控制台应用程序的入口函数,我们的程序从这里开始
    //-----------------------------------------------------------------------------------------------
    int main( )
    {
           //载入原始图  
           Mat image = imread("1.jpg");  //工程目录下应该有一张名为1.jpg的素材图
           //创建窗口  
           namedWindow("【原始图】黑帽运算"); 
           namedWindow("【效果图】黑帽运算"); 
           //显示原始图 
           imshow("【原始图】黑帽运算", image); 
           //定义核
           Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); 
           //进行形态学操作
           morphologyEx(image,image, MORPH_BLACKHAT, element);
           //显示效果图 
           imshow("【效果图】黑帽运算", image); 
     
           waitKey(0); 
     
           return 0; 
    }

    运行效果图:



     



    3.7 腐蚀(morphologyEx调用版)示例程序



    OpenCV中调用morphologyEx函数进行腐蚀操作的示例程序如下:

    //-----------------------------------【头文件包含部分】---------------------------------------
    //            描述:包含程序所依赖的头文件
    //----------------------------------------------------------------------------------------------
    #include <opencv2/opencv.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include<opencv2/imgproc/imgproc.hpp>
     
    //-----------------------------------【命名空间声明部分】---------------------------------------
    //            描述:包含程序所使用的命名空间
    //-----------------------------------------------------------------------------------------------
    using namespace cv;
    //-----------------------------------【main( )函数】--------------------------------------------
    //            描述:控制台应用程序的入口函数,我们的程序从这里开始
    //-----------------------------------------------------------------------------------------------
    int main( )
    {
           //载入原始图  
           Mat image = imread("1.jpg");  //工程目录下应该有一张名为1.jpg的素材图
           //创建窗口  
           namedWindow("【原始图】腐蚀"); 
           namedWindow("【效果图】腐蚀"); 
           //显示原始图 
           imshow("【原始图】腐蚀", image); 
           //定义核
           Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); 
           //进行形态学操作
           morphologyEx(image,image, MORPH_ERODE, element);
           //显示效果图 
           imshow("【效果图】腐蚀", image); 
     
           waitKey(0); 
     
           return 0; 
    }

    运行效果图:



     



    3.8 膨胀(morphologyEx调用版)示例程序



    OpenCV中调用morphologyEx函数进行膨胀操作的示例程序如下:

    //-----------------------------------【头文件包含部分】---------------------------------------
    //            描述:包含程序所依赖的头文件
    //----------------------------------------------------------------------------------------------
    #include <opencv2/opencv.hpp>
    #include<opencv2/highgui/highgui.hpp>
    #include<opencv2/imgproc/imgproc.hpp>
     
    //-----------------------------------【命名空间声明部分】---------------------------------------
    //            描述:包含程序所使用的命名空间
    //-----------------------------------------------------------------------------------------------
    using namespace cv;
    //-----------------------------------【main( )函数】--------------------------------------------
    //            描述:控制台应用程序的入口函数,我们的程序从这里开始
    //-----------------------------------------------------------------------------------------------
    int main( )
    {
           //载入原始图  
           Mat image = imread("1.jpg");  //工程目录下应该有一张名为1.jpg的素材图
           //创建窗口  
           namedWindow("【原始图】膨胀"); 
           namedWindow("【效果图】膨胀"); 
           //显示原始图 
           imshow("【原始图】膨胀", image); 
           //定义核
           Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); 
           //进行形态学操作
           morphologyEx(image,image, MORPH_DILATE, element);
           //显示效果图 
           imshow("【效果图】膨胀", image); 
     
           waitKey(0); 
     
           return 0; 
    }

    运行效果图:



     








    四、综合示例——在实战中熟稔

     



    依然是每篇文章都会配给大家的一个详细注释的博文配套示例程序,把这篇文章中介绍的知识点以代码为载体,展现给大家。

    这个示例程序中,一共有四个显示图像的窗口。

    原始图一个,开/闭运算为一个,腐蚀/膨胀为一个,顶帽/黑帽运算为一个。

    分别使用滚动条,来控制得到的形态学效果。且迭代值为10的时候,为中间。

    另外,还可以通过键盘按键1,2,3以及空格,来调节成不同的元素结构(矩形、椭圆、十字形)。说明页面如下:





    废话不多说,上代码吧:


    //-----------------------------------【程序说明】----------------------------------------------
    //		程序名称::《【OpenCV入门教程之十一】形态学图像处理(一):膨胀与腐蚀  》 博文配套源码 
    //		开发所用IDE版本:Visual Studio 2010
    //   		开发所用OpenCV版本:	2.4.8
    //		2014年4月25日 Create by 浅墨
    //----------------------------------------------------------------------------------------------
    
    //-----------------------------------【头文件包含部分】---------------------------------------
    //		描述:包含程序所依赖的头文件
    //---------------------------------------------------------------------------------------------- 
    #include <opencv2/opencv.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    
    //-----------------------------------【命名空间声明部分】--------------------------------------
    //		描述:包含程序所使用的命名空间
    //----------------------------------------------------------------------------------------------- 
    using namespace std;
    using namespace cv;
    
    
    //-----------------------------------【全局变量声明部分】--------------------------------------
    //		描述:全局变量声明
    //-----------------------------------------------------------------------------------------------
    Mat g_srcImage, g_dstImage;//原始图和效果图
    int g_nElementShape = MORPH_RECT;//元素结构的形状
    
    //变量接收的TrackBar位置参数
    int g_nMaxIterationNum = 10;
    int g_nOpenCloseNum = 0;
    int g_nErodeDilateNum = 0;
    int g_nTopBlackHatNum = 0;
    
    
    
    //-----------------------------------【全局函数声明部分】--------------------------------------
    //		描述:全局函数声明
    //-----------------------------------------------------------------------------------------------
    static void on_OpenClose(int, void*);//回调函数
    static void on_ErodeDilate(int, void*);//回调函数
    static void on_TopBlackHat(int, void*);//回调函数
    static void ShowHelpText();//帮助文字显示
    
    
    //-----------------------------------【main( )函数】--------------------------------------------
    //		描述:控制台应用程序的入口函数,我们的程序从这里开始
    //-----------------------------------------------------------------------------------------------
    int main( )
    {
    	//改变console字体颜色
    	system("color 2F");  
    
    	ShowHelpText();
    
    	//载入原图
    	g_srcImage = imread("1.jpg");//工程目录下需要有一张名为1.jpg的素材图
    	if( !g_srcImage.data ) { printf("Oh,no,读取srcImage错误~! \n"); return false; }
    
    	//显示原始图
    	namedWindow("【原始图】");
    	imshow("【原始图】", g_srcImage);
    
    	//创建三个窗口
    	namedWindow("【开运算/闭运算】",1);
    	namedWindow("【腐蚀/膨胀】",1);
    	namedWindow("【顶帽/黑帽】",1);
    
    	//参数赋值
    	g_nOpenCloseNum=9;
    	g_nErodeDilateNum=9;
    	g_nTopBlackHatNum=2;
    
    	//分别为三个窗口创建滚动条
    	createTrackbar("迭代值", "【开运算/闭运算】",&g_nOpenCloseNum,g_nMaxIterationNum*2+1,on_OpenClose);
    	createTrackbar("迭代值", "【腐蚀/膨胀】",&g_nErodeDilateNum,g_nMaxIterationNum*2+1,on_ErodeDilate);
    	createTrackbar("迭代值", "【顶帽/黑帽】",&g_nTopBlackHatNum,g_nMaxIterationNum*2+1,on_TopBlackHat);
    
    	//轮询获取按键信息
    	while(1)
    	{
    		int c;
    
    		//执行回调函数
    		on_OpenClose(g_nOpenCloseNum, 0);
    		on_ErodeDilate(g_nErodeDilateNum, 0);
    		on_TopBlackHat(g_nTopBlackHatNum,0);
    
    		//获取按键
    		c = waitKey(0);
    
    		//按下键盘按键Q或者ESC,程序退出
    		if( (char)c == 'q'||(char)c == 27 )
    			break;
    		//按下键盘按键1,使用椭圆(Elliptic)结构元素结构元素MORPH_ELLIPSE
    		if( (char)c == 49 )//键盘按键1的ASII码为49
    			g_nElementShape = MORPH_ELLIPSE;
    		//按下键盘按键2,使用矩形(Rectangle)结构元素MORPH_RECT
    		else if( (char)c == 50 )//键盘按键2的ASII码为50
    			g_nElementShape = MORPH_RECT;
    		//按下键盘按键3,使用十字形(Cross-shaped)结构元素MORPH_CROSS
    		else if( (char)c == 51 )//键盘按键3的ASII码为51
    			g_nElementShape = MORPH_CROSS;
    		//按下键盘按键space,在矩形、椭圆、十字形结构元素中循环
    		else if( (char)c == ' ' )
    			g_nElementShape = (g_nElementShape + 1) % 3;
    	}
    
    	return 0;
    }
    
    
    //-----------------------------------【on_OpenClose( )函数】----------------------------------
    //		描述:【开运算/闭运算】窗口的回调函数
    //-----------------------------------------------------------------------------------------------
    static void on_OpenClose(int, void*)
    {
    	//偏移量的定义
    	int offset = g_nOpenCloseNum - g_nMaxIterationNum;//偏移量
    	int Absolute_offset = offset > 0 ? offset : -offset;//偏移量绝对值
    	//自定义核
    	Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset*2+1, Absolute_offset*2+1), Point(Absolute_offset, Absolute_offset) );
    	//进行操作
    	if( offset < 0 )
    		morphologyEx(g_srcImage, g_dstImage, CV_MOP_OPEN, element);
    	else
    		morphologyEx(g_srcImage, g_dstImage, CV_MOP_CLOSE, element);
    	//显示图像
    	imshow("【开运算/闭运算】",g_dstImage);
    }
    
    
    //-----------------------------------【on_ErodeDilate( )函数】----------------------------------
    //		描述:【腐蚀/膨胀】窗口的回调函数
    //-----------------------------------------------------------------------------------------------
    static void on_ErodeDilate(int, void*)
    {
    	//偏移量的定义
    	int offset = g_nErodeDilateNum - g_nMaxIterationNum;	//偏移量
    	int Absolute_offset = offset > 0 ? offset : -offset;//偏移量绝对值
    	//自定义核
    	Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset*2+1, Absolute_offset*2+1), Point(Absolute_offset, Absolute_offset) );
    	//进行操作
    	if( offset < 0 )
    		erode(g_srcImage, g_dstImage, element);
    	else
    		dilate(g_srcImage, g_dstImage, element);
    	//显示图像
    	imshow("【腐蚀/膨胀】",g_dstImage);
    }
    
    
    //-----------------------------------【on_TopBlackHat( )函数】--------------------------------
    //		描述:【顶帽运算/黑帽运算】窗口的回调函数
    //----------------------------------------------------------------------------------------------
    static void on_TopBlackHat(int, void*)
    {
    	//偏移量的定义
    	int offset = g_nTopBlackHatNum - g_nMaxIterationNum;//偏移量
    	int Absolute_offset = offset > 0 ? offset : -offset;//偏移量绝对值
    	//自定义核
    	Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset*2+1, Absolute_offset*2+1), Point(Absolute_offset, Absolute_offset) );
    	//进行操作
    	if( offset < 0 )
    		morphologyEx(g_srcImage, g_dstImage, MORPH_TOPHAT , element);
    	else
    		morphologyEx(g_srcImage, g_dstImage, MORPH_BLACKHAT, element);
    	//显示图像
    	imshow("【顶帽/黑帽】",g_dstImage);
    }
    
    //-----------------------------------【ShowHelpText( )函数】----------------------------------
    //		描述:输出一些帮助信息
    //----------------------------------------------------------------------------------------------
    static void ShowHelpText()
    {
    //输出一些帮助信息
    	printf("\n\n\n\t请调整滚动条观察图像效果~\n\n");
    	printf( "\n\n\t按键操作说明: \n\n"
    		"\t\t键盘按键【ESC】或者【Q】- 退出程序\n"
    		"\t\t键盘按键【1】- 使用椭圆(Elliptic)结构元素\n"
    		"\t\t键盘按键【2】- 使用矩形(Rectangle )结构元素\n"
    		"\t\t键盘按键【3】- 使用十字型(Cross-shaped)结构元素\n"
    		"\t\t键盘按键【空格SPACE】- 在矩形、椭圆、十字形结构元素中循环\n"
    		"\n\n\t\t\t\t\t\t\t\t by浅墨"
    		);
    }

    放出一些效果图:

    首先是原图:


    非常帅气的Captain America有木有!

    腐蚀效果图:


    膨胀效果图:



    开运算效果图:



    闭运算效果图:



    顶帽运算效果图:


    黑帽运算效果图:



    好的,就放出这些效果图吧,具体更多的运行效果大家就自己下载示例程序回去玩~

     

    本篇文章的配套源代码请点击这里下载:


    【浅墨OpenCV入门教程之十一】配套源代码下载

     


    OK,今天的内容大概就是这些,我们下篇文章见:)




    展开全文
  • 形态学处理 一 膨胀 二 腐蚀 三 开运算 四 闭运算 五 形态学梯度 六 顶帽 七 黑帽 形态学处理 一 膨胀  代码: #include &lt;opencv2/core/core.hpp&gt; #include &lt;ope...

    形态学处理

    一 膨胀

     代码:

    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <iostream>
    
    //-----------------------------------【命名空间声明部分】---------------------------------------
    //  描述:包含程序所使用的命名空间
    //-----------------------------------------------------------------------------------------------  
    using namespace std;
    using namespace cv;
    
    //-----------------------------------【main( )函数】--------------------------------------------
    //  描述:控制台应用程序的入口函数,我们的程序从这里开始
    //-----------------------------------------------------------------------------------------------
    int main()
    {
    
        //载入原图  
        Mat image = imread("D:/srcPics/3.jpg");
    
        //创建窗口  
        namedWindow("【原图】膨胀操作");
        namedWindow("【效果图】膨胀操作");
    
        //显示原图
        imshow("【原图】膨胀操作", image);
    
        //进行膨胀操作 
        Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
        Mat out;
        dilate(image, out, element);
    
        //显示效果图 
        imshow("【效果图】膨胀操作", out);
    
        waitKey(0);
    
        return 0;

    运行结果:
    这里写图片描述
    这里写图片描述

    二 腐蚀

    代码:

    //-----------------------------------【头文件包含部分】---------------------------------------
    //  描述:包含程序所依赖的头文件
    //---------------------------------------------------------------------------------------------- 
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <iostream>
    
    //-----------------------------------【命名空间声明部分】---------------------------------------
    //  描述:包含程序所使用的命名空间
    //-----------------------------------------------------------------------------------------------  
    using namespace std;
    using namespace cv;
    
    //-----------------------------------【main( )函数】--------------------------------------------
    //  描述:控制台应用程序的入口函数,我们的程序从这里开始
    //-----------------------------------------------------------------------------------------------
    int main(   )
    {
    
        //载入原图  
        Mat image = imread("1.jpg");
    
        //创建窗口  
        namedWindow("【原图】膨胀操作");
        namedWindow("【效果图】膨胀操作");
    
        //显示原图
        imshow("【原图】膨胀操作", image);
    
        //进行膨胀操作 
        Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
        Mat out;
        dilate(image, out, element);
    
        //显示效果图 
        imshow("【效果图】膨胀操作", out);
    
        waitKey(0); 
    
        return 0;
    }

    这里写图片描述
    这里写图片描述

    三 开运算

      本节的主角是OpenCV中的morphologyEx函数,它利用基本的膨胀和腐蚀技术,来执行更加高级的形态学变换,如开闭运算、形态学梯度、“顶帽”、“黑帽”等。
       代码:

         #include <opencv2/opencv.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    using namespace cv;
    
    //-----------------------------------【main( )函数】--------------------------------------------
    //      描述:控制台应用程序的入口函数,我们的程序从这里开始
    //-----------------------------------------------------------------------------------------------
    int main( )
    {
        //载入原始图   
        Mat image = imread("1.jpg");  //工程目录下应该有一张名为1.jpg的素材图
        //创建窗口   
        namedWindow("【原始图】开运算");  
        namedWindow("【效果图】开运算");  
        //显示原始图  
        imshow("【原始图】开运算", image);  
        //定义核
        Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));  
        //进行形态学操作
        morphologyEx(image, image, MORPH_OPEN, element);
        //显示效果图  
        imshow("【效果图】开运算", image);  
    
        waitKey(0);  
    
        return 0;  
    }

    这里写图片描述
    这里写图片描述
      实质:
       开运算,其实就是先腐蚀后膨胀的过程。
      功能:
       开运算可以用来消除小物体,在纤细点处分离物体,并且在平滑较大物体的边界的同时不明显改变其面积。

    四 闭运算

      代码:

      #include <opencv2/opencv.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    using namespace cv;
    
    
    //-----------------------------------【main( )函数】------------------------------------------
    //      描述:控制台应用程序的入口函数,我们的程序从这里开始
    //-----------------------------------------------------------------------------------------------
    int main( )
    {
        //载入原始图   
        Mat image = imread("1.jpg");  //工程目录下应该有一张名为1.jpg的素材图
        //创建窗口   
        namedWindow("【原始图】闭运算");  
        namedWindow("【效果图】闭运算");  
        //显示原始图  
        imshow("【原始图】闭运算", image);  
        //定义核
        Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));  
        //进行形态学操作
        morphologyEx(image, image, MORPH_CLOSE, element);
        //显示效果图  
        imshow("【效果图】闭运算", image);  
    
        waitKey(0);  
    
        return 0;  
    }
    

      先膨胀后腐蚀的过程称为闭运算。
      功能:闭运算能够排除小型黑洞(黑色区域)。

    五 形态学梯度

    #include"opencv.hpp"
    #include"opencv2/opencv.hpp"
    using namespace cv;
    int main()
    {
        Mat image = imread("D:/srcPics/3.jpg");
        namedWindow("【原始图】");
        namedWindow("【效果图】");
        imshow("【原始图】", image);
        Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
        morphologyEx(image, image, MORPH_GRADIENT, element);
        imshow("【效果图】", image);
        waitKey(0);
        return 0;
    }

    这里写图片描述
    这里写图片描述
    形态学梯度是膨胀图与腐蚀图之差。

    六 顶帽

    #include <opencv2/opencv.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    using namespace cv;
    
    
    
    //-----------------------------------【main( )函数】------------------------------------------
    //      描述:控制台应用程序的入口函数,我们的程序从这里开始
    //-----------------------------------------------------------------------------------------------
    int main( )
    {
        //载入原始图   
        Mat image = imread("1.jpg");  //工程目录下应该有一张名为1.jpg的素材图
        //创建窗口   
        namedWindow("【原始图】顶帽运算");  
        namedWindow("【效果图】顶帽运算");  
        //显示原始图  
        imshow("【原始图】顶帽运算", image);  
        //定义核
        Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));  
        //进行形态学操作
        morphologyEx(image, image, MORPH_TOPHAT, element);
        //显示效果图  
        imshow("【效果图】顶帽运算", image);  
    
        waitKey(0);  
    
        return 0;  
    }

    这里写图片描述
    这里写图片描述
      顶帽运算(Top Hat)**又常常被译为“礼帽”运算,是原图像与上文刚刚介绍的“开运算”的结果图之差。
      作用:
    因为开运算带来的结果是放大了裂缝或者是局部低亮度的区域。因此,从原图中减去开运算后的图,得到的效果图突出了比原图轮廓周围的区域更加明亮的区域,且这已操作与选择的核大小相关。
    顶帽运算往往用来分离比临近点亮一些的斑块。在一幅图像具有大幅的背景,而微小物品比较有规律的情况下,可以使用顶帽运算进行背景提取。

    七 黑帽

    #include <opencv2/opencv.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    using namespace cv;
    
    
    //-----------------------------------【main( )函数】--------------------------------------------
    //      描述:控制台应用程序的入口函数,我们的程序从这里开始
    //-----------------------------------------------------------------------------------------------
    int main( )
    {
        //载入原始图   
        Mat image = imread("1.jpg");  //工程目录下应该有一张名为1.jpg的素材图
        //创建窗口   
        namedWindow("【原始图】黑帽运算");  
        namedWindow("【效果图】黑帽运算");  
        //显示原始图  
        imshow("【原始图】黑帽运算", image);  
        //定义核
        Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));  
        //进行形态学操作
        morphologyEx(image, image, MORPH_BLACKHAT, element);
        //显示效果图  
        imshow("【效果图】黑帽运算", image);  
    
        waitKey(0);  
    
        return 0;  
    }

    这里写图片描述
    这里写图片描述
      黑帽运算是闭运算的结果图与原图像之差。
    黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,且这一操作和选择的核的大小相关。
       所以,黑帽运算用来分离比邻近点暗一些的斑块,效果图有着非常完美的轮廓。

      注:
       这一章节的核心API函数:morphologyEx()
    这里写图片描述
    这里写图片描述
    这里写图片描述

    以上是我根据OpenCV3.0总结的形态学相关内容,方便以后自己调用。

       个人公众号:视觉IMAX

    这里写图片描述

    展开全文
  • 形态学操作

    千次阅读 2018-03-14 10:54:40
    形态学操作 主要针对二值图像进行处理图像形态学操作是 基于形状的一系列图像处理操作的合集,主要是基于集合论基础上的形态学数学。形态学有四个基本操作:膨胀、腐蚀、开、闭。膨胀与腐蚀是图像处理中最常用的...
  • OpenCV形态学操作

    2015-02-13 11:30:00
    数字图像处理中的形态学处理是指将数字形态学作为工具从图像中提取对于表达和描绘区域形状有用处的图像分量,比如边界、骨架以及凸壳,还包括用于预处理或后处理的形态学过滤、细化和修剪等。图像形态学处理中我们感...
  • 目的:观察实验性继发牙折裂的线及面形态学改变。方法:对没有裂纹牙冠完好的离体牙进行根管治疗和多类型的■面充填后,在万能力学试验机上对牙■面施以静态压力造成继发性牙折裂,分析裂纹的数量、形态和牙折面的...
  • 形态学图像处理

    千次阅读 2018-07-13 21:05:55
    原文链接:https://blog.csdn.net/whuhan2013/article/details/53956606形态学,即数学形态学(mathematical Morphology),是图像处理中应用最为广泛的技术之一,主要用于从图像中提取对表达和描绘区域形状有意义的...
  • OpenCV形态学操作——开运算、闭运算、形态学梯度、顶帽、黑帽一、学习目标二、各种操作简介三、综合实例 一、学习目标 理解什么是开运算、闭运算、形态学梯度、顶帽和黑帽 学会使用OpenCV实现上述的图像形态学操作...
  • OpenCV与EmguCV中的形态学滤波

    千次阅读 2016-06-28 14:41:32
    形态学(morphology)一词通常表示生物学的一个分支,该分支主要研究动植物的形态和结构。而我们图像处理中指的形态学,往往表示的是数学形态学。下面一起来了解数学形态学的概念。数学形态学是由一组形态学的代数运...
  • 图像的形态学处理

    千次阅读 2014-04-26 22:13:02
    数学形态运算中,最常见的基本运算有七种, 分别为:腐蚀、膨胀、开运算、闭运算、击中、细化和粗化, 它们是全部形态学的基础。腐蚀和膨胀,看上去好像是一对互逆的操作,实际上,这两种操作不具有互逆的关系。 开...
  • 形态学算子

    2019-07-22 15:56:13
    形态学算子的主要思想是用一定形状的结构元素SE(structureelement)在图像中抽取出相应的某些结构,通常可以用于图像的滤波、分割、分类等处理。形态学算子有腐蚀、膨胀、开和闭四种。 腐蚀 腐蚀是...
  • 形态学(morphology)一词通常表示生物学的一个分支,该分支主要研究动植物的形态和结构。而我们图像处理中指的形态学,往往表示的是数学形态学。下面一起来了解数学形态学的概念。 数学形态学(Mathematical ...
  • 主要形态学操作有 膨胀、腐蚀 、开运算,闭运算,形态学梯度,顶帽,黑帽。对其原理及opencv的实现进行总结。  参考博客及资料如下:图像处理--形态学...
  • 数字图像处理 - 形态学腐蚀

    千次阅读 2017-10-26 16:16:38
    一、理论与概念讲解——...而我们图像处理中指的形态学,往往表示的是数学形态学。下面一起来了解数学形态学的概念。 数学形态学(Mathematical morphology) 是一门建立在格论和拓扑学基础之上的图像分析学科,是数学
  • opencv图像形态学处理

    千次阅读 2016-06-04 20:17:13
    膨胀、腐蚀、开、闭运算是数学形态学最基本的变换,用得最多的主要是针对二值图像的形态学 膨胀:把二值图像各1像素连接成分的边界扩大一层(填充边缘或0像素内部的孔); 腐蚀:把二值图像各1像素连接成分的边界...
  • 为研究三七总皂苷(PNS)对急性心肌梗塞(AMI)后左室重构(LVRM)大鼠自由基损伤和心肌细胞形态学改变的作用,采用结扎大鼠左冠状动脉前降支的方法,建立AMI模型,术后24 h后随机分为对照组和实验组,连续4周分别灌胃给予生理...
  • 机器视觉学习之-二值形态学

    千次阅读 2018-06-04 15:02:59
    今天小石在这里讲解下我们在机器视觉当中常用的形态学处理运算! 常用的有四个基本运算,分别是膨胀和腐蚀、开运算和闭运算、两两配对。 1、了解前提 在了解形态学处理之前,我们需要知道形态学处理,是针对...
  • 基于OpenCV的图像形态学处理

    千次阅读 2018-11-21 12:17:50
    1、形态学概述 一词通常表示生物学的个分支,该主要研究动植形态 和结构 。 而我们图像处理中的形态学,往指是数。 而我们图像处理中的形态学,往指是数学形态学。 最基本的形态学操作有两种:膨胀和腐蚀 膨胀:...
  • 图像形态学

    千次阅读 2011-08-12 16:28:20
    形态学:一般指生物学中研究动物和植物结构的一个分支 数学形态学(也称图像代数)表示以形态为基础对图像进行分析的数学工具  数学形态学以图像的形态特征为研究对象,描述图像的基本特征和基本结构,也就是...
  • 在图像处理技术中,有一些的操作会对图像的形态发生改变,这些操作一般称之为形态学操作(phology)。数学形态学是基于集合论的图像处理方法,最早出现在生物学的形态与结构中,图像处理中的形态学操作用于图像与...
  • Matlab数学形态学运算

    千次阅读 2019-07-05 21:25:41
    数学形态学运算 语法格式:  BW2 = bwmorph(BW,operation)  对二值图像进行指定的形态学处理。  BW2 = bwmorph(BW,operation,n)  对二值图像进行n次指定的形态学处理。 n可以是Inf(无穷大),这意味着将...
  • 形态学处理方法总结

    千次阅读 2013-08-22 13:41:19
    一:基本形态学处理算法  简单来讲,形态学操作就是基于形状的一系列图像处理操作。通过将 结构元素 作用于输入图像来产生输出图像。 最基本的形态学操作有二:腐蚀与膨胀(Erosion 与 Dilation)。 他们的运用...
  • 形态学滤波

    千次阅读 2017-04-20 14:01:38
    基本形态学滤波:膨胀,腐蚀 膨胀腐蚀功能:消除噪声,分割出独立的图像元素,在图像中连接相邻的元素,寻找图像中的明显的极大值区域或极小值区域,求出图像的梯度。 膨胀是向着高亮部分进行膨胀,腐蚀亮度腐蚀,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 34,853
精华内容 13,941
关键字:

形态学的改变