opencv学习笔记11-opencv图像形态学处理

一、图像形态学处理:

        一种基于图像形状和结构的图像分析方法,主要使用二值图像。它涉及到几种基本的运算,包括腐蚀、膨胀、开运算(先腐蚀后膨胀)和闭运算(先膨胀后腐蚀)。

示例使用图片:(将硬币看为了背景)

 

示例图片:(将硬币看为了前景,可用于硬币计数)

二、结构元素:

(1)函数原型:
CV_EXPORTS_W Mat getStructuringElement(int shape, Size ksize, 
                                Point anchor = Point(-1,-1));
(2)函数功能:

        返回用于形态学操作的指定大小和形状的结构元素。

(3)参数:
  • shape:指定结构元素的形状,可以是 #MorphShapes 枚举类型中的一个值。#MorphShapes 包括:MORPH_RECT:矩形,MORPH_CROSS:十字形,MORPH_ELLIPSE:椭圆形。
  • ksize:结构元素的大小,用 Size 类型表示,Size 是一个包含宽度和高度的简单结构。
  • anchor:结构元素内部的锚点位置。默认值 Point(-1, -1) 表示锚点位于结构元素的中心。对于十字形结构元素,锚点的位置会影响其形状,因为十字形是围绕锚点对称的。对于其他形状,锚点主要影响形态学操作结果的偏移量。

三、腐蚀:

  • 腐蚀操作会减少对象的尺寸,移除对象的边缘,并且可以移除小的物体或细节。
  • 腐蚀是通过将结构元素(通常是一个简单的几何形状,如矩形、圆形等)滑动到图像上,只有当结构元素完全包含在前景(非零值)时,中心元素才被保留。
(1)函数原型:
CV_EXPORTS_W void erode( InputArray src, OutputArray dst, 
                        InputArray kernel, Point anchor = Point(-1,-1), 
                        int iterations = 1, int borderType = BORDER_CONSTANT, 
                 const Scalar& borderValue = morphologyDefaultBorderValue() );
(2)函数功能:

        通过使用特定的结构元素对图像进行腐蚀。

(3)参数:
  • src:输入图像,可以有任意数量的通道,但深度应该是 CV_8UCV_16UCV_16SCV_32FCV_64F 中的一种。

  • dst:输出图像,其大小和类型应与 src 相同。

  • kernel:用于腐蚀的结构元素,决定了在图像上取最小值时考虑的像素邻域的形状。如果 element=Mat()(即未指定),则默认使用 3 x 3 矩形结构元素。结构元素可以使用 #getStructuringElement 函数创建。

  • anchor:结构元素内锚点的位置。默认值 Point(-1, -1) 表示锚点位于结构元素的中心。

  • iterations:腐蚀操作应用的次数。

  • borderType:边界外推方法,用于确定图像边界外的像素值。#BorderTypes 定义了不同的边界类型,但 BORDER_WRAP 不受支持。

  • borderValue:在常数边界情况下的边界值。

(4)腐蚀操作的影响:

a.前景(白色区域)

  • 腐蚀操作会优先作用于前景区域,尤其是前景的边缘部分。如果前景对象的边缘像素在结构元素覆盖下不完全被前景像素填满,这些像素将被移除,导致前景对象的尺寸减小。
  • 小的前景对象或细节,如噪点或细小的纹理,可能会在腐蚀过程中被完全移除。
  • 腐蚀还可以平滑前景对象的边缘,使其变得更加圆润或平直。

b.背景(黑色区域)

  • 腐蚀操作通常不会改变背景区域,除非结构元素足够大,以至于触及了背景和前景的边界。
  • 如果前景对象非常接近背景,腐蚀操作可能会使这些对象与背景分离,从而增加背景区域的尺寸。
(5)代码示例:
#include <opencv2/core/utils/logger.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <iostream>
using namespace cv;
using namespace std;

