我的编程空间,编程开发者的网络收藏夹
学习永远不晚

OpenCV图像处理之实现图像膨胀腐蚀操作

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

OpenCV图像处理之实现图像膨胀腐蚀操作

一.形态学操作概念

图像形态学操作是指基于形状的一系列图像处理操作的合集,主要是基于集合论基础上的形态学数学对图像进行处理。

形态学有四个基本操作:腐蚀、膨胀、开操作、闭操作,膨胀与腐蚀是图像处理中最常用的形态学操作手段。

二.形态学操作-膨胀

跟卷积操作类似,假设有图像A和结构元素B,结构元素B在图像A上面移动,其中结构元素B定义其中心为锚点,计算B覆盖下A的最大像素值用来替换锚点的像素,其中B作为结构体可以是任意形状。

膨胀的原理:

膨胀或者腐蚀操作就是将图像(或图像的一部分区域,我们称之为图像A)与结构元素(我们称之为卷积核B)进行卷积。核可以是任何的形状和大小,拥有一个单独定义出来的参考点,我们称其为锚点(anchorpoin)。多数情况下,核是一个小的中间带有参考点和实心正方形或者圆盘,可以把核视为模板或者掩码。

膨胀就是求局部最大值的操作,核B与图形卷积,即计算核B覆盖的区域的像素点的最大值,并把这个最大值赋值给参考点指定的像素。这样就会使图像中的高亮区域逐渐增长。

膨胀和腐蚀操作的核心内容是结构元素。一般来说结构元素是由元素为1或者0的矩阵组成。结构元素为1的区域定义了图像的领域,领域内的像素在进行膨胀和腐蚀等形态学操作时要进行考虑。

膨胀函数API接口

dst=cv2.dilate(  
        InputArray class="lazy" data-src,  
        OutputArray dst,  
        InputArray kernel,  
        Point anchor=Point(-1,-1),  
        int iterations=1,  
        int borderType=BORDER_CONSTANT,  
        const Scalar& borderValue=morphologyDefaultBorderValue()   
    );  

参数详解:

第一个参数,InputArray类型的class="lazy" data-src,输入图像,即源图像,填Mat类的对象即可。图像通道的数量可以是任意的,但图像深度应为CV_8U,CV_16U,CV_16S,CV_32F或 CV_64F其中之一。
第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。

第三个参数,InputArray类型的kernel,膨胀操作的核。若为NULL时,表示的是使用参考点位于中心3x3的核。

我们一般使用函数 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 ));

第四个参数,Point类型的anchor,锚的位置,其有默认值(-1,-1),表示锚位于中心。

第五个参数,int类型的iterations,迭代使用erode()函数的次数,默认值为1。

第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。

第七个参数,const Scalar&类型的borderValue,当边界为常数时的边界值,有默认值morphologyDefaultBorderValue(),一般我们不用去管他。需要用到它时,可以看官方文档中的createMorphologyFilter()函数得到更详细的解释。

使用erode函数,一般我们只需要填前面的三个参数,后面的四个参数都有默认值。而且往往结合getStructuringElement一起使用。

结构元素的API函数接口

cv::Mat kernel = getStructuringElement(int shape,Size ksize,Point anchor);
//返回值:返回指定形状和尺寸的结构元素
 
 
//结构元素的定义:形状 (MORPH_RECT(矩形核)
//MORPH_CROSS(十字交叉形核) 
//MORPH_ELLIPSE(椭圆形核));结构元素大小;锚点 默认是Point(-1, -1)意思就是中心像素,也可以自己指定
 
//函数接口示例
cv::Mat elementRect,elementCross,elementEllipse;
 
    elementRect = cv::getStructuringElement(cv::MORPH_RECT,cv::Size(3,3),cv::Point(-1,-1));
 
    elementCross = 
    cv::getStructuringElement(cv::MORPH_CROSS,cv::Size(3,3),cv::Point(-1,-1));
 
    elementEllipse = 
    cv::getStructuringElement(cv::MORPH_ELLIPSE,cv::Size(5,5),cv::Point(-1,-1));
 

此外,我们也可以自定义结构元素,如下:

使用Mat_模板类自定义5×5大小十字形、菱形、方形、x形结构元素:

 //自定义核(结构元素)
    cv::Mat_<uchar> cross(5,5);
    cv::Mat_<uchar> diamond(5,5);
    cv::Mat_<uchar> x(5,5);
    cv::Mat_<uchar> square(5,5);
 
    // Creating the cross-shaped structuring element
    cross <<
            0, 0, 1, 0, 0,
            0, 0, 1, 0, 0,
            1, 1, 1, 1, 1,
            0, 0, 1, 0, 0,
            0, 0, 1, 0, 0;
 
    // Creating the diamond-shaped structuring element
    diamond <<
            0, 0, 1, 0, 0,
            0, 1, 1, 1, 0,
            1, 1, 1, 1, 1,
            0, 1, 1, 1, 0,
            0, 0, 1, 0, 0;
 
    // Creating the x-shaped structuring element
    x <<
            1, 0, 0, 0, 1,
            0, 1, 0, 1, 0,
            0, 0, 1, 0, 0,
            0, 1, 0, 1, 0,
            1, 0, 0, 0, 1;
 
    // Creating the square-shaped structuring element
    square <<
            1, 1, 1, 1, 1,
            1, 1, 1, 1, 1,
            1, 1, 1, 1, 1,
            1, 1, 1, 1, 1,
            1, 1, 1, 1, 1;
 
    int xnr = x.rows;
    int xnl = x.cols;
    for(int j = 0;j<xnr;j++)
    {
        char *data = x.ptr<char>(j);
        for(int i = 0; i<xnl; i++)
        {
            int value = data[i];
            std::cout<<value<<" ";
        }
        std::cout<<std::endl;
    }

