目录

形态学通用API:morphologyEx

一、基础理论

1、邻接关系

(1)四邻接:

(2)D邻接:

(3) 八邻接:

2、连通性

(1)四连通:

(2)八连通:

(3)m连通:

3、形态学基础

二、结构元

三、膨胀

1、基础理论

作用:

原理:

2、膨胀函数dilate()

3、代码

4、效果

四、腐蚀

1、原理

作用:

原理:

2、腐蚀函数erode()

3、代码、

4、效果

四、简便操作---回调函数与滑动条

1、回调函数

2、滑动条创建

3、代码

4、效果

参考资料


形态学通用API:morphologyEx

morphologyEx(Mat src, Mat dst, int op, Mat kernel, Point anchor, int iterations, int borderType, Scalar borderValue)

参数介绍:

第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。图像位深应该为以下五种之一:CV_8U, CV_16U,CV_16S, CV_32F 或CV_64F。
第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。
第三个参数,int类型的op,表示形态学运算的类型,可以是如下之一的标识符:

enum MorphTypes{MORPH_ERODE    = 0, //腐蚀MORPH_DILATE   = 1, //膨胀MORPH_OPEN     = 2, //开操作MORPH_CLOSE    = 3, //闭操作MORPH_GRADIENT = 4, //梯度操作MORPH_TOPHAT   = 5, //顶帽操作MORPH_BLACKHAT = 6, //黑帽操作MORPH_HITMISS  = 7
};

第四个参数,InputArray类型的kernel,形态学运算的内核。

一、基础理论

1、邻接关系

在图像中,最小的单位是像素每个像素周围有8个邻接像素,常见的邻接关系有3种:4邻接D邻接8邻接

(1)四邻接:

上下左右的点  

(2)D邻接:

对角线的点

(3) 八邻接:

四周的点

2、连通性

(1)四连通:

两点在4邻域范围内。

(2)八连通:

两点在8邻域范围内,

(3)m连通:

p/q在彼此的D邻域内(4邻域交集为空)

3、形态学基础

形态学是基于图像形状的一些操作,通常在二进制图像上进行。(腐蚀膨胀是两个基本的形态学运算符, 它的变体形式如开运算闭运算礼帽黑帽等等)

腐蚀和膨胀:

膨胀︰求局部最大值(消除内部噪声)
腐蚀:求局部最小值(使内部噪声变大)

开闭运算:
开∶先腐蚀后膨胀(消除噪声)

闭:先膨胀后腐蚀(填充孔洞)

礼帽和黑帽:
礼帽:原图像与开运算之差(找到亮区域)

黑帽:闭运算与原图像之差(找到暗区域)

二、结构元

getStructuringElement()函数会返回指定形状和尺寸的结构元素。

Mat getStructuringElement(int shape, Size esize, Point anchor = Point(-1, -1));

参数介绍:

参数1:(卷积核形状)

矩形:MORPH_RECT;

交叉形:MORPH_CROSS;

椭圆形:MORPH_ELLIPSE;

参数2:内核的尺寸宽,高)(必须为奇数

参数3:锚点位置(默认值Point(-1,-1)表示锚点位于中心点)

实例:

C++;

//卷积核(结构元)Mat structureElement = getStructuringElement(MORPH_RECT, Size(11, 11) , Point(-1,-1));//                返回指定形状和尺寸的结构元素     形状      尺寸(宽, 高)   锚点(中心点)

三、膨胀

1、基础理论

作用

将与物体接触的所有背景点融入物体中,使目标增大,可填补目标中的空洞

原理:

取结构元领域内最大值,所以膨胀后输出图像的总体亮度的平均值比起原图会有所升高扩张高亮区域,而较物体的尺寸会减小甚至消失暗的地方被覆盖)。(红色是参考点/锚点)(类似于“”操作,附近都为0,锚点才为0,否则为1)

2、膨胀函数dilate()

c++:

//膨胀函数
dilate(img, dst, structureElement, Point(-1, -1), 1);
//     原图  新图 卷积核(结构元)     锚点            膨胀操作次数(默认1次)

python:

dilate = cv2.dilate(img, kernel=(7, 7), iterations=1)#                        卷积核大小      迭代次数

3、代码

C++:

//膨胀
void Dilate()
{//卷积核(结构元)Mat structureElement = getStructuringElement(MORPH_RECT, Size(11, 11) , Point(-1,-1));//                       返回指定形状和尺寸的结构元素     形状                   尺寸(宽, 高)     锚点(中心点)//膨胀函数dilate(img, dst, structureElement, Point(-1, -1), 1);//         原图  新图 卷积核(结构元)          锚点               膨胀操作次数(默认1次)
}

