Opencv学习笔记(2)——模糊处理与形态学基本操作_形态学操作原理-程序员宅基地

技术标签: 视觉  c++  计算机视觉  opencv  

Opencv学习笔记(2)——模糊处理与形态学基本操作

在本节我将为大家介绍Opencv的模糊处理与形态学基本操作

一.模糊图像

1.模糊原理

1.Smooth/Blur 是图像处理中最简单和常用的操作之一。
2.使用该操作的原因之一就为了给图像预处理时候减低噪声。
3.使用Smooth/Blur操作其背后是数学的卷积计算。
在这里插入图片描述
注:h(k,l)称为卷积核或卷积算子。

图像演示:
在这里插入图片描述
假设有6x6的图像像素点矩阵。

卷积过程:6x6上面是个3x3的窗口,从左向右,从上向下移动,黄色的每个像个像素点值之和取平均值赋给中心红色像素作为它卷积处理之后新的像素值。每次移动一个像素格。

2.常见模糊方法

1.归一化盒子滤波(均值滤波)
在这里插入图片描述
将结构元素内的各像素点的均值赋予锚点,从而达到降低对比度,达到滤波降噪目的,卷积算子均为1。

2.高斯滤波
在这里插入图片描述
卷积算子取值依据正态分布函数取得。

3.中值滤波
在这里插入图片描述特点:
统计排序滤波器。
中值对椒盐噪声有很好的抑制作用。
注:中值滤波将结构元素中像素点的中值像素赋予给锚点。
椒盐噪声:形象比喻,好比一锅白粥里面洒了一些胡椒和盐粒,使得整个图像有那种极大或极小的噪声点。

4.高斯双边滤波
均值模糊无法克服边缘像素信息丢失缺陷。原因是均值滤波是基于平均权重。
高斯模糊部分克服了该缺陷,但是无法完全避免,因为没有考虑像素值的不同。
高斯双边模糊 – 是边缘保留的滤波方法,避免了边缘信息丢失,保留了图像轮廓不变。
在这里插入图片描述
高斯双边模糊考虑的结构元素像素点之间的差异,若像素点差异过大,超过规定阈值,则不做模糊操作即添加值域核。若像素点差异未超过规定阈值,则进行模糊操作,考虑空间差异,即添加空域核。空域核和值域核共同组成了高斯双边模糊的卷积核。

3.相关API函数

1.均值模糊

- blur(Mat src, Mat dst, Size(xradius, yradius), Point(-1,-1));
参数说明:
src:源图像
dst:目标图像
Size(xradius, yradius):结构元素尺寸,为奇数
Point(-1,-1):锚点位置,一般用(-1-1),表示结构元素中心位置

在这里插入图片描述

2.高斯模糊

-GaussianBlur(Mat src, Mat dst, Size(11, 11), sigmax, sigmay);
参数说明:
src:源图像
dst:目标图像
Size(xradius, yradius):结构元素尺寸,为奇数
sigmax, sigmay:影响正态分布函数的取值从而影响卷积算子的取值,可都不输入,则根据size确定取值
其中Size(x, y), x, y 必须是正数而且是奇数

3.中值模糊

medianBlur(Mat src, Mat dest, ksize);
参数说明:
src:源图像
dst:目标图像
ksize:结构元素尺寸,为奇数
中值模糊的ksize大小必须是大于1而且必须是奇数。

4.高斯双边滤波

bilateralFilter(src, dest, d=15, 150, 3);
参数说明:
 - 15 –计算的半径,半径之内的像数都会被纳入计算,如果提供-1 则根据sigma space参数取值
 - 150 – sigma color 决定多少差值之内的像素会被计算
 - 3 – sigma space 如果d的值大于0则声明无效,否则根据它来计算d值

4.程序运行

1.均值模糊与高斯模糊

#include <opencv2/opencv.hpp> 
#include <iostream> 
using namespace cv;

