图像的膨胀与腐蚀——OpenCV与C++的具体实现
1. 膨胀与腐蚀的原理
膨胀与腐蚀是数学形态学在图像处理中最基础的操作。在笔者之前的文章《图像的卷积(滤波)运算(一)——图像梯度》、《图像的卷积(滤波)运算(二)——高斯滤波》具体介绍了图像卷积\滤波的具体的概念与操作,图像的膨胀与腐蚀其实也是一种类似的卷积操作。其卷积操作非常简单,对于图像的每个像素,取其一定的邻域,计算最大值/最小值作为新图像对应像素位置的像素值。其中,取最大值就是膨胀,取最小值就是腐蚀。
2. 膨胀的具体实现
1) OpenCV实现
在OpenCV中实现了图像膨胀的函数dilate(),可以直接调用:
Mat img = imread(imagename, IMREAD_GRAYSCALE);
if (img.empty())
{
fprintf(stderr, "Can not load image %s\n", imagename);
return -1;
}
//OpenCV方法
Mat dilated_cv;
dilate(img, dilated_cv, Mat());
dilate()函数第一个参数表示输入影像,第二个参数表示输出影像,第三个表示一个默认的核,在3X3的范围内寻找最大值。
2) C/C++实现
在一般的图像处理时,图像读写是由专门的组件进行读取的。这这里仍然使用OpenCV进行读取,以免增加复杂性。而在CV::Mat类中,提供了at()函数访问某一行某一列的像素值,可以通过at()函数去访问每一个像素的领域。
与之前OpenCV实现的一样,对于每一个像素,遍历以其像素位置为中心的3X3邻域,取最大值作为新图像对应位置的像素值。
其具体实现如下:
//从文件中读取成灰度图像
const char* imagename = "D:\\Data\\imgDemo\\lena.jpg";
Mat img = imread(imagename, IMREAD_GRAYSCALE);
if (img.empty())
{
fprintf(stderr, "Can not load image %s\n", imagename);
return -1;
}
//自定义方法
Mat dilated_my;
dilated_my.create(img.rows, img.cols, CV_8UC1);
for (int i = 0; i < img.rows; ++i)
{
for (int j = 0; j < img.cols; ++j)
{
//uchar minV = 255;
uchar maxV = 0;
//遍历周围最大像素值
for (int yi = i-1; yi <= i+1; yi++)
{
for (int xi = j-1; xi <= j+1; xi++)
{
if (xi<0||xi>= img.cols|| yi<0 || yi >= img.rows)
{
continue;
}
//minV = (std::min<uchar>)(minV, img.at<uchar>(yi, xi));
maxV = (std::max<uchar>)(maxV, img.at<uchar>(yi, xi));
}
}
dilated_my.at<uchar>(i, j) = maxV;
}
}
3) 验证与结果
为了验证自己的算法是否正确,可以通过把两者膨胀的结果通过compare()函数进行比较。compare()函数会逐个比较两者的像素值,如果相同就会返回255(白色),如果不相同就会返回0(黑色)。整个过程的具体实现如下:
#include <iostream>
#include <algorithm>
#include <opencv2\opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
//从文件中读取成灰度图像
const char* imagename = "D:\\Data\\imgDemo\\lena.jpg";
Mat img = imread(imagename, IMREAD_GRAYSCALE);
if (img.empty())
{
fprintf(stderr, "Can not load image %s\n", imagename);
return -1;
}
//OpenCV方法
Mat dilated_cv;
dilate(img, dilated_cv, Mat());
//自定义方法
Mat dilated_my;
dilated_my.create(img.rows, img.cols, CV_8UC1);
for (int i = 0; i < img.rows; ++i)
{
for (int j = 0; j < img.cols; ++j)
{
//uchar minV = 255;
uchar maxV = 0;
//遍历周围最大像素值
for (int yi = i-1; yi <= i+1; yi++)
{
for (int xi = j-1; xi <= j+1; xi++)
{
if (xi<0||xi>= img.cols|| yi<0 || yi >= img.rows)
{
continue;
}
//minV = (std::min<uchar>)(minV, img.at<uchar>(yi, xi));
maxV = (std::max<uchar>)(maxV, img.at<uchar>(yi, xi));
}
}
dilated_my.at<uchar>(i, j) = maxV;
}
}
//比较两者的结果
Mat c;
compare(dilated_cv, dilated_my, c, CMP_EQ);
//显示
imshow("原始", img);
imshow("膨胀_cv", dilated_cv);
imshow("膨胀_my", dilated_my);
imshow("比较结果", c);
waitKey();
return 0;
}
其运行结果如下所示。可以发现最后的比较结果是一张白色的图像,说明自己实现的算法是正确的。
3. 腐蚀的具体实现
同样的办法可以实现图像腐蚀的过程,只要将求局部最大值改成局部最小值就可以了。具体实现过程如下:
#include <iostream>
#include <algorithm>
#include <opencv2\opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
//从文件中读取成灰度图像
const char* imagename = "D:\\Data\\imgDemo\\lena.jpg";
Mat img = imread(imagename, IMREAD_GRAYSCALE);
if (img.empty())
{
fprintf(stderr, "Can not load image %s\n", imagename);
return -1;
}
//OpenCV方法
Mat eroded_cv;
erode(img, eroded_cv, Mat());
//自定义方法
Mat eroded_my;
eroded_my.create(img.cols, img.rows, CV_8UC1);
for (int i = 0; i < img.rows; ++i)
{
for (int j = 0; j < img.cols; ++j)
{
uchar minV = 255;
//uchar maxV = 0;
//遍历周围最大像素值
for (int yi = i-1; yi <= i+1; yi++)
{
for (int xi = j-1; xi <= j+1; xi++)
{
if (xi<0||xi>= img.cols|| yi<0 || yi >= img.rows)
{
continue;
}
minV = (std::min<uchar>)(minV, img.at<uchar>(yi, xi));
//maxV = (std::max<uchar>)(maxV, img.at<uchar>(yi, xi));
}
}
eroded_my.at<uchar>(i, j) = minV;
}
}
//比较两者的结果
Mat c;
compare(eroded_cv, eroded_my, c, CMP_EQ);
//显示
imshow("原始", img);
imshow("膨胀_cv", eroded_cv);
imshow("膨胀_my", eroded_my);
imshow("比较结果", c);
waitKey();
return 0;
}
其运行结果如下:
图像的膨胀与腐蚀——OpenCV与C++的具体实现的更多相关文章
- Atitit 图像处理—图像形态学(膨胀与腐蚀)
Atitit 图像处理-图像形态学(膨胀与腐蚀) 1.1. 膨胀与腐蚀1 1.2. 图像处理之二值膨胀及应用2 1.3. 测试原理,可以给一个5*5pic,测试膨胀算法5 1.4. Photoshop ...
- 膨胀和腐蚀 - cvErode() 和 cvDilate() 函数实现
前言 膨胀就是对图中的每个像素取其核范围内最大的那个值,腐蚀就相反.这两个操作常用来突出显示图的某个高亮部分或者昏暗部分以及去噪.本文展示两个分别对图像进行膨胀和腐蚀的例子. 膨胀和腐蚀函数 cvEr ...
- OpenCV膨胀与腐蚀
膨胀与腐蚀 本篇博客主要介绍使用OpenCV中的函数接口实现对一个图片的腐蚀或者膨胀,听起来有点像是对图像进行放大和缩小的意思,如果你也是这样认为,那我只能说你跟我一样肤浅!!在OpenCV中几乎所有 ...
- opencv之膨胀与腐蚀
腐蚀和膨胀 Erosion/Dilation erosion/dilation,用白话说,就是让图像亮的区域收缩和扩张. 原理 我们定义一个卷积核矩阵.这个矩阵可以是任何形状的,但通常而言,是矩形或者 ...
- OpenCV——图像处理入门:膨胀与腐蚀、图像模糊、边缘检测
全部外部依赖项: opencv_aruco341d.lib opencv_bgsegm341d.lib opencv_calib3d341d.lib opencv_bioinspired341d.li ...
- OpenCV膨胀和腐蚀示例代码
#include<cv.h> #include<highgui.h> int main(int argc, char** argv) { IplImage* img = cvL ...
- 学习 opencv---(9)形态学图像处理(一):膨胀和腐蚀
本篇文章中,我们一起探究了图像处理中,最基本的形态学运算--膨胀与腐蚀.浅墨在文章开头友情提醒,用人物照片做腐蚀和膨胀的素材图片得到的效果会比较惊悚,毁三观的,不建议尝试.......... 一.理论 ...
- paper 76:膨胀、腐蚀、开、闭运算——数字图像处理中的形态学
膨胀.腐蚀.开.闭运算是数学形态学最基本的变换.本文主要针对二值图像的形态学膨胀:把二值图像各1像素连接成分的边界扩大一层(填充边缘或0像素内部的孔):腐蚀:把二值图像各1像素连接成分的边界点去掉从而 ...
- 膨胀、腐蚀、开、闭(matlab实现)
膨胀.腐蚀.开.闭运算是数学形态学最基本的变换. 本文主要针对二值图像的形态学 膨胀:把二值图像各1像素连接成分的边界扩大一层(填充边缘或0像素内部的孔): B=[0 1 0 1 1 1 ...
随机推荐
- ASP.NET Core 实战:使用 NLog 将日志信息记录到 MongoDB
一.前言 在项目开发中,日志系统是系统的一个重要组成模块,通过在程序中记录运行日志.错误日志,可以让我们对于系统的运行情况做到很好的掌控.同时,收集日志不仅仅可以用于诊断排查错误,由于日志同样也是大量 ...
- 将AE开发的专题图制作功能发布为WPS
AE开发可以定制化实现ArcGIS的地理处理功能,并实际运用于其他方面的工作,有时候我们还希望将AE开发的功能发布为网络地理信息处理服务(WPS),从而能在Web端更自由便利地调用所需要的地学处理算法 ...
- spring JdbcTemplate 在itest 开源测试管理项目中的浅层(5个使用场景)封装
导读: 主要从4个方面来阐述,1:背景:2:思路:3:代码实现:4:使用 一:封装背景, 在做项目的时候,用的JPA ,有些复杂查询,比如报表用原生的JdbcTemplate ,很不方便;传参也不方便 ...
- 第四节 pandas 数据加载
pandas提供了一些用于将表格型数据读取为DataFrame对象的函数,其中read_csv和read_table这两个使用最多. #导包import pandas as pd from panda ...
- PostgreSQL(PostGIS)安装和入门的若干问题
1. 装完PostgreSQL后记得打开pgAdmin4启动一下服务器和启动一下数据库,否则PostGIS装不上. 2. pgAdmin4是网页,而3是客户端,当然都可以在File - Prefere ...
- gitbook 入门教程之 gitbook 简介
gitBook 是一个基于node.js的命令行工具,使用 github/git 和 markdown/asciiDoc 构建精美的电子书. gitbook 支持输出静态网页和电子书等多种格式,其中默 ...
- July 04th. 2018, Week 27th. Wednesday
And if you really want to see what people are, all you have to do is to look. 想真正了解他人,只需要用心看. From W ...
- C# Npoi 实现Excel与数据库相互导入
十年河东,十年河西,莫欺少年穷! NPOI支持对 Word 和 Excel 文件的操作! 针对 Word 的操作一般用于打印技术!说白了就是利用 Word 文件作为模板,生成各种不同的打印!具体用到的 ...
- 如何在你的项目中集成 CAP【手把手视频教程】
前言 之前录制过一期关于CAP的视频,但是由于当时是直播时录制的视频,背景音比较杂所以质量有点差.这次的视频没有直播,直接录制的,视频质量会好很多,第一遍录制完成之后发现播放到一半没有声音,所以又重新 ...
- Window10升级遇到大坑错误代码:0xc000000e完美解决方案
昨天忽然升级了,然后并没有立即重启更新,因为但是正在工作所以等下班回到家后就是一直提示:文件:\Windows\system32\winload.efi 错误代码:0xc000000e!!! 如下图所 ...