int main()
{
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);
	//读取图片并转化为灰度图
	Mat srcMat = imread("C:\\Users\\86173\\Desktop\\TI\\Coin.jpg", 0);

	//判断读取图片是否失败
	if (srcMat.empty()) {
		cout << "fail to read pic!" << endl;
		return 0;
	}
	//定义图像容器
	Mat image;
	Mat erode_image;

	//二值化
	threshold(srcMat,image, 100, 255, THRESH_OTSU);

	//定义结构元素
	Mat element = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));

	//腐蚀
	erode(image, erode_image, element, Point(-1, -1), 1);

	//显示结果
	imshow("二值化", image);//二值化
	imshow("腐蚀", erode_image);//腐蚀


	waitKey(0);
	destroyAllWindows();
	return 0;

}
(6)运行结果:

(白色为前景,黑色为背景,)

四、膨胀:

  • 膨胀操作会增加前景对象的尺寸,向对象的边界外扩展。这可以填充前景对象中的小洞,并且可能连接邻近的前景对象。膨胀通常不会改变背景区域,除非膨胀的内核足够大,以至于触及了背景和前景的边界。
(1)函数原型:
CV_EXPORTS_W void dilate( InputArray src, OutputArray dst, 
                InputArray kernel, Point anchor = Point(-1,-1), 
                int iterations = 1, int borderType = BORDER_CONSTANT, 
                const Scalar& borderValue = morphologyDefaultBorderValue() ); 
(2)函数功能:
  • dilate 函数用于对图像进行膨胀操作,这是一种形态学处理,可以增加图像中前景对象的尺寸。
(3)原地模式
  • 函数支持原地模式(in-place mode),即输入图像 src 和输出图像 dst 可以使用相同的内存空间。
(4)参数:
  • src:输入图像,可以有任意数量的通道,但深度应该是 CV_8UCV_16UCV_16SCV_32F 或 CV_64F 中的一种。
  • dst:输出图像,其大小和类型应与 src 相同。
  • kernel:用于膨胀操作的结构元素。如果 element=Mat()(即未指定),则默认使用 3 x 3 矩形结构元素。结构元素可以使用 getStructuringElement 函数创建。
  • anchor:结构元素内锚点的位置。默认值 Point(-1, -1) 表示锚点位于结构元素的中心。
  • iterations:膨胀操作应用的次数。
  • borderType:边界外推方法,用于确定图像边界外的像素值。BORDER_WRAP 不受支持。详见 BorderTypes
  • borderValue:在常数边界情况下的边界值。
(5)代码示例:
#include <opencv2/core/utils/logger.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <iostream>
using namespace cv;
using namespace std;

int main()
{
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);
	//读取图片并转化为灰度图
	Mat srcMat = imread("C:\\Users\\86173\\Desktop\\TI\\Coin.jpg", 0);

	//判断读取图片是否失败
	if (srcMat.empty()) {
		cout << "fail to read pic!" << endl;
		return 0;
	}
	//定义图像容器
	Mat image;
	Mat erode_image;
	//二值化
	threshold(srcMat,image, 100, 255, THRESH_OTSU);

	//定义结构元素
	Mat element = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));

	//膨胀
	dilate(image, erode_image, element, Point(-1, -1), 1);
	//显示结果
	imshow("二值化", image);//二值化
	imshow("膨胀", erode_image);//膨胀


	waitKey(0);
	destroyAllWindows();
	return 0;

}
(6)运行结果:

五、开运算:

  • 执行高级形态学变换,先腐蚀再膨胀
(1)函数原型:
CV_EXPORTS_W void morphologyEx( InputArray src, OutputArray dst, 
                        int op, InputArray kernel, Point anchor = Point(-1,-1), 
                        int iterations = 1, int borderType = BORDER_CONSTANT, 
                    const Scalar& borderValue = morphologyDefaultBorderValue() );
(2)函数功能
  • morphologyEx 函数使用腐蚀和膨胀作为基本操作,可以执行高级形态学变换。