三.形态学操作—腐蚀

腐蚀就是清除掉图像的一些毛刺和细节,腐蚀一般可以用来消除噪点,分割出独立的图像元素等。其本质上也是一种空间滤波,设定一个掩模,掩模中心逐次滑过每一个像素点,当前像素点(即掩模中心所对应的位置)的值设为掩模覆盖区域中像素的最小值。

腐蚀原理

膨胀或者腐蚀操作就是将图像(或图像的一部分区域,我们称之为图像A)与结构元素(我们称之为卷积核B)进行卷积。核可以是任何的形状和大小,拥有一个单独定义出来的参考点,我们称其为锚点(anchorpoin)。多数情况下,核是一个小的中间带有参考点和实心正方形或者圆盘,可以把核视为模板或者掩码。掩膜中心位置的像素点是否与周围领域的像素点颜色一样(即是否是白色点,即像素值是否为255),若一致,则保留,不一致则该点变为黑色(值即为0)。

腐蚀函数API接口


dst=cv2.erode(  
        InputArray class="lazy" data-src,  
        OutputArray dst,  
        InputArray kernel,  
        Point anchor=Point(-1,-1),  
        int iterations=1,  
        int borderType=BORDER_CONSTANT,  
        const Scalar& borderValue=morphologyDefaultBorderValue()  
     );  

参数说明:

第一个参数,InputArray类型的class="lazy" data-src,输入图像,即源图像,填Mat类的对象即可。图像通道的数量可以是任意的,但图像深度应为CV_8U,CV_16U,CV_16S,CV_32F或 CV_64F其中之一。

第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。

第三个参数,InputArray类型的kernel,膨胀操作的核。若为NULL时,表示的是使用参考点位于中心3x3的核。

我们一般使用函数 getStructuringElement配合这个参数的使用。getStructuringElement函数会返回指定形状和尺寸的结构元素(内核矩阵)。

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

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

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

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

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

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

第四个参数,Point类型的anchor,锚的位置,其有默认值(-1,-1),表示锚位于中心。

第五个参数,int类型的iterations,迭代使用erode()函数的次数,默认值为1。

第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。

第七个参数,const Scalar&类型的borderValue,当边界为常数时的边界值,有默认值morphologyDefaultBorderValue(),一般我们不用去管他。需要用到它时,可以看官方文档中的createMorphologyFilter()函数得到更详细的解释。

使用erode函数,一般我们只需要填前面的三个参数,后面的四个参数都有默认值。而且往往结合getStructuringElement一起使用。

腐蚀的具体操作是:用一个结构元素(一般是3×3的大小)扫描图像中的每一个像素,用结构元素中的每一个像素与其覆盖的像素做“与”操作,如果都为1,则该像素为1,否则为0。

膨胀的具体操作是:用一个结构元素(一般是3×3的大小)扫描图像中的每一个像素,用结构元素中的每一个像素与其覆盖的像素做“与”操作,如果都为0,则该像素为0,否则为1。

代码实现:

#include"stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include<stdio.h>
using namespace cv;
using namespace std;
 
 
int _tmain(int argc, _TCHAR* argv[])
{
	Mat image1 = imread("F:/photo/qx.jpg", 1);
	namedWindow("input_picture1");
	imshow("input_picture1", image1);
 
	Mat image2;
	Mat image3;
	cvtColor(image1, image2, COLOR_RGB2GRAY);
	namedWindow("input_picture2");
	imshow("input_picture2", image2);
 
	threshold(image2, image3, 65, 255, THRESH_BINARY);
	namedWindow("input_picture3");
	imshow("input_picture3", image3);
 
	Mat eroded;
	erode(image3, eroded, Mat());
	namedWindow("erode");
	imshow("erode", eroded);
 
	Mat dilated;
	dilate(image3, dilated, Mat());
	namedWindow("dilate");
	imshow("dilate", dilated);
 
	waitKey(0);
	return 0;
}

图像处理效果

原图和灰度图

灰度图和二值化图: 

 二值化图像腐蚀膨胀效果:

到此这篇关于OpenCV图像处理之实现图像膨胀腐蚀操作的文章就介绍到这了,更多相关OpenCV图像膨胀腐蚀内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

OpenCV图像处理之实现图像膨胀腐蚀操作

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

OpenCV+Qt实现图像处理操作

这篇文章主要为大家详细介绍了OpenCV+Qt实现图像处理操作,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
2022-11-13

OpenCV+Qt实现图像处理操作工具的示例代码

这篇文章主要介绍了利用OpenCV+Qt实现图像处理操作工具,可以实现雪花屏、高斯模糊、中值滤波、毛玻璃等操作,感兴趣的可以了解一下
2022-11-13

python中opencv怎么实现图像叠加、图像融合、按位操作

本篇内容介绍了“python中opencv怎么实现图像叠加、图像融合、按位操作”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录1图像叠加2
2023-06-20

如何在Python中使用OpenCV实现图像平滑处理操作

这期内容当中小编将会给大家带来有关如何在Python中使用OpenCV实现图像平滑处理操作,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。什么是图像平滑处理在尽量保留图像原有信息的情况下,过滤掉图像内部的噪
2023-06-15

Java数字图像处理之图像灰度处理怎么实现

本篇内容介绍了“Java数字图像处理之图像灰度处理怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、简介图像灰度化处理可以作为图像处
2023-07-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录