高斯双边滤波

news2024/11/17 8:32:41

note

原理:从空间维度和灰度维度生成两个高斯滤波器,再合成一个高斯滤波器

空间域高斯滤波器:GaussSpace(x,y) = exp(-1 * (x*x + y*y) / 2 / sigma / sigma) / 2 / PI / sigma / sigma;

灰度域(颜色域)高斯滤波器:GaussColor(x,y) = exp(-1 * (f(x,y) - g(x,y)^2) / 2 / PI / sigma / sigma) / sigma / sqrt(2*PI);

空间域高斯滤波器和颜色域高斯滤波器的合成,相乘,注意归一化

code

static void GetSapceGaussKernel2D(Mat& gaussFilter, double sigma) {
	if (gaussFilter.rows != gaussFilter.cols || gaussFilter.channels() != 1) {
		return;
	}
	if (gaussFilter.rows / 2 == 0) {
		return;
	}
	if (gaussFilter.type() != CV_64FC1) {
		gaussFilter.convertTo(gaussFilter, CV_64FC1);
	}
	
	int mid = gaussFilter.rows / 2;
	for (int x = 0; x < gaussFilter.cols; ++x) {
		for (int y = 0; y < gaussFilter.rows; ++y) {
			double l2 = (double)(mid-x)*(mid-x) + (double)(mid-y)*(mid-y);
			double val = exp((-0.5) * (l2) / sigma / sigma) / 2 / PI / sigma / sigma;
			gaussFilter.at<double>(y,x) = val;
		}
	}
}
static void GetColorGaussKernel(double color, Mat& mat, Mat& gaussFilter, double sigma = 1) {
	if (mat.type() != CV_64FC1) {
		return;
	}
	if (mat.channels() > 1) {
		return;
	}
	if (gaussFilter.rows != gaussFilter.cols || gaussFilter.channels() != 1) {
		return;
	}
	if (gaussFilter.rows / 2 == 0) {
		return;
	}
	if (gaussFilter.type() != CV_64FC1) {
		gaussFilter.convertTo(gaussFilter, CV_64FC1);
	}

	for (int r = 0; r < gaussFilter.rows; ++r) {
		for (int c = 0; c < gaussFilter.cols; ++c) {
			double val = (mat.at<double>(r,c));
			double deta = (color - val) * (color - val);
			gaussFilter.at<double>(r,c) = exp(-0.5 * deta / PI / sigma / sigma) / sigma / sqrt(2 * PI);
		}
	}
}
/*
 \brief 高斯双边滤波;
 \brief 原理:从空间维度和灰度维度生成两个高斯滤波器,再合成一个高斯滤波器;
 \brief 空间域高斯滤波器:GaussSpace(x,y) = exp(-1 * (x*x + y*y) / 2 / sigma / sigma) / 2 / PI / sigma / sigma;
 \brief 灰度域(颜色域)高斯滤波器:GaussColor(x,y) = exp(-1 * (f(x,y) - g(x,y)^2) / 2 / PI / sigma / sigma) / sigma / sqrt(2*PI);
 \brief 空间域高斯滤波器和颜色域高斯滤波器的合成,相乘,注意归一化
 \param src:原图像矩阵
 \param res:输出图像矩阵
 \param sigmaSpace:空间域sigma
 \param sigmaColor:颜色域sigma
*/
void MyGaussBilateralFilter(Mat& src, Mat& res, Size& size, double sigmaSpace = 1, double sigmaColor = 1) {
	if ((src.channels() > 1) || (res.channels() > 1)) {
		return;
	}
	if (size.width != size.height) {
		return;
	}
	if ((size.width / 2 == 0) || (size.height / 2 == 0)) {
		return;
	}
	int srcType = src.type();
	if (srcType != CV_64FC1) {
		src.convertTo(src, CV_64FC1);
	}
	Mat kernel(size, CV_64FC1);	// 总滤波器,高斯双边滤波器
	Mat spaceGauss(size, CV_64FC1);	// 空间域高斯滤波器
	int anchor = size.height / 2;	// 锚点位置
	double sumVal = 0.0;	// 归一化时求和使用
	Mat colorGauss(size, CV_64FC1);	// 颜色域高斯滤波器
	Mat mat;	// 原图根据roi矩形截取的矩阵
	Rect rec;	// roi矩形框
	Mat tmp(size, CV_64FC1);

	rec.width = size.width;
	rec.height = size.height;

	GetSapceGaussKernel2D(spaceGauss, sigmaSpace);
	sumVal = (sum(spaceGauss))[0];
	spaceGauss = spaceGauss / sumVal;	// 空间域高斯滤波器归一化
	for (int r = 0; r+size.height <= src.rows; r++) {
		for (int c = 0; c+size.width <= src.cols; c++) {
			rec.x = c;
			rec.y = r;
			
			src(rec).copyTo(mat);	// 从原图截取矩阵
			src(rec).copyTo(res(rec));
			double color = mat.at<double>(anchor,anchor);	// 锚点位置灰度值\颜色值
			GetColorGaussKernel(color, mat, colorGauss, sigmaColor);
			sumVal = (sum(colorGauss))[0];
			colorGauss = colorGauss / sumVal;	// 颜色域高斯滤波器归一化
			
			multiply(spaceGauss, colorGauss, kernel);	// 由空间域高斯滤波器和颜色域高斯滤波器获取总滤波器
			
			sumVal = (sum(kernel))[0];
			kernel = kernel / sumVal;	// 总滤波器归一化
			
			multiply(mat, kernel, tmp);
			double tmpSum = (sum(tmp))[0];
			(res(rec)).at<double>(anchor,anchor) = tmpSum;	// 锚点位置像素修改
		}
	}

	src.convertTo(src, srcType);
	res.convertTo(res, srcType);
}

