这篇文章主要介绍了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 膨胀腐蚀内容请搜索编程学习网以前的文章希望大家以后多多支持编程学习网!
沃梦达教程
本文标题为:C++ Opencv自写函数实现膨胀腐蚀处理技巧
基础教程推荐
猜你喜欢
- C语言基础全局变量与局部变量教程详解 2022-12-31
- 一文带你了解C++中的字符替换方法 2023-07-20
- C++中的atoi 函数简介 2023-01-05
- C++使用easyX库实现三星环绕效果流程详解 2023-06-26
- C语言 structural body结构体详解用法 2022-12-06
- C++详细实现完整图书管理功能 2023-04-04
- C/C++编程中const的使用详解 2023-03-26
- 如何C++使用模板特化功能 2023-03-05
- C利用语言实现数据结构之队列 2022-11-22
- 详解c# Emit技术 2023-03-25