OPENCV形态学操作1
形态学操作是指基于形状的一系列图像处理操作,包括膨胀,腐蚀,二值化,开运算,闭运算,顶帽算法,黑帽算法,形态学梯度等,最基本的形态学操作就是膨胀和腐蚀.
一.膨胀
首先需要明确一个概念,膨胀和腐蚀都是针对于图像中较亮的区域而言的,膨胀就是亮的区域变多了,而腐蚀就是暗的区域变多了.
膨胀的功能主要有消除噪声,分割出独立的图像元素,在图像操作的时候,有时候需要对图像中的某些形状进行检测,而这些形状相互连接在一起,不好分开检测,膨胀就能切开这些形状(很小的连接位置),或者图像中有很小块的黑斑,或许是相机上的影响,膨胀,也能消除这些小的黑斑
膨胀的基本思路就是图像与一个核函数进行卷积,并取出结果中的极大值作为结果,使得图像中的高亮区域增长.这个核的形状,锚点都可以进行设置,OPENCV提供了API供我们获得核.
API:Mat getStructuringElement(int 内核形状,Size 内核尺寸,Point 锚点位置)
注:内核形状可以取方形MORPH_RECT,十字形MORPH_CROSS,椭圆形MORPH_ELLIPSE
锚点位置默认值Point(-1,-1),取形状的中心
通过该API就可以获得相应的计算核,接下来计算膨胀的函数为
API:void dilate(源图像,目标图像,膨胀核,锚点,int 迭代次数,int边界模式,int 边界为常数时边界值)
注:该API支持in_place(源图像可以做目的图像参数,算法会修改源图像内数据),迭代次数默认为1
例子如下
- Mat srcImage;
- //膨胀
- const int g_dilateIterMax = 100;//迭代次数
- int g_nDilateIterValue;
- const int g_dilateCoreMax = 100;//核大小
- int g_nDilateCoreValue;
- Mat dilateImage;
- void OnDilateIterTrackbar(int pos,void* userData);
- void onDilateCoreSizeTrackBar(int pos,void* userData);
- int main(int argc,char* argv)
- {
- srcImage = imread("F:\\opencv\\OpenCVImage\\erode_dilate.jpg");
- namedWindow("src image");
- namedWindow("dilate image");
- g_nDilateIterValue = 1;
- g_nDilateCoreValue = 5;
- createTrackbar("inter count", "dilate image", &g_nDilateIterValue, g_dilateIterMax,OnDilateIterTrackbar);
- createTrackbar("core size", "dilate image", &g_nDilateCoreValue, g_dilateCoreMax,onDilateCoreSizeTrackBar);
- OnDilateIterTrackbar(g_nDilateIterValue,0);
- moveWindow("src image", 0, 0);
- moveWindow("dilate image", srcImage.cols, 0);
- imshow("src image", srcImage);
- waitKey(0);
- return 0;
- }
- //调整迭代次数
- void OnDilateIterTrackbar(int pos,void* userData)
- {
- if(pos == 0||g_nDilateCoreValue == 0)
- {
- imshow("dilate image", srcImage);
- }
- else
- {
- if(g_nDilateCoreValue%2 == 0)
- {
- g_nDilateCoreValue++;
- }
- Mat core = getStructuringElement(MORPH_RECT, Size(g_nDilateCoreValue,g_nDilateCoreValue));
- dilate(srcImage, dilateImage, core,Point(-1,-1),g_nDilateIterValue);
- imshow("dilate image", dilateImage);
- }
- }
- //调整核大小
- void onDilateCoreSizeTrackBar(int pos,void* userData)
- {
- if(pos == 0 || g_nDilateIterValue == 0)
- {
- imshow("dilate image", srcImage);
- }
- else
- {
- if(g_nDilateCoreValue%2 == 0)
- {
- g_nDilateCoreValue++;
- }
- Mat core = getStructuringElement(MORPH_RECT, Size(g_nDilateCoreValue,g_nDilateCoreValue));
- dilate(srcImage, dilateImage, core,Point(-1,-1),g_nDilateIterValue);
- imshow("dilate image", dilateImage);
- }
- }
二.腐蚀
腐蚀与膨胀正好相反,是求局部最小值的操作,亮的地方会减少,黑的地方会增多,在图像中连接接近的区域,消除高亮造成的噪声
API: void erode(源,目的,核,锚点,迭代次数,边缘类型,边缘为常数时边界值);
注:腐蚀和膨胀API的形式一致
使用代码
- //腐蚀
- Mat srcImage;
- const int g_erodeIterMax = 100;
- int g_nErodeIterValue;
- const int g_erodeCoreMax = 100;
- int g_nErodeCoreValue;
- Mat erodeImage;
- void OnErodeIterTrackbar(int pos,void* userData);
- void onErodeCoreSizeTrackBar(int pos,void* userData);
- int main(int argc,char* argv)
- {
- srcImage = imread("F:\\opencv\\OpenCVImage\\erode_dilate.jpg");
- namedWindow("src image");
- namedWindow("erode image");
- g_nErodeIterValue = 1;
- g_nErodeCoreValue = 5;
- createTrackbar("inter count", "erode image", &g_nErodeIterValue, g_erodeIterMax,OnErodeIterTrackbar);
- createTrackbar("core size", "erode image", &g_nErodeCoreValue, g_erodeCoreMax,onErodeCoreSizeTrackBar);
- OnErodeIterTrackbar(g_nErodeIterValue, 0);
- moveWindow("src image", 0, 0);
- moveWindow("erode image", srcImage.cols, 0);
- imshow("src image", srcImage);
- waitKey(0);
- return 0;
- }
- //调整迭代次数
- void OnErodeIterTrackbar(int pos,void* userData)
- {
- if(pos == 0 || g_nErodeCoreValue == 0)
- {
- imshow("erode image", srcImage);
- }
- else
- {
- if(g_nErodeCoreValue%2 == 0)
- {
- g_nErodeCoreValue++;
- }
- Mat core = getStructuringElement(MORPH_RECT, Size(g_nErodeCoreValue,g_nErodeCoreValue),Point(-1,-1));
- erode(srcImage, erodeImage, core,Point(-1,-1),g_nErodeIterValue);
- imshow("erode image", erodeImage);
- }
- }
- //调整核大小
- void onErodeCoreSizeTrackBar(int pos,void* userData)
- {
- if(pos == 0 || g_nErodeIterValue == 0)
- {
- imshow("erode image", srcImage);
- }
- else
- {
- if(g_nErodeCoreValue%2 == 0)
- {
- g_nErodeCoreValue++;
- }
- Mat core = getStructuringElement(MORPH_RECT, Size(g_nErodeCoreValue,g_nErodeCoreValue),Point(-1,-1));
- erode(srcImage, erodeImage, core,Point(-1,-1),g_nErodeIterValue);
- imshow("erode image", erodeImage);
- }
- }
三.形态学滤波算法
形态学的高级操作,往往都建立在基础的膨胀和腐蚀的操作之上
1.开运算:开运算是一个先腐蚀,后膨胀的过程,用于在图像中消除小的物体,在纤细点处分离物体,在平滑化较大的物体的边界的同时不明显改变物体的体积.
2.闭运算:先膨胀后腐蚀的过程,能够用于消除物体中的小型黑洞
3.形态学梯度:膨胀图和腐蚀图之差,对二值图像进行这一操作,可以将团块的边缘突出来,可以使用形态学梯度来保留物体的边缘轮廓.
4.顶帽:源图像和开运算的结果的差值,往往用来分离比邻近点亮一点的斑块,在一幅图具体大幅的背景,而微小物体有比较有规律的情况下,可以使用top_hat运算进行背景的提取
5.黑帽:闭运算的结果与源图像之差,突出了比源图像轮廓周围更暗的区域,往往用于分离比邻近点暗一些的斑块.
核心API:void morpholgyEx(源,目标,int 形态学操作标志,mat 形态学操作内核,Point 锚点,int 迭代次数,int 边界模式,int 边界为常数时的边界值).
注:形态学操作标志的取值如下:MORPH_OPEN开运算 MORPH_CLOSE 闭运算 MORPH_GRENIENT 形态学梯度 MORPH_TOPHAT顶帽 MORPH_BLACKHAT黑帽 MORPH_ERODE腐蚀 MORPH_DILATE 膨胀
形态学操作内核就是前面膨胀腐蚀使用的内核.
使用范例如下:
1.开运算 闭运算 形态学梯度三者联合
- //源¡ä图ª?像?
- Mat srcImage;
- //开a运?算?
- const int g_openIterMax = 100;
- int g_nopenIterValue;
- const int g_openCoreMax = 100;
- int g_nopenCoreValue;
- Mat openImage;
- void OnopenIterTrackbar(int pos,void* userData);
- void onopenCoreSizeTrackBar(int pos,void* userData);
- //闭À?运?算?
- const int g_closeIterMax = 100;
- int g_ncloseIterValue;
- const int g_closeCoreMax = 100;
- int g_ncloseCoreValue;
- Mat closeImage;
- void OncloseIterTrackbar(int pos,void* userData);
- void oncloseCoreSizeTrackBar(int pos,void* userData);
- //形?态¬?学¡ì梯¬Y度¨¨
- const int g_gredientIterMax = 100;
- int g_ngredientIterValue;
- const int g_gredientCoreMax = 100;
- int g_ngredientCoreValue;
- Mat gredientImage;
- void OngredientIterTrackbar(int pos,void* userData);
- void ongredientCoreSizeTrackBar(int pos,void* userData);
- int main(int argc,char* argv[])
- {
- srcImage = imread("F:\\opencv\\OpenCVImage\\morpholgy.jpg");
- g_nopenIterValue = 1;
- g_nopenCoreValue = 5;
- namedWindow("open image");
- createTrackbar("iter count", "open image", &g_nopenIterValue, g_openIterMax,OnopenIterTrackbar,0);
- createTrackbar("core size", "open image", &g_nopenCoreValue, g_openCoreMax,onopenCoreSizeTrackBar,0);
- onopenCoreSizeTrackBar(g_nopenCoreValue, 0);
- g_ncloseCoreValue = 5;
- g_ncloseIterValue = 1;
- namedWindow("close image");
- createTrackbar("iter count", "close image", &g_ncloseIterValue, g_closeIterMax,OncloseIterTrackbar,0);
- createTrackbar("core size", "close image", &g_ncloseCoreValue, g_closeCoreMax,oncloseCoreSizeTrackBar,0);
- oncloseCoreSizeTrackBar(g_ncloseCoreValue, 0);
- g_ngredientCoreValue = 5;
- g_ngredientIterValue = 1;
- namedWindow("gredient image");
- createTrackbar("iter count", "gredient image", &g_ngredientIterValue, g_gredientIterMax,OngredientIterTrackbar,0);
- createTrackbar("core size", "gredient image", &g_ngredientCoreValue, g_gredientCoreMax,OngredientIterTrackbar,0);
- OngredientIterTrackbar(g_ngredientIterValue, 0);
- imshow("src image", srcImage);
- moveWindow("src image", 0, 0);
- moveWindow("open image", srcImage.cols, 0);
- moveWindow("close image", srcImage.cols*2, 0);
- moveWindow("gredient image", srcImage.cols*3, 0);
- waitKey(0);
- return 0;
- }
- void OnopenIterTrackbar(int pos,void* userData)
- {
- if(g_nopenCoreValue == 0||g_nopenIterValue == 0)
- {
- imshow("open image", srcImage);
- }
- else
- {
- if(g_nopenCoreValue%2 == 0)
- g_nopenCoreValue++;
- Mat core = getStructuringElement(MORPH_RECT, Size(g_nopenCoreValue,g_nopenCoreValue));
- morphologyEx(srcImage, openImage, MORPH_OPEN, core,Point(-1,-1),g_nopenIterValue);
- imshow("open image", openImage);
- }
- }
- void onopenCoreSizeTrackBar(int pos,void* userData)
- {
- if(g_nopenCoreValue == 0||g_nopenIterValue == 0)
- {
- imshow("open image", srcImage);
- }
- else
- {
- if(g_nopenCoreValue%2 == 0)
- g_nopenCoreValue++;
- Mat core = getStructuringElement(MORPH_RECT, Size(g_nopenCoreValue,g_nopenCoreValue));
- morphologyEx(srcImage, openImage, MORPH_OPEN, core,Point(-1,-1),g_nopenIterValue);
- imshow("open image", openImage);
- }
- }
- void OncloseIterTrackbar(int pos,void* userData)
- {
- if(g_ncloseCoreValue == 0||g_ncloseIterValue == 0)
- {
- imshow("close image", srcImage);
- }
- else
- {
- if(g_ncloseCoreValue%2 == 0)
- g_ncloseCoreValue++;
- Mat core = getStructuringElement(MORPH_RECT, Size(g_ncloseCoreValue,g_ncloseCoreValue));
- morphologyEx(srcImage, closeImage, MORPH_CLOSE, core,Point(-1,-1),g_ncloseIterValue);
- imshow("close image", closeImage);
- }
- }
- void oncloseCoreSizeTrackBar(int pos,void* userData)
- {
- if(g_ncloseCoreValue == 0||g_ncloseIterValue == 0)
- {
- imshow("close image", srcImage);
- }
- else
- {
- if(g_ncloseCoreValue%2 == 0)
- g_ncloseCoreValue++;
- Mat core = getStructuringElement(MORPH_RECT, Size(g_ncloseCoreValue,g_ncloseCoreValue));
- morphologyEx(srcImage, closeImage, MORPH_CLOSE, core,Point(-1,-1),g_ncloseIterValue);
- imshow("close image", closeImage);
- }
- }
- void OngredientIterTrackbar(int pos,void* userData)
- {
- if(g_ngredientCoreValue == 0||g_ngredientIterValue == 0)
- {
- imshow("gredient image", srcImage);
- }
- else
- {
- if(g_ngredientCoreValue%2 == 0)
- g_ngredientCoreValue++;
- Mat core = getStructuringElement(MORPH_RECT, Size(g_ngredientCoreValue,g_ngredientCoreValue));
- morphologyEx(srcImage, gredientImage, MORPH_GRADIENT, core,Point(-1,-1),g_ngredientIterValue);
- imshow("gredient image", gredientImage);
- }
- }
- void ongredientCoreSizeTrackBar(int pos,void* userData)
- {
- if(g_ngredientCoreValue == 0||g_ngredientIterValue == 0)
- {
- imshow("gredient image", srcImage);
- }
- else
- {
- if(g_ngredientCoreValue%2 == 0)
- g_ngredientCoreValue++;
- Mat core = getStructuringElement(MORPH_RECT, Size(g_ngredientCoreValue,g_ngredientCoreValue));
- morphologyEx(srcImage, gredientImage, MORPH_GRADIENT, core,Point(-1,-1),g_ngredientIterValue);
- imshow("gredient image", gredientImage);
- }
- }
2. 顶帽 黑帽结合
- Mat srcImage;
- //顶£¤帽¡À tophat
- const int g_tophatIterMax = 100;
- int g_ntophatIterValue;
- const int g_tophatCoreMax = 100;
- int g_ntophatCoreValue;
- Mat tophatImage;
- void OntophatIterTrackbar(int pos,void* userData);
- void ontophatCoreSizeTrackBar(int pos,void* userData);
- //黑¨²帽¡À
- const int g_blackhatIterMax = 100;
- int g_nblackhatIterValue;
- const int g_blackhatCoreMax = 100;
- int g_nblackhatCoreValue;
- Mat blackhatImage;
- void OnblackhatIterTrackbar(int pos,void* userData);
- void onblackhatCoreSizeTrackBar(int pos,void* userData);
- int main(int argc,char* argv[])
- {
- srcImage = imread("F:\\opencv\\OpenCVImage\\morpholgy.jpg");
- g_ntophatIterValue = 1;
- g_ntophatCoreValue = 5;
- namedWindow("tophat image");
- createTrackbar("iter count", "tophat image", &g_ntophatIterValue, g_tophatIterMax,OntophatIterTrackbar,0);
- createTrackbar("core size", "tophat image", &g_ntophatCoreValue, g_tophatCoreMax,ontophatCoreSizeTrackBar,0);
- ontophatCoreSizeTrackBar(g_ntophatCoreValue, 0);
- g_nblackhatCoreValue = 5;
- g_nblackhatIterValue = 1;
- namedWindow("blackhat image");
- createTrackbar("iter count", "blackhat image", &g_nblackhatIterValue, g_blackhatIterMax,OnblackhatIterTrackbar,0);
- createTrackbar("core size", "blackhat image", &g_nblackhatCoreValue, g_blackhatCoreMax,onblackhatCoreSizeTrackBar,0);
- onblackhatCoreSizeTrackBar(g_nblackhatCoreValue, 0);
- imshow("src image", srcImage);
- moveWindow("src image", 0, 0);
- moveWindow("tophat image", srcImage.cols, 0);
- moveWindow("blackhat image", srcImage.cols*2, 0);
- waitKey(0);
- return 0;
- }
- void OntophatIterTrackbar(int pos,void* userData)
- {
- if(g_ntophatCoreValue == 0||g_ntophatIterValue == 0)
- {
- imshow("tophat image", srcImage);
- }
- else
- {
- if(g_ntophatCoreValue%2 == 0)
- g_ntophatCoreValue++;
- Mat core = getStructuringElement(MORPH_RECT, Size(g_ntophatCoreValue,g_ntophatCoreValue));
- morphologyEx(srcImage, tophatImage, MORPH_TOPHAT, core,Point(-1,-1),g_ntophatIterValue);
- imshow("tophat image", tophatImage);
- }
- }
- void ontophatCoreSizeTrackBar(int pos,void* userData)
- {
- if(g_ntophatCoreValue == 0||g_ntophatIterValue == 0)
- {
- imshow("tophat image", srcImage);
- }
- else
- {
- if(g_ntophatCoreValue%2 == 0)
- g_ntophatCoreValue++;
- Mat core = getStructuringElement(MORPH_RECT, Size(g_ntophatCoreValue,g_ntophatCoreValue));
- morphologyEx(srcImage, tophatImage, MORPH_TOPHAT, core,Point(-1,-1),g_ntophatIterValue);
- imshow("tophat image", tophatImage);
- }
- }
- void OnblackhatIterTrackbar(int pos,void* userData)
- {
- if(g_nblackhatCoreValue == 0||g_nblackhatIterValue == 0)
- {
- imshow("blackhat image", srcImage);
- }
- else
- {
- if(g_nblackhatCoreValue%2 == 0)
- g_nblackhatCoreValue++;
- Mat core = getStructuringElement(MORPH_RECT, Size(g_nblackhatCoreValue,g_nblackhatCoreValue));
- morphologyEx(srcImage, blackhatImage, MORPH_BLACKHAT, core,Point(-1,-1),g_nblackhatIterValue);
- imshow("blackhat image", blackhatImage);
- }
- }
- void onblackhatCoreSizeTrackBar(int pos,void* userData)
- {
- if(g_nblackhatCoreValue == 0||g_nblackhatIterValue == 0)
- {
- imshow("blackhat image", srcImage);
- }
- else
- {
- if(g_nblackhatCoreValue%2 == 0)
- g_nblackhatCoreValue++;
- Mat core = getStructuringElement(MORPH_RECT, Size(g_nblackhatCoreValue,g_nblackhatCoreValue));
- morphologyEx(srcImage, blackhatImage, MORPH_BLACKHAT, core,Point(-1,-1),g_nblackhatIterValue);
- imshow("blackhat image", blackhatImage);
- }
- }
OPENCV形态学操作1的更多相关文章
- opencv::形态学操作
形态学操作 开操作- open 闭操作- close 形态学梯度- Morphological Gradient 顶帽 – top hat 黑帽 – black hat 开操作- open 先腐蚀后膨 ...
- opencv 形态学操作应用-提取水平与垂直线
adaptiveThreshold(~gray_src, binImg, , ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, , -); #include <ope ...
- OpenCV学习笔记(六) 滤波器 形态学操作(腐蚀、膨胀等)
转自:OpenCV 教程 另附:计算机视觉:算法与应用(2012),Learning OpenCV(2009) 平滑图像:滤波器 平滑 也称 模糊, 是一项简单且使用频率很高的图像处理方法.平滑处理的 ...
- OpenCV 图象腐蚀形态学操作 全家桶
图象腐蚀与形态学操作 opencv 1. 通过调用库函数实现图像的腐蚀.膨胀: 2. 通过设置结构元素.元素大小.形态学操作类型实现对图象的形态学操作. 源码(VS2017+OpenCV 4.0) # ...
- 【图像处理】OpenCV+Python图像处理入门教程(七)图像形态学操作
图像形态学主要从图像内提取分量信息,该分量信息通常对表达图像的特征具有重要意义.例如,在车牌号码识别中,能够使用形态学计算其重要特征信息,在进行识别时,只需对这些特征信息运算即可.图像形态学在目标视觉 ...
- opencv学习笔记(五)----图像的形态学操作
图像的形态学操作有基本的腐蚀和膨胀操作和其余扩展形态学变换操作(高级操作)-----开运算,闭运算,礼帽(顶帽)操作,黑帽操作...(主要也是为了去噪声,改善图像) 形态学操作都是用于处理二值图像(其 ...
- EasyPR--开发详解(4)形态学操作、尺寸验证、旋转等操作
在上一篇深度分析与调优讨论中,我们介绍了高斯模糊,灰度化和Sobel算子.在本文中,会分析剩余的定位步骤. 根据前文的内容,车牌定位的功能还剩下如下的步骤,见下图中未涂灰的部分. 图1 车牌定位步骤 ...
- opencv6.1-imgproc图像处理模块之平滑与形态学操作
这个部分是<opencv-tutorials.pdf>的部分,这部分也是几大部分中例子最多的,其实这个教程的例子都很不错,不过有些看得出来还是c接口的例子,说明例子有些年头了,其实在&qu ...
- OpenCV-Python:形态学操作
常用的形态学操作:腐蚀.膨胀.开运算和闭运算 一.什么叫形态学操作 形态学操作就是改变物体的形状,比如腐蚀就是"变瘦",膨胀就是"变胖" 形态学操作一般作用于二 ...
随机推荐
- Ubuntu配置eclipse
1.安装jdk 去官网下载最新版jdk,目前是 jdk-8u45-linux-x64.tar.gz 创建Java的目标路径文件夹,这里我们放在/usr/lib/jvm下面.在终端下操作: sudo m ...
- IO流的操作规律
输入流和输出流相对于内存设备而言. 将外设中的数据读取到内存中:输入将内存的数写入到外设中:输出. 字符流的由来:其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表.获取对应的文字.在 ...
- 异步加载AsyncTask
private void huodeshuju() { new AsyncTask<String, Void, String>() { @Overrid ...
- AsyncTask异步加载和HttpURLConnection网络请求数据
//获得网络数据 private void huodeshuju() { //这里是使用线程,已注释掉 /*new Thread(){ public void ...
- 用python计算md5,sha1,crc32
Linux下计算md5sum,sha1sum,crc: 命令 输出 $md5sum hello f19dd746bc6ab0f0155808c388be8ff0 hello $sha1sum hel ...
- HDU1896Stones(优先队列)
Stones Time Limit : 5000/3000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total Submis ...
- java 接口参数
Example6_5.java interface SpeakHello { void speakHello(); } class Chinese implements SpeakHello { pu ...
- 当浏览器窗体改变时,div跟着变动方法
$(function(){ resizeU(); $(window).resize(resizeU); }); function resizeU() { var divkuangH = $(windo ...
- 服务器 vps 空间
服务器 服务器是一台独立的机器,拥有独立的ip,磁盘空间,内存空间,可以认为是一台功能强大的电脑. VPS VPS是利用虚拟化技术将服务器虚拟成多台服务器,独立的ip,磁盘空间,内存空间,服务器的vp ...
- jsp如果超过字数就变成...
<script> var infoTitle = '<ww:property value="infoTitle"/>'; if(infoTitle.leng ...