int main(int argc, char** argv) {
    
	Mat src, dst;
	src = imread("D:/photos/2.jpg");
	if (!src.data) {
    
		printf("could not load image...\n");
		return -1;
	}
	char input_title[] = "input image";
	char output_title[] = "blur image";
	namedWindow(input_title, CV_WINDOW_AUTOSIZE);
	namedWindow(output_title, CV_WINDOW_AUTOSIZE);
	imshow(input_title, src);

	blur(src, dst, Size(11, 11), Point(-1, -1));//均值模糊
	imshow(output_title, dst);

	Mat gblur;
	GaussianBlur(src, gblur, Size(11, 11), 11, 11);//高斯模糊,sigmax,sigay均取11
	imshow("gaussian blur", gblur);

	waitKey(0);
	return 0;
}

运行效果:
在这里插入图片描述
2.中值模糊

#include <opencv2/opencv.hpp> 
#include <iostream> 
using namespace cv;

int main(int argc, char** argv) {
    
	Mat src, dst;
	src = imread("D:/photos/21.jpg");
	if (!src.data) {
    
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);

	medianBlur(src, dst, 3);//中值模糊
	imshow("medianBlur image", dst);//去椒盐噪声效果较好
	waitKey(0);
	return 0;

}

运行效果:
在这里插入图片描述
3.高斯双边模糊

#include <opencv2/opencv.hpp> 
#include <iostream> 
using namespace cv;

int main(int argc, char** argv) {
    
	Mat src, dst;
	src = imread("D:/photos/21.jpg");
	if (!src.data) {
    
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);
	bilateralFilter(src, dst, 15, 100, 5);//双边模糊
	namedWindow("BiBlur Filter Result", CV_WINDOW_AUTOSIZE);
	imshow("BiBlur Filter Result", dst);//双边模糊

	Mat resultImg;
	Mat kernel = (Mat_<int>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);//掩膜算子,提高对比度
	filter2D(dst, resultImg, -1, kernel, Point(-1, -1), 0);
	imshow("Final Result", resultImg);//双边模糊后再提高其图像对比度
	
	waitKey(0);
	return 0;

}

运行效果:
在这里插入图片描述

二.形态学操作

1.形态学操作原理

1.形态学操作(morphology operators)-膨胀

  • 图像形态学操作 – 基于形状的一系列图像处理操作的合集,主要是基于集合论基础上的形态学数学。
  • 形态学有四个基本操作:腐蚀、膨胀、开、闭
  • 膨胀与腐蚀是图像处理中最常用的形态学操作手段。

形态学操作-膨胀
跟卷积操作类似,假设有图像A和结构元素B,结构元素B在A上面移动,其中B定义其中心为锚点,计算B覆盖下A的最大像素值用来替换锚点的像素,其中B作为结构体可以是任意形状。
在这里插入图片描述注:以结构元素中各像素点的最大值来替代锚点中的值

2.形态学操作-腐蚀
腐蚀跟膨胀操作的过程类似,唯一不同的是以最小值替换锚点重叠下图像的像素值。
在这里插入图片描述
注:以结构元素中的最小值替代锚点重叠下图像的像素值。

3.开操作- open

  • 先腐蚀后膨胀
    在这里插入图片描述
  • 可以去掉小的对象,假设对象是前景色,背景是黑色
    在这里插入图片描述
    4.闭操作-close
  • 先膨胀后腐蚀(bin2)
    在这里插入图片描述
  • 可以填充小的洞(fill hole),假设对象是前景色,背景是黑色
    在这里插入图片描述
    5.形态学梯度- Morphological Gradient
  • 膨胀减去腐蚀
    在这里插入图片描述
  • 又称为基本梯度(其它还包括-内部梯度、方向梯度)
    在这里插入图片描述
    6.顶帽 – top hat
  • 顶帽 是原图像与开操作之间的差值图像
    在这里插入图片描述
    7.黑帽-black hat
  • 黑帽是闭操作图像与源图像的差值图像
    在这里插入图片描述

2.相关API

1.创建结构元素

getStructuringElement(int shape, Size ksize, Point anchor)//创建结构元素
参数说明:
shape:结构元素形状,可选参数:MORPH_RECT(矩形)\MORPH_CROSS(十字架型) \MORPH_ELLIPSE(椭圆)
ksize:结构元素形状
anchor:锚点位置,默认是Point(-1, -1)意思就是中心像素

