热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于OpenCV的膨胀和腐蚀

本博客讲解形态雪中的膨胀和腐蚀操作。使用的函数为:cv::erodecv::dilate形态学操作简而言之:一组基于形状的图像处理的操作。形态学运算
本博客讲解形态雪中的膨胀和腐蚀操作。使用的函数为:

        cv::erode

        cv::dilate


形态学操作

简而言之:一组基于形状的图像处理的操作。形态学运算对输入图像应用astructuring元素生成一个输出图像。
最基本的形态操作是两个:腐蚀和膨胀。他们有一个广泛的用途,即:


  • 去除噪声
  • 单个元素的分离和图像中的分离元素的连接
  • 发现图像中的强度颠簸或空洞

我们将简要地解释扩张和侵蚀,使用下面的图像作为一个例子:



Dilation


  • 该操作由卷积图像 A 和某个卷积核 ( B)的卷积完成,卷积核可以有任何形状或大小,通常是一个方形或圆形.
  • 卷积核 B 有一个定义的锚定点( anchor point), 通常是内核的中心.
  • 随着卷积核 B 扫过图像, 我们计算由卷积核 B 覆盖的的像素的最大值,并用该最大值替换在锚定点位置的图像像素。 可以推断,这种最大化的操作使图像内明亮区域“生长”(也就是所谓的膨胀)。以上面的图片为例。应用扩张,我们可以得到:



围绕黑色字母区域的背景 (亮的区域) 的膨胀


Erosion

这个操作是在内核重叠区域上计算一个局部最小值.

随着卷积核B 扫过图像, 计算有卷积核 B 覆盖部分像素的最小值,并用最小值替换在锚定点的图像像素.

和dilation的例子一样,我们可以对原始图像应用腐蚀算子。你可以看到在下面的结果,图像的明亮区域(背景,显然的),变得更薄,而黑暗的区域(“书写”部分)变得更大。



/*** @file Morphology_1.cpp* @brief Erosion and Dilation sample code* @author OpenCV team*/#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"using namespace cv;/// Global variables
Mat src, erosion_dst, dilation_dst;int erosion_elem = 0;
int erosion_size = 0;
int dilation_elem = 0;
int dilation_size = 0;
int const max_elem = 2;
int const max_kernel_size = 21;/** Function Headers */
void Erosion( int, void* );
void Dilation( int, void* );/*** @function main*/
int main( int, char** argv )
{/// Load an imagesrc = imread( argv[1], IMREAD_COLOR );if( src.empty() ){ return -1; }/// Create windowsnamedWindow( "Erosion Demo", WINDOW_AUTOSIZE );namedWindow( "Dilation Demo", WINDOW_AUTOSIZE );moveWindow( "Dilation Demo", src.cols, 0 );/// Create Erosion TrackbarcreateTrackbar( "Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Erosion Demo",&erosion_elem, max_elem,Erosion );createTrackbar( "Kernel size:\n 2n +1", "Erosion Demo",&erosion_size, max_kernel_size,Erosion );/// Create Dilation TrackbarcreateTrackbar( "Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Dilation Demo",&dilation_elem, max_elem,Dilation );createTrackbar( "Kernel size:\n 2n +1", "Dilation Demo",&dilation_size, max_kernel_size,Dilation );/// Default startErosion( 0, 0 );Dilation( 0, 0 );waitKey(0);return 0;
}//![腐蚀]
/*** @function Erosion*/
void Erosion( int, void* )
{int erosion_type = 0;if( erosion_elem == 0 ){ erosion_type = MORPH_RECT; }else if( erosion_elem == 1 ){ erosion_type = MORPH_CROSS; }else if( erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; }//![kernel]Mat element = getStructuringElement( erosion_type,Size( 2*erosion_size + 1, 2*erosion_size+1 ),Point( erosion_size, erosion_size ) );//![kernel]/// Apply the erosion operationerode( src, erosion_dst, element );imshow( "Erosion Demo", erosion_dst );
}
//![腐蚀]//![膨胀]
/*** @function Dilation*/
void Dilation( int, void* )
{int dilation_type = 0;if( dilation_elem == 0 ){ dilation_type = MORPH_RECT; }else if( dilation_elem == 1 ){ dilation_type = MORPH_CROSS; }else if( dilation_elem == 2) { dilation_type = MORPH_ELLIPSE; }Mat element = getStructuringElement( dilation_type,Size( 2*dilation_size + 1, 2*dilation_size+1 ),Point( dilation_size, dilation_size ) );/// Apply the dilation operationdilate( src, dilation_dst, element );imshow( "Dilation Demo", dilation_dst );
}
//![膨胀]


例子




推荐阅读
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • 实现一个通讯录系统,可添加、删除、修改、查找、显示、清空、排序通讯录信息
    本文介绍了如何实现一个通讯录系统,该系统可以实现添加、删除、修改、查找、显示、清空、排序通讯录信息的功能。通过定义结构体LINK和PEOPLE来存储通讯录信息,使用相关函数来实现各项功能。详细介绍了每个功能的实现方法。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 本文介绍了指针的概念以及在函数调用时使用指针作为参数的情况。指针存放的是变量的地址,通过指针可以修改指针所指的变量的值。然而,如果想要修改指针的指向,就需要使用指针的引用。文章还通过一个简单的示例代码解释了指针的引用的使用方法,并思考了在修改指针的指向后,取指针的输出结果。 ... [详细]
author-avatar
liutiancinet
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有