(3)参数:
  • src:源图像,可以有任意数量的通道,但深度应该是 CV_8UCV_16UCV_16SCV_32F 或 CV_64F 中的一种。
  • dst:目标图像,其大小和类型应与源图像 src 相同。
  • op:要执行的形态学操作类型,见 #MorphTypes
  • kernel:结构元素,用于定义形态学操作的形状和大小,可以使用 #getStructuringElement 创建。
  • anchor:结构元素内的锚点位置。负值意味着锚点位于结构元素的中心。
  • iterations:腐蚀和膨胀操作应用的次数。
  • borderType:边界外推方法,用于确定图像边界外的像素值,见 #BorderTypesBORDER_WRAP 不受支持。
  • borderValue:在常数边界情况下的边界值,默认值具有特殊含义。
(4)注意事项:

       迭代次数实际上是腐蚀或膨胀操作将被应用的次数。例如,对于形态学开操作(#MORPH_OPEN),两次迭代相当于依次应用:腐蚀 -> 腐蚀 -> 膨胀 -> 膨胀(而不是腐蚀 -> 膨胀 -> 腐蚀 -> 膨胀)。

(5)形态学操作类型(#MorphTypes 枚举类型的说明):
a.MORPH_ERODE:
  • 腐蚀操作。减少前景对象的尺寸,移除前景边缘的像素。
b.MORPH_DILATE:
  • 膨胀操作。增加前景对象的尺寸,填充前景内部的空洞。
c.MORPH_OPEN:
  • 开运算。先腐蚀再膨胀,有助于去除小的物体和细节,分离相邻对象。
  • 数学表达式为:
d.MORPH_CLOSE:
  • 闭运算。先膨胀再腐蚀,有助于填充小的空洞和缝隙,连接断裂的对象。
  • 数学表达式为:
e.MORPH_GRADIENT:
  • 形态学梯度。膨胀结果减去腐蚀结果,突出显示前景对象的边缘。
  • 数学表达式为:
f.MORPH_TOPHAT:
  • 顶帽操作。原图像减去开运算结果,显示比前景小的物体或细节。
  • 数学表达式为:
g.MORPH_BLACKHAT:
  • 黑帽操作。闭运算结果减去原图像,显示比前景大的区域或背景。
  • 数学表达式为:
h.MORPH_HITMISS:
  • 命中或错过操作。这是一种特殊的形态学操作,仅支持单通道8位二值图像。通常用于特定形状的匹配或检测。
(6)示例代码:
#include <opencv2/core/utils/logger.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <iostream>
using namespace cv;
using namespace std;

int main()
{
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);
	//读取图片并转化为灰度图
	Mat srcMat = imread("C:\\Users\\86173\\Desktop\\TI\\Coin.jpg", 0);

	//判断读取图片是否失败
	if (srcMat.empty()) {
		cout << "fail to read pic!" << endl;
		return 0;
	}
	//定义图像容器
	Mat image;
	Mat erode_image;
	//二值化
	threshold(srcMat,image, 100, 255, THRESH_OTSU);

	//定义结构元素
	Mat element = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));

    //闭运算
	morphologyEx(image, erode_image, MORPH_CLOSE, element, Point(-1, -1), 1);
	//显示结果
	imshow("二值化", image);//二值化
	imshow("闭运算", erode_image);//闭运算


	waitKey(0);
	destroyAllWindows();
	return 0;

}
(7)运行结果 

六、闭运算: 

  • 执行高级形态学变换,先膨胀再腐蚀。
(1)函数同开运算。
(2)示例代码:
#include <opencv2/core/utils/logger.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <iostream>
using namespace cv;
using namespace std;

int main()
{
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);
	//读取图片并转化为灰度图
	Mat srcMat = imread("C:\\Users\\86173\\Desktop\\TI\\Coin.jpg", 0);

	//判断读取图片是否失败
	if (srcMat.empty()) {
		cout << "fail to read pic!" << endl;
		return 0;
	}
	//定义图像容器
	Mat image;
	Mat erode_image;
	//二值化
	threshold(srcMat,image, 100, 255, THRESH_OTSU);

	//定义结构元素
	Mat element = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));

    //开运算
	morphologyEx(image, erode_image, MORPH_OPEN, element, Point(-1, -1), 1);
	//显示结果
	imshow("二值化", image);//二值化
	imshow("开运算", erode_image);//开运算


	waitKey(0);
	destroyAllWindows();
	return 0;

}
(3)运行结果:

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值