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 自写函数实现膨胀腐蚀处理的更多相关文章
- opencv学习之路(16)、膨胀腐蚀应用之走迷宫
一.分析 贴出应用图片以供直观了解 红色部分,因图而异(某些参数,根据图片的不同需要进行相应的修改) 二.代码 #include "opencv2/opencv.hpp" #inc ...
- opencv学习之路(14)、形态学之膨胀腐蚀
一.膨胀腐蚀概述(对高亮部分进行操作) 二.膨胀 三.腐蚀 四.代码 1.查看结构元素 #include<opencv2/opencv.hpp> #include<iostream& ...
- 常用的OpenCV 2.0函数速查
OpenCV 2.0函数释义列表 1.cvLoadImage:将图像文件加载至内存: 2.cvNamedWindow:在屏幕上创建一个窗口: 3.cvShowImage:在一个已创建好的窗口中显示图像 ...
- opencv 手写选择题阅卷 (二)字符识别
opencv 手写选择题阅卷 (二)字符识别 选择题基本上只需要识别ABCD和空五个内容,理论上应该识别率比较高的,识别代码参考了网上搜索的代码,因为参考的网址比较多,现在也弄不清是参考何处的代码了, ...
- 自写函数VB6 STUFF函数 和 VB.net 2010 STUFF函数 详解
'*************************************************************************'**模 块 名:自写函数VB6 STUFF函数 和 ...
- opencv 手写选择题阅卷 (四)Android端 手机应用开发
opencv 手写选择题阅卷 (四)Android 手机应用开发 在PC端把代码调通以后开始开发Android 手机应用,因为主要功能代码为C++代码,所以需要通过NDK编译,JAVA通过JNI方式调 ...
- opencv 手写选择题阅卷 (三)训练分类器
opencv 手写选择题阅卷 (三)训练分类器 1,分类器选择:SVM 本来一开始用的KNN分类器,但这个分类器目前没有实现保存训练数据的功能,所以选择了SVN分类器; 2,样本图像的预处理和特征提取 ...
- 由lib引发的血案(opencv找不函数问题)
在使用opencv中的函数时,连续两次遇到函数找不到的问题,第一次查时按照他人说的包含进一个头文件后,果真还真解决了:然而第二次在调用cvInpaint函数时包含进对应头文件,编译通过但运行不成功还是 ...
- (原)使用opencv的warpAffine函数对图像进行旋转
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5070576.html 参考网址: http://stackoverflow.com/questions ...
随机推荐
- Jenkins+docker自动部署
项目目录结构如下 对此项目,使用Jenkins构建dockers镜像 步骤如下: 1.安装Jenkins和docker,具体安装步骤,自行度娘把,在此不详述了. 2.Jenkins安装插件Gradle ...
- 【aardio】]SQL创建、读写 excel
import access; var db,err = access( "/test.xls" ) //文件不存在可自动创建 //创建表 if( ! db.existsTable( ...
- dotNet程序员的Java爬坑之旅(二)
囉里囉唆的寫了一大堆,最後還是全刪除了.哎~ 言歸正傳,最近因爲發生了很多事情,所以更新的有嗲晚了,最近也一直在學習,但是感覺效率什麽的不是很高,這是不對的,反思一下,從這篇博文開始,打起精神吧. M ...
- 表table
(一)创建表 create table if not exists mydb.employees( name string comment "employee name", sal ...
- http://www.cnblogs.com/langjt/p/4281477.html
http://www.cnblogs.com/langjt/p/4281477.html
- 【SerpentAI:Python开源游戏智能体开发框架——相比OpenAI Universe可导入自己的游戏、可脱离Docker/VNC运行】
https://weibo.com/fly51fly?from=myfollow_all&is_all=1#1514439335614 [SerpentAI:Python开源游戏智能体开发框架 ...
- c#串口测试
软件和代码网盘下载 https://pan.baidu.com/s/1dFrE1pv#list/path=%2F SerialPort 类 https://msdn.microsoft.com/zh- ...
- mac mysql5.7.17修改root初始密码(知道初始密码)
最近在mac上装个mysql可以说是麻烦死了,在这里就说说修改初始密码吧! 刚开始的时候不知道怎么修改,于是上网百度,网上几乎都是说要先执行命令mysqld_safe --skip-grant-tab ...
- P3047 [USACO12FEB]附近的牛Nearby Cows
https://www.luogu.org/problemnew/show/P304 1 #include <bits/stdc++.h> 2 #define up(i,l,r) for( ...
- Python19/1/11--标签与过滤器/Django模块导入继承/静态文件配置
1 模板语言之变量: -{{ }} 相当于执行了print -深度查询 . 如果是方法,不能加括号,不能传参数2 过滤器 {{ 变量|过滤器的名字:'参数' }} -add -default -s ...