python:

# 膨胀
def Dilate():# 膨胀dilate = cv2.dilate(img, kernel=(7, 7), iterations=1)#                        卷积核大小      迭代次数cv2.imshow("dilate", dilate)

4、效果

四、腐蚀

1、原理

作用

可以用于去除噪声

原理:

腐蚀操作与膨胀操作类似,只是它取结构元所指定的领域内值的最小值作为该位置的输出灰度值。因为取每个位置领域内最小值,所以腐蚀后输出图像的总体亮度的平均值比起原图会有所降低,图像中比较亮的区域的面积会变小甚至消失亮的地方被覆盖),而较暗区域的尺寸会扩大。(蚕食高亮区域

(类似于“”操作,附近只要有1个为0,锚点就位0)

2、腐蚀函数erode()

//腐蚀函数erode(img, dst, structureElement, Point(-1, -1), 1);//   原图  新图  卷积核(结构元)    锚点            腐蚀操作次数(默认1次)
erode = cv2.erode(img, kernel=(7, 7), iterations=5)#                        卷积核大小      迭代次数

3、代码、

C++:

//腐蚀
void Erode()
{//卷积核(结构元)Mat structureElement = getStructuringElement(MORPH_RECT, Size(11, 11), Point(-1, -1));//                       返回指定形状和尺寸的结构元素     形状                   尺寸(宽, 高)     锚点(中心点)//腐蚀函数erode(img, dst, structureElement, Point(-1, -1), 1);//      原图  新图 卷积核(结构元)          锚点               腐蚀操作次数(默认1次)
}

python:

# 腐蚀
def Enrode():# 腐蚀erode = cv2.erode(img, kernel=(7, 7), iterations=5)#                        卷积核大小      迭代次数cv2.imshow("erode", erode)

4、效果

四、简便操作---回调函数与滑动条

1、回调函数

回调函数:把函数指针作为参数

//回调函数膨胀
void CallBack_Dilate(int,           void*)
//                  轨迹条位置       用户数据
{cont = element_size * 2 + 1; //结构元尺寸控制Dilate();                                  //膨胀imshow("Dilate:", dst);                //显示
}//回调函数腐蚀
void CallBack_Erode(int,         void*)
//                  轨迹条位置   用户数据
{cont = element_size * 2 + 1; //结构元尺寸控制Erode();                                   //腐蚀imshow("Erode:", dst);             //显示
}

2、滑动条创建

createTrackbar(conststring& trackbarname, conststring& winname, int* value, int count, TrackbarCallback onChange=0,void* userdata=0); 

参数解释:

1、trackbarname,表示轨迹条的名字,用来代表我们创建的轨迹条。
2、winname,填窗口的名字,表示这个轨迹条会依附到哪个窗口上,即对应namedWindow()创建窗口时填的某一个窗口名。(窗口名需与显示窗口一致
3、value,一个指向整型的指针,表示滑块的位置。并且在创建时,滑块的初始位置就是该变量当前的值。
4、count,表示滑块可以达到的最大位置的值。滑块最小的位置的值始终为0。
5、onChange,首先注意他有默认值0。这是一个指向回调函数的指针每次滑块位置改变时,这个函数都会进行回调。并且这个函数的原型必须为void XXXX(int,void*);其中第一个参数是轨迹条的位置第二个参数是用户数据(看下面的参数)。如果回调是NULL指针,表示没有回调函数的调用,仅第三个参数value有变化。
6、userdata,他也有默认值0。这个参数是用户传给回调函数的数据,用来处理轨迹条事件。如果使用的第三个参数value实参是全局变量的话,完全可以不去管这个userdata参数。

//创建滑动条1(膨胀)
createTrackbar("结构元尺寸", "Dilate:",   &element_size, max_size, CallBack_Dilate);
//创建滑动条2(腐蚀)
createTrackbar("结构元尺寸", "Erode:",                 &element_size, max_size, CallBack_Erode);
//              滑动条名字    窗口名字(必须和原窗口一致)   当前数值       最大数值    回调函数(函数指针作为参数)
//每次滑块位置改变,回调函数都会回调

3、代码

C++:

//膨胀与腐蚀(回调函数)
#include <iostream>
#include <opencv2/opencv.hpp>using namespace cv;
using namespace std;Mat img, dst;
int element_size = 3;      //结构元大小(2*ele +1)
int max_size = 21;         //最大容量
int cont;                           //控制结构元大小//图像初始化
void Image_Init()
{img = imread("Resource/test4.jpg");dst = Mat::zeros(img.size(), img.type());if (img.empty()){printf("图像加载失败");exit(0);}
}//显示图像
void Show()
{imshow("原图", img);
}//膨胀
void Dilate()
{//卷积核(结构元)Mat structureElement = getStructuringElement(MORPH_RECT, Size(cont, cont), Point(-1, -1));//                       返回指定形状和尺寸的结构元素     形状                   尺寸(宽, 高)     锚点(中心点)//膨胀函数dilate(img, dst, structureElement, Point(-1, -1), 1);//         原图  新图 卷积核(结构元)          锚点               膨胀操作次数(默认1次)
}//腐蚀
void Erode()
{//卷积核(结构元)Mat structureElement = getStructuringElement(MORPH_RECT, Size(cont, cont), Point(-1, -1));//                       返回指定形状和尺寸的结构元素     形状                   尺寸(宽, 高)     锚点(中心点)//腐蚀函数erode(img, dst, structureElement, Point(-1, -1), 1);//      原图  新图 卷积核(结构元)          锚点               腐蚀操作次数(默认1次)
}//回调函数膨胀
void CallBack_Dilate(int,               void*)
//                            轨迹条位置 用户数据
{cont = element_size * 2 + 1; //结构元尺寸控制Dilate();                                  //膨胀imshow("Dilate:", dst);                //显示
}//回调函数腐蚀
void CallBack_Erode(int, void*)
//                            轨迹条位置 用户数据
{cont = element_size * 2 + 1; //结构元尺寸控制Erode();                                   //腐蚀imshow("Erode:", dst);             //显示
}int main()
{Image_Init();                              //图像初始化//Dilate();                                  //膨胀//Erode();                                  //腐蚀//回调函数(简便控制膨胀与腐蚀)CallBack_Dilate(element_size, 0);        //先显示图片(膨胀回调函数)CallBack_Erode(element_size, 0);       //先显示图片(腐蚀回调函数)//                   轨迹条位置     用户数据//创建滑动条1(膨胀)createTrackbar("结构元尺寸", "Dilate:",                         &element_size, max_size, CallBack_Dilate);//创建滑动条2(腐蚀)createTrackbar("结构元尺寸", "Erode:", &element_size, max_size, CallBack_Erode);//                        滑动条名字    窗口名字(必须和原窗口一致)  当前数值            最大数值     回调函数(函数指针作为参数)//每次滑块位置改变,回调函数都会回调Show();                                     //显示原图像waitKey(0);return 0;
}

python:

# 形态学(膨胀、腐蚀、开闭运算、顶帽与底帽)
import cv2# 膨胀
def Dilate():# 膨胀dilate = cv2.dilate(img, kernel=(7, 7), iterations=1)#                        卷积核大小      迭代次数cv2.imshow("dilate", dilate)# 腐蚀
def Enrode():# 腐蚀erode = cv2.erode(img, kernel=(7, 7), iterations=5)#                        卷积核大小      迭代次数cv2.imshow("erode", erode)# 开运算(先腐后膨)
def Open():open = cv2.morphologyEx(img, cv2.MORPH_OPEN, (7, 7), iterations=5)#                            类型             卷积核大小    迭代次数cv2.imshow('open', open)# 闭运算(先膨后腐)
def Close():close = cv2.morphologyEx(img, cv2.MORPH_CLOSE, (7, 7), iterations=5)#                            类型             卷积核大小    迭代次数cv2.imshow('close', close)# 顶帽(原-开)
def TopHat():tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, (7, 7), iterations=5)
#                                   类型              卷积核   迭代次数cv2.imshow('TopHat', tophat)# 底帽(原-闭)
def BlackHat():blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT,  (7, 7), iterations=5)
#                                    类型                  卷积核   迭代次数cv2.imshow('BlackHat', blackhat)if __name__ == '__main__':# 读取图片img = cv2.imread("Resource/test5.jpg")cv2.imshow("img", img)Dilate()        #膨胀Enrode()        #腐蚀Open()          #开运算Close()         #闭运算TopHat()        #顶帽运算BlackHat()      #底帽运算cv2.waitKey(0)

