C++ Opencv自写函数实现膨胀腐蚀处理技巧

 更新时间:2021年10月13日 10:40:17   作者:秋沐霖  
这篇文章主要介绍了C++ Opencv 自写函数实现膨胀腐蚀处理,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

一、膨胀腐蚀学习笔记

二、代码及结果分享

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

//定义腐蚀函数
void myErode(Mat Src, Mat Tem, Mat Dst)
{
	int m = (Tem.rows - 1) / 2;
	int n = (Tem.cols - 1) / 2;
	for (int i = m; i < Src.rows - m; i++)//i、j的范围保证结构元始终在扩展后的图像内部
	{
		for (int j = n; j < Src.cols - n; j++)
		{
			Mat SrcROI = Src(Rect(j - m, i - n, Tem.cols, Tem.rows));
			double sum = 0;
			sum = SrcROI.dot(Tem);//矩阵对应位置相乘后求和
			if (sum == 9)//结构元的9个元素均为1,和为9才能保证结构元完全包含于相应集合
				Dst.at<uchar>(i, j) = 255;
			else
				Dst.at<uchar>(i, j) = 0;
		}
	}
}

//定义膨胀函数
void myDilate(Mat Src, Mat Tem, Mat Dst)
{
	int m = (Tem.rows - 1) / 2;
	int n = (Tem.cols - 1) / 2;
	for (int i = m; i < Src.rows - m; i++)//i、j的范围保证结构元始终在扩展后的图像内部
	{
		for (int j = n; j < Src.cols - n; j++)
		{
			Mat SrcROI = Src(Rect(j - m, i - n, Tem.cols, Tem.rows));
			double sum = 0;
			sum = SrcROI.dot(Tem);//矩阵对应位置相乘后求和
			if (sum != 0)//结构元的9个元素均为1,只要和不为0,就能说明结构元与相应集合有交集
				Dst.at<uchar>(i, j) = 255;
			else
				Dst.at<uchar>(i, j) = 0;
		}
	}
}

int main()
{
	Mat mImage = imread("dada.jpg", 0);
	if (mImage.data == 0)
	{
		cerr << "Image reading error !" << endl;
		system("pause");
		return -1;
	}
	namedWindow("The original image", WINDOW_NORMAL);
	imshow("The original image", mImage);

	//设置阈值将图像二值化
	const int binThreshold = 80;
	for (int i = 0; i < mImage.rows; i++)
	{
		uchar* pImage = mImage.ptr<uchar>(i);
		for (int j = 0; j < mImage.cols; j++)
		{
			if (pImage[j] > binThreshold)//事实上应将灰度值大于阈值的赋值为255,但为了方便后续膨胀腐蚀的计算,在这里将其赋值为1
				pImage[j]= 1;
			else
				pImage[j] = 0;
		}
	}

	//定义并初始化结构元
	Mat mTemplate(3, 3, CV_8UC1, Scalar(1));
	if (mTemplate.rows * mTemplate.cols % 2 == 0)
	{
		cerr << "The size doesn't meet the requirement !" << endl;
		system("pause");
		return -1;
	}
	
	//扩展图像边界
	copyMakeBorder(mImage, mImage, mTemplate.rows, mTemplate.rows, mTemplate.cols, mTemplate.cols, BORDER_CONSTANT, Scalar(0));

	//进行图像腐蚀
	Mat mEResult = mImage.clone();
	myErode(mImage, mTemplate, mEResult);

	//进行图像膨胀
	Mat mDResult = mImage.clone();
	myDilate(mImage, mTemplate, mDResult);

	//进行显示
	namedWindow("The eroding image", WINDOW_NORMAL);
	imshow("The eroding image", mEResult);
	namedWindow("The dilating image", WINDOW_NORMAL);
	imshow("The dilating image", mDResult);
	waitKey();
	destroyAllWindows();

	return 0;
}

膨胀(dilate)和腐蚀(erode)均是对白色区域而言。由结果可明显看出,膨胀后的白色面积要比腐蚀后的大。由图像左下角的水印变化也可直观看出两种操作对图像的不同影响。

三、注意事项

在本次编程实现过程中,为了确定结构元是否包含于集合(或与集合是否有交集),需要让结构元中各元素与图像中对应位置像素值相乘后求和。Mat类型中有几种不同类型的乘法,在这里加以总结。