test

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/737630.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android性能优化

Android性能优化 一、卡顿优化 前言&#xff1a;说到卡顿我们可能正常能想到是FPS刷新率&#xff0c;这是一个平均值&#xff0c;FPS高并不代表页面流畅&#xff0c;比如一个页面某一贞耗时了160毫秒&#xff0c;但是其他都是16毫秒&#xff0c;那么这个页面通过FPS的数据来看…

Java去重的终极指南:性能对比与高效实现

文章目录 前言一、使用Set接口下面是对几种Set实现类的简单介绍及代码示例&#xff1a;1.HashSet&#xff1a;2.LinkedHashSet&#xff1a;3.TreeSet&#xff1a; 二、使用Stream API三、其他方式1.使用Collectors.toSet()方法&#xff1a;配合Stream API的collect()方法&#…

vue3+cesium项目搭建

前言 最近需要在一个Vue3的项目中使用到cesium&#xff0c;对于一个cesium没有太多了解的人来说&#xff0c;还是比较麻烦的&#xff0c;本篇博文就将自己在这个过程踩的坑记录下来&#xff0c;有需要的可以看一下 1、vuecesium框架搭建 2、项目运行起来后&#xff0c;球体不…

展会邀请|虹科诚邀您参加7月11-13日上海慕尼黑光博会

2023年上海慕尼黑光博会与机器视觉展将于7月11-13日在上海国家会展中心隆重召开&#xff01; 慕尼黑上海光博会自2006年举办以来&#xff0c;已成为中国激光、光学、光电行业一年一度的聚会。慕尼黑上海光博会助力行业发展趋势&#xff0c; 集中展示涵盖激光器与光电子、光学与…

科技云报道:当云厂商主动拥抱生成式AI,会碰撞出什么样的火花?

科技云报道原创。 如果说这是AI大模型的时代&#xff0c;不如说是生成式AI的时代。 在AI大模型、生成式AI、ChatGPT这三者中&#xff0c;生成式AI是最广泛的概念&#xff0c;涵盖了所有使用AI生成新内容的应用。 大模型是实现生成式AI的一种方式&#xff0c;而ChatGPT则是大…

精选了20个Python实战项目(附源码),拿走就用!零基础练手不二项目!

Python是目前最好的编程语言之一。由于其可读性和对初学者的友好性&#xff0c;已被广泛使用。 那么要想学会并掌握Python&#xff0c;可以实战的练习项目是必不可少的。 接下来&#xff0c;我将给大家介绍20个非常实用的Python项目&#xff0c;帮助大家更好的学习Python。 …

电表是怎么计算度数的

电表是一种用来测量电能的仪表&#xff0c;也称为电度表、火表、电能表、千瓦小时表等。电表可以通过测量电流、电压、功率等因素来计算用户消耗的电能&#xff0c;从而确定用户应缴纳的电费。在本文中&#xff0c;我们将详细介绍电表的计算方式以及如何读取电表的度数。 一、电…

自学网络安全(黑客)

一、为什么选择网络安全&#xff1f; 这几年随着我国《国家网络空间安全战略》《网络安全法》《网络安全等级保护2.0》等一系列政策/法规/标准的持续落地&#xff0c;网络安全行业地位、薪资随之水涨船高。 未来3-5年&#xff0c;是安全行业的黄金发展期&#xff0c;提前踏入…

Android之WebView加载PDF链接预览PDF文件