4、效果

参考资料

https://blog.csdn.net/weixin_41695564/article/details/79928835

https://www.bilibili.com/video/BV1uy4y1p7BR?from=search&seid=4644291277982613292

OpenCV(六)形态学操作1--基础:膨胀与腐蚀(回调函数)相关推荐

  1. opencv进阶学习笔记13:图像形态学操作大全(膨胀,腐蚀,开闭,黑帽,顶帽,梯度)python版

    基础版学习笔记: python3+opencv学习笔记汇总目录(适合基础入门学习) 进阶版笔记目录链接: python+opencv进阶版学习笔记目录(适合有一定基础) 基础版形态学: opencv学 ...

  2. pythonopencv图像形态_python+opencv图像形态学处理详细解释(膨胀、腐蚀、开闭运算、礼帽和黑猫)...

    python+opencv图像形态学处理 本篇博客主要是关于形态学中的腐蚀.膨胀.开运算.闭运算.礼帽和黑帽的函数用法. 内容会比较,为方便查阅.代码的解释会写在代码中. 用于测试的图像原图: 一.腐 ...

  3. opencv —— morphology形态学操作函数讲解(python)

    opencv -- morphology形态学操作函数讲解 目录 opencv -- morphology形态学操作函数讲解 形态学滤波:morphologyEx 函数 开运算:先腐蚀后膨胀. 闭运算 ...

  4. 使用Python,OpenCV进行形态学操作

    使用Python,OpenCV进行形态学操作) 1. 效果图 2. 原理 3. 源码 3.1 [制作logo源码](https://blog.csdn.net/qq_40985985/article/ ...

  5. OpenCV通过形态学操作提取水平线和垂直线

    OpenCV通过形态学操作提取水平线和垂直线 通过形态学操作提取水平线和垂直线 目标 理论 形态学运算 结构元素 代码 说明/结果 载入图片 灰阶 灰度到二进制图像 输出图像 结构要素 优化边缘/结果 ...

  6. opencv 的形态学操作,cv2.erode,cv.dilate等。

    opencv 的形态学操作,cv2.erode,cv.dilate,cv2.morphologyEx的使用. 一.膨胀 cv2.erode(img, kernel_size) 函数参数, img是输入 ...

  7. 用openCV实现形态学操作

    尊师: © Fu Xianjun. All Rights Reserved. 老样子先进行把图片放入文件夹如何用openCV打开 形态学操作(移除噪声) 先使用开运算去除图像中的细小白色噪点,然后通过 ...

  8. OPenCv java 形态学操作(12)

    创建图片 Mat mat=new Mat();mat.create(new Size(516,516),CvType.CV_8UC3);Imgproc.putText(mat, "hello ...

  9. opencv学习-形态学操作应用-提取图片中的文字

    提取图片中的文字 一.步骤 1.读取原图 2.灰度化 3.二值化 4.膨胀 5.腐蚀 6.像素值取反 二.全部代码 #include<iostream> #include<openc ...

  10. 基于OpenCV [c++]——形态学操作(分析和应用)

    摘要: 形态学一般指生物学中研究动物和植物结构的一个分支.用数学形态学(也称图像代数)表示以形态为基础对图像进行分析的数学工具. 基本思想是用具有一定形态的结构元素去度量和提取图像中的对应形状以达到对 ...

最新文章

  1. AngularJS学习笔记之一: AngularJS入门
  2. 记录一下CUDA-opencv联合编程
  3. VC#版DirectX开发入门详解
  4. linux常用命令:系统目录说明及命令ls,cp,touch,history,gparted分区
  5. java编程赋值运算符_(24)赋值运算符
  6. python判断质数用for循环_Day3.Python判断与循环语句
  7. python常见编程面试题_python面试题基础部分 80题
  8. java WebService 异常
  9. 【wpf】在win10系统上弹出toast和notification
  10. python学习笔记之列表(list)
  11. ACL 2020投稿破 3 千,到底有多少人在做 NLP 研究?
  12. Mybatis_3.基于注解的增删改查
  13. 【docker】3-配置阿里云加速
  14. 【数据结构初阶-oj】入门二叉树的入门oj
  15. 特斯拉又发生车祸!电池夜间还自燃3次
  16. 阶段巨献 - centos+php-fpm+mariaDB+svn+nodejs+redis(开机启动及配置远程连接),配置linux的php和nodejs网站运行环境。
  17. 行走的励志君——选择和努力哪个更重要
  18. iOS 12 - iOS 15,如何在iPhone上设置“早上好”功能
  19. NORDIC52832 TWI(I2C) 特点 (2)驱动CHT8305C 温湿度传感器
  20. daemon(守护进程)

热门文章

  1. Android Textview 实现版权符号© 的 实现
  2. Android 10 新增的功能
  3. 算法之递归(3)- 链表操作
  4. ASP.NET中 RequiredFieldValidator(非空验证)的使用
  5. 【转】C/C++中的日期和时间
  6. 跟踪workflow instance 状态
  7. 《OpenCV3编程入门》学习笔记10 角点检测(一)Harris角点检测
  8. php 解决方案,php优化解决方案
  9. mysql数据库比对视频教程_MySQL数据库全学习实战视频教程(27讲 )
  10. c语言 如何读多种数据类型 非类,c语言程序设计教学大纲(非电气类)文档.doc