Mat A, B ;

3.1A.dot(B)

A、B对应位置元素相乘,之后将所有乘积相加求和,返回值是double型数字。要求A、B size必须相同。

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
	uchar A[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
	uchar B[3][3] = { { 1,1,1 },{ 1,1,1 },{ 1,1,1 } };
	Mat Src(3, 3, CV_8UC1, A);
	Mat Dst(3, 3, CV_8UC1, B);
	double Result = Src.dot(Dst);
	cout << "Src:" << Src << endl;
	cout << "Dst:" << Dst << endl;
	cout << "Result:" << Result << endl;
	system("pause");
	return 0;
}

3.2A.mul(B)

A、B对应位置元素相乘,返回值是和A、B等大小,同类型的Mat型矩阵。要求A、B size必须相同。若计算结果溢出,则溢出值自动变为当前数据类型下允许的的最大值。

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
	uchar A[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
	uchar B[3][3] = { { 1,1,1 },{ 1,1,1 },{ 1,1,1 } };
	Mat Src(3, 3, CV_8UC1, A);
	Mat Dst(3, 3, CV_8UC1, B);
	Mat Result = Src.mul(Dst);
	cout << "Src:" << Src << endl;
	cout << "Dst:" << Dst << endl;
	cout << "Result:" << Result << endl;
	system("pause");
	return 0;
}

到此这篇关于C++ Opencv 自写函数实现膨胀腐蚀处理的文章就介绍到这了,更多相关C++ Opencv 膨胀腐蚀内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Qt 使用 canon edsdk 实现实时预览的示例代码

    Qt 使用 canon edsdk 实现实时预览的示例代码

    这篇文章主要介绍了Qt 使用 canon edsdk 实现实时预览的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • DevC++如何自定义头文件并使用

    DevC++如何自定义头文件并使用

    文章介绍了如何在DevC++中自定义头文件并使用,首先创建一个项目,然后新建一个头文件并编写代码,保存后创建一个源文件并将其放在项目目录下
    2024-11-11
  • C/C++使用API实现数据的压缩与解压缩

    C/C++使用API实现数据的压缩与解压缩

    在Windows编程中,经常会遇到需要对数据进行压缩和解压缩的情况,本文将深入探讨使用Windows API进行数据压缩与解压缩的过程,感兴趣的小伙伴可以了解下
    2023-11-11
  • C语言中的柔性数组你了解吗

    C语言中的柔性数组你了解吗

    这篇文章主要为大家详细介绍了C99中的新语法——柔性数组的使用以及优缺点,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的可以了解一下
    2023-04-04
  • 讲解C语言编程中指针赋值的入门实例

    讲解C语言编程中指针赋值的入门实例

    这篇文章主要介绍了讲解C语言编程中指针赋值的入门实例,通过const int i与int *const pi这样两个例子来分析指针的赋值和地址指向,需要的朋友可以参考下
    2015-12-12
  • 解析C++中的虚拟函数及其静态类型和动态类型

    解析C++中的虚拟函数及其静态类型和动态类型

    虚拟函数(Visual Function)亦常被成为虚函数,是C++中的一个重要特性,本文我们就来解析C++中的虚拟函数及其静态类型和动态类型
    2016-06-06
  • C++实现有向图的邻接表表示

    C++实现有向图的邻接表表示

    这篇文章主要为大家详细介绍了C++实现有向图的邻接表表示,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C语言入门篇--注释,关键字typedef及转义字符详解

    C语言入门篇--注释,关键字typedef及转义字符详解

    本篇文章是c语言基础篇,主要为大家介绍了C语言的关键字typedef,注释,转义字符的基本理论知识,希望可以帮助大家快速入门c语言的世界,更好的理解c语言
    2021-08-08
  • C++编译器无法捕捉到的8种错误实例分析

    C++编译器无法捕捉到的8种错误实例分析

    这篇文章主要介绍了C++编译器无法捕捉到的8种错误,是深入学习C++所必须加以掌握的排错技能,需要的朋友可以参考下
    2014-09-09
  • C语言实现杨辉三角实例

    C语言实现杨辉三角实例

    这篇文章主要介绍了C语言实现杨辉三角的方法,主要通过数组简单实现,具有一定的参考借鉴价值,需要的朋友可以参考下
    2014-09-09

最新评论