文章目录 前言一、效果图二、实现步骤1.在项目main目录下新建一个assets2.新建一个js为index.js3.新建一个HTML为index.html4.xml布局4.Activity类&#xff08;kotlin&#xff09;5.Activity类&#xff08;Java&#xff09; 总结 前言 Android的webview压根就不支持加载pdf&am…

深度卷积网络的实际应用

1、三种经典的深度卷积网络 1.1、LeNet-5 使用 sigmoid 函数和 tanh 函数&#xff0c;而不是ReLu 函数&#xff0c;这篇论文中使用的正是 sigmoid 函数和 tanh 函数LeNet-5 是针对灰度图片训练的&#xff0c;所以图片的大小只有 32321 6 个 55 的过滤器&#xff0c;步幅为 …

【如何在深度学习的道路上越走越远?】

作为近几年人工智能领域的主要研究方向之一&#xff0c;深度学习主要通过构建深度卷积神经网络和采用大量样本数据作为输入&#xff0c;最终得到-一个具有强大分析能力和识别能力的模型。深度学习可以是有监督的、半监督的或无监督的。深度学习架构(例如深度神经网络、深度信念…

el-input输入框type=“number“时,禁止鼠标上下滑动改变数值

el-input输入框type"number"时&#xff0c;禁止鼠标上下滑动改变数值 解决方法&#xff1a;在el-input中添加属性设置 mousewheel.native.prevent

【达哥讲网络——只讲你不知道的】第1集:网络体系结构中的功能模块

大家好&#xff0c;经过公司缜密的思考和策划&#xff0c;【达哥讲网络——只讲你不知道的】系列连载今天正式与大家见面了。经过深入考虑&#xff0c;本系列只对一些重要的网络技术原理、网络功能实现原理及配置进行连载&#xff0c;其中会穿插一些实战案例&#xff0c;以帮助…

python与蒸散发与植被总初级生产力估算

植被总初级生产力(GPP)是指植物通过光合作用吸收的碳&#xff0c;是陆地生物圈和大气之间最大的碳通量&#xff0c;GPP的准确量化对于理解气候变化中生态系统功能、农业生产和碳循环的动态以及对气候的反馈具有重要意义 蒸散发&#xff08;Evapotranspiration&#xff0c;ET&a…

websdk上传阿里云视频完整教程

批量上传视频到阿里云 这段时间项目里有一个上传视频到阿里云的功能是我来负责写的&#xff0c;之前一直没有写过这种功能&#xff0c;感觉很难的亚子&#xff0c;但是后来仔细研究了一遍发现也没想象中那么难&#xff0c;最后经过不懈的努力也算是搞出来了哈哈哈&#xff0c;开…

集合List和Map

ArrayList底层的实现原理 初始化后ArrayList添加元素的步骤 首先计算数组的容量&#xff0c;如果当前数组已使用长度1后的大于当前的数组长度&#xff0c;则调用grow方法扩容(原来的1.5倍)&#xff0c;确保新增的数据有地方存储之后&#xff0c;则添加元素到size的位置上。返回…

docker环境下安装mysql 5.6

一、查看mgsql镜像版本 docker search mysql 二、拉取mysql镜像到本地标签为5.6版本 docker pull mysql:5.6 三、使用mysql5.6镜像创建容器(也叫运行镜像) 1.执行命令&#xff1a; docker run -p 3306:3306 --name mysql -v /haolb/mysql/conf:/etc/mysql/conf.d -v /haolb/my…

P2P、BT、ED2k、FTP、磁力链接下载到底是什么鬼?

1、HTTP/HTTPS 下载 有小伙伴会问&#xff0c;这个协议不是用来浏览网页的时候用的吗&#xff1f; 其实不然&#xff0c;用来下载文件一样可以&#xff0c;本质上都是从服务器拉取资源到本地&#xff0c;不同的是网页内容被渲染到浏览器上&#xff0c;而文件直接放在你的下载…

财富航向:企业为何急需财务管理软件?

随着市场的竞争日益激烈&#xff0c;企业对于财务数据的管理越来越重视。财务管理软件存在的好处越来越明显&#xff0c;它们可以帮助企业更好地管理财务信息并提高工作效率。 企业为什么需要财务管理软件&#xff1f; 1、方便管理财务数据 财务管理软件能够方便地管理与公司财…

教程学习:AutoQSAR

教程和练习文件从软件官网下载 内容&#xff1a; 1、拷贝教程提供的练习文件素材&#xff1a; 在软件的help中选择需要的教程&#xff0c;点击Copy to&#xff0c;可以将教程需要的文件拷贝到指定的文件夹里。点击Browse可以进行预览。 2、建立一个数值型的QSAR模型评估结合…