2.动态调整结构元素大小——TrackBar功能

createTrackbar(const String & trackbarname, const String winName,  int* value, int count, Trackbarcallback func, void* userdata=0);
参数说明:
trackbarname:工具条名称
winName:所需要用到的图像窗口明辰
value:需要动态改变的变量指针
count:需要动态变化的变量的最大值
func:拉动滑条时,所想要调用的函数名

3.膨胀函数API——dilate

 dilate(src, dst, kernel) ;
参数说明:
src:源图像
dst:目标图像
kernel:函数所需结构元素

在这里插入图片描述
4.腐蚀函数API——erode

erode(src, dst, kernel);
参数说明:
src:源图像
dst:目标图像
kernel:函数所需结构元素

在这里插入图片描述
5.其他形态学操作——morphologyEx

morphologyEx(src, dest, int OPT , kernel);
参数说明:
- Mat src – 输入图像
- Mat dest – 输出结果
- int OPT – CV_MOP_OPEN(开操作)/ CV_MOP_CLOSE(闭操作)/ CV_MOP_GRADIENT(梯度操作) / CV_MOP_TOPHAT(顶帽)/ CV_MOP_BLACKHAT(黑帽) 形态学操作类型
- kernel:函数所需结构元素
- int Iteration 迭代次数,默认是1
eg:morphologyEx(src, dest, CV_MOP_BLACKHAT, kernel)

3.程序运行

1.腐蚀与膨胀

#include <iostream> 
using namespace cv;

Mat src, dst;
char OUTPUT_WIN[] = "output image";
int element_size = 3;
int max_size = 21;
void CallBack_Demo(int, void*);
int main(int argc, char** argv) {
    
	
	src = imread("D:/photos/21.jpg");
	if (!src.data) {
    
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);

	namedWindow(OUTPUT_WIN, CV_WINDOW_AUTOSIZE);
	createTrackbar("Element Size :", OUTPUT_WIN, &element_size, max_size, CallBack_Demo);//动态调整结构元素尺寸
	CallBack_Demo(0, 0);

	waitKey(0);
	return 0;
}

void CallBack_Demo(int, void*) {
    
	int s = element_size * 2 + 1;
	Mat structureElement = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1, -1));//创建结构元素
	// dilate(src, dst, structureElement, Point(-1, -1), 1);//膨胀操作
	erode(src, dst, structureElement);//腐蚀操作
	imshow(OUTPUT_WIN, dst);
	return;
}

运行结果:
在这里插入图片描述
2.顶帽操作

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;

int main(int argc, char** argv) {
    
	Mat src, dst;
	src = imread("D:/photos/21.jpg");
	if (!src.data) {
    
		std::cout << "could not find image...\n";
		return -1;
	}
	namedWindow("input_image", CV_WINDOW_AUTOSIZE);
	imshow("input_image", src);
	char output_title[] = "morphology demo";
	namedWindow(output_title, CV_WINDOW_AUTOSIZE);
	
	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));//定义结构元素
	morphologyEx(src, dst, CV_MOP_TOPHAT, kernel);//顶帽操作,原图像与开操作(先腐蚀后膨胀)的差值
	imshow(output_title, dst);
	waitKey(0);
	return 0;
}

运行结果:
在这里插入图片描述

三.形态学操作应用举例——提取水平与垂直线

1.应用原理

图像形态学操作时候,可以通过自定义的结构元素实现结构元素
对输入图像一些对象敏感、另外一些对象不敏感,这样就会让敏
感的对象改变而不敏感的对象保留输出。通过使用两个最基本的
形态学操作 – 膨胀与腐蚀,使用不同的结构元素实现对输入图像
的操作、得到想要的结果。

  • 膨胀,输出的像素值是结构元素覆盖下输入图像的最大像素值
  • 腐蚀,输出的像素值是结构元素覆盖下输入图像的最小像素值

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.提取步骤

  • 输入图像彩色图像 imread
  • 转换为灰度图像 – cvtColor
  • 转换为二值图像 – adaptiveThreshold
  • 定义结构元素
  • 开操作 (腐蚀+膨胀)提取 水平与垂直线
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

3.程序运行

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;

int main(int argc, char** argv) {
    
	Mat src, dst;
	src = imread("D:/photos/31.png");

	if (!src.data) {
    
		std::cout << "could not find image...\n";
		return -1;
	}
	char INPUT_WIN[] = "input_image";
	char OUTPUT_WIN[] = "output_image";
	namedWindow(INPUT_WIN, CV_WINDOW_AUTOSIZE);
	imshow(INPUT_WIN, src);
	
	Mat gray_src;
	cvtColor(src, gray_src, CV_BGR2GRAY);
	imshow("gray image", gray_src);

	Mat binIma;
	adaptiveThreshold(~gray_src, binIma, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
	imshow("binary_image", binIma);

	Mat hline = getStructuringElement(MORPH_RECT, Size(src.cols / 16, 1), Point(-1, -1));
	Mat vline = getStructuringElement(MORPH_RECT, Size(1,src.rows / 16), Point(-1, -1));
	Mat kernel= getStructuringElement(MORPH_RECT, Size(5,5 ),Point(-1, -1));

	Mat temp;
	morphologyEx(binIma, dst, CV_MOP_OPEN, kernel);//开操作
	//erode(binIma, temp, hline);
	//dilate(temp, dst, hline);
	bitwise_not(dst, dst);//背景变白色
	blur(dst, dst, Size(3, 3), Point(-1, -1));
	imshow("final_image", dst);
	waitKey(0);
	return 0;
}

运行结果:
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/secretboys/article/details/111435494

智能推荐

分布式光纤传感器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告_预计2026年中国分布式传感器市场规模有多大-程序员宅基地

文章浏览阅读3.2k次。本文研究全球与中国市场分布式光纤传感器的发展现状及未来发展趋势,分别从生产和消费的角度分析分布式光纤传感器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。主要生产商包括:FISO TechnologiesBrugg KabelSensor HighwayOmnisensAFL GlobalQinetiQ GroupLockheed MartinOSENSA Innovati_预计2026年中国分布式传感器市场规模有多大

07_08 常用组合逻辑电路结构——为IC设计的延时估计铺垫_基4布斯算法代码-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏12次。常用组合逻辑电路结构——为IC设计的延时估计铺垫学习目的:估计模块间的delay,确保写的代码的timing 综合能给到多少HZ,以满足需求!_基4布斯算法代码

OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版-程序员宅基地

文章浏览阅读3.3k次,点赞3次,收藏5次。OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版

关于美国计算机奥赛USACO,你想知道的都在这_usaco可以多次提交吗-程序员宅基地

文章浏览阅读2.2k次。USACO自1992年举办,到目前为止已经举办了27届,目的是为了帮助美国信息学国家队选拔IOI的队员,目前逐渐发展为全球热门的线上赛事,成为美国大学申请条件下,含金量相当高的官方竞赛。USACO的比赛成绩可以助力计算机专业留学,越来越多的学生进入了康奈尔,麻省理工,普林斯顿,哈佛和耶鲁等大学,这些同学的共同点是他们都参加了美国计算机科学竞赛(USACO),并且取得过非常好的成绩。适合参赛人群USACO适合国内在读学生有意向申请美国大学的或者想锻炼自己编程能力的同学,高三学生也可以参加12月的第_usaco可以多次提交吗

MySQL存储过程和自定义函数_mysql自定义函数和存储过程-程序员宅基地

文章浏览阅读394次。1.1 存储程序1.2 创建存储过程1.3 创建自定义函数1.3.1 示例1.4 自定义函数和存储过程的区别1.5 变量的使用1.6 定义条件和处理程序1.6.1 定义条件1.6.1.1 示例1.6.2 定义处理程序1.6.2.1 示例1.7 光标的使用1.7.1 声明光标1.7.2 打开光标1.7.3 使用光标1.7.4 关闭光标1.8 流程控制的使用1.8.1 IF语句1.8.2 CASE语句1.8.3 LOOP语句1.8.4 LEAVE语句1.8.5 ITERATE语句1.8.6 REPEAT语句。_mysql自定义函数和存储过程

半导体基础知识与PN结_本征半导体电流为0-程序员宅基地

文章浏览阅读188次。半导体二极管——集成电路最小组成单元。_本征半导体电流为0

随便推点

【Unity3d Shader】水面和岩浆效果_unity 岩浆shader-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏18次。游戏水面特效实现方式太多。咱们这边介绍的是一最简单的UV动画(无顶点位移),整个mesh由4个顶点构成。实现了水面效果(左图),不动代码稍微修改下参数和贴图可以实现岩浆效果(右图)。有要思路是1,uv按时间去做正弦波移动2,在1的基础上加个凹凸图混合uv3,在1、2的基础上加个水流方向4,加上对雾效的支持,如没必要请自行删除雾效代码(把包含fog的几行代码删除)S..._unity 岩浆shader

广义线性模型——Logistic回归模型(1)_广义线性回归模型-程序员宅基地

文章浏览阅读5k次。广义线性模型是线性模型的扩展,它通过连接函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。广义线性模型拟合的形式为:其中g(μY)是条件均值的函数(称为连接函数)。另外,你可放松Y为正态分布的假设,改为Y 服从指数分布族中的一种分布即可。设定好连接函数和概率分布后,便可以通过最大似然估计的多次迭代推导出各参数值。在大部分情况下,线性模型就可以通过一系列连续型或类别型预测变量来预测正态分布的响应变量的工作。但是,有时候我们要进行非正态因变量的分析,例如:(1)类别型.._广义线性回归模型

HTML+CSS大作业 环境网页设计与实现(垃圾分类) web前端开发技术 web课程设计 网页规划与设计_垃圾分类网页设计目标怎么写-程序员宅基地

文章浏览阅读69次。环境保护、 保护地球、 校园环保、垃圾分类、绿色家园、等网站的设计与制作。 总结了一些学生网页制作的经验:一般的网页需要融入以下知识点:div+css布局、浮动、定位、高级css、表格、表单及验证、js轮播图、音频 视频 Flash的应用、ul li、下拉导航栏、鼠标划过效果等知识点,网页的风格主题也很全面:如爱好、风景、校园、美食、动漫、游戏、咖啡、音乐、家乡、电影、名人、商城以及个人主页等主题,学生、新手可参考下方页面的布局和设计和HTML源码(有用点赞△) 一套A+的网_垃圾分类网页设计目标怎么写

C# .Net 发布后,把dll全部放在一个文件夹中,让软件目录更整洁_.net dll 全局目录-程序员宅基地

文章浏览阅读614次,点赞7次,收藏11次。之前找到一个修改 exe 中 DLL地址 的方法, 不太好使,虽然能正确启动, 但无法改变 exe 的工作目录,这就影响了.Net 中很多获取 exe 执行目录来拼接的地址 ( 相对路径 ),比如 wwwroot 和 代码中相对目录还有一些复制到目录的普通文件 等等,它们的地址都会指向原来 exe 的目录, 而不是自定义的 “lib” 目录,根本原因就是没有修改 exe 的工作目录这次来搞一个启动程序,把 .net 的所有东西都放在一个文件夹,在文件夹同级的目录制作一个 exe._.net dll 全局目录

BRIEF特征点描述算法_breif description calculation 特征点-程序员宅基地

文章浏览阅读1.5k次。本文为转载,原博客地址:http://blog.csdn.net/hujingshuang/article/details/46910259简介 BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度..._breif description calculation 特征点

房屋租赁管理系统的设计和实现,SpringBoot计算机毕业设计论文_基于spring boot的房屋租赁系统论文-程序员宅基地

文章浏览阅读4.1k次,点赞21次,收藏79次。本文是《基于SpringBoot的房屋租赁管理系统》的配套原创说明文档,可以给应届毕业生提供格式撰写参考,也可以给开发类似系统的朋友们提供功能业务设计思路。_基于spring boot的房屋租赁系统论文