(十)图像的梯度倒数加权平滑

环境:Windows10专业版 + IDEA2021.2.3 + jdk11.0.1 + OpenCV-460.jar

系列文章:

(一)Python+GDAL实现BSQ,BIP,BIL格式的相互转换

(二)BSQ,BIL,BIP存储格式的相互转换算法

(三)单波段图像的伪彩色合成:密度分割(含介绍OpenCV中的Mat类)

(四)图像的%2线性拉伸

(五)图像的标准假彩色合成

(六)图像的直方图均衡化

(七)图像的均值滤波

(八)图像的中值滤波

(九)图像的高斯低通滤波

(十)图像的梯度倒数加权平滑

(十一)图像的罗伯特梯度锐化

(十二)图像的Sobel梯度锐化

(十三)图像的拉普拉斯梯度锐化

目录

一、梯度倒数加权简介

二、算法流程

三、代码实现

四、实验结果

1、读入的图像

2、经过梯度倒数加权平滑后的图像


一、梯度倒数加权简介

图像的梯度倒数加权平滑是一种基于像素邻域梯度信息的数字图像处理技术,主要用于降低图像噪声同时保留边缘特征

以下是关于图像梯度倒数加权平滑的具体介绍:

1、基本原理:在一幅图像中,相邻区域之间的变化通常大于区域内部的变化。在同一区域内,中心像素的变化小于边缘像素的变化。图像梯度反映了这种变化率,即在图像变化缓慢的区域梯度值较小,而在变化快的区域梯度值较大。梯度倒数加权平滑正是利用这个原理,对图像中的像素进行加权平均,使得变化平缓区域的像素获得较大的平滑效果,而变化剧烈的边缘区域则保持原有特征。

2、应用范围:由于其在去噪的同时能够有效保留图像边缘,梯度倒数加权平滑广泛应用于图像预处理、医学成像、遥感图像分析等领域。

3、注意事项:在进行梯度倒数加权平滑时,应注意选择适当的窗口大小和权重函数,以达到最佳的去噪效果和边缘保持能力。

4、与其他方法对比:与直方图修正法等其他图像增强技术相比,梯度倒数加权平滑更注重于局部特征的保持,而不是全局的对比度调整。

5、数学基础:从数学角度来看,图像可以被视为一个二维离散函数。图像梯度是一个矢量,表示函数在某点沿着该方向变化最快,变化率为梯度的模。在数字图像处理中,通常通过计算像素点的偏微分来估计图像梯度。

图像的梯度倒数加权平滑是一种有效的图像去噪技术,它通过对图像局部区域进行加权平均来降低噪声,同时保留重要的边缘信息。

二、算法流程

(以单波段图像为例) 

1、利用OpenCV读入图像,将像素存储在数组里

2、边缘像素不做处理,以3×3模板为例,模板为

 规定w( i ,j ) = 1/2,其余系数之和为1/2,定义除中心像素外的其他系数为

 对于中心像素与其他像素的差值为0的情况,用如下公式:

 通过下面公式将w总和归一化为1/2:

 3、进行卷积运算:

新像素=0.022×21+0.218×30+0.073×28+0.031×24+0.5×31+0.027×23+0.044×36+0.031×38+0.054×27≈30

 4、将经过梯度倒数加权平滑后的像素值存入数组合成图像并存储

三、代码实现

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;/*** @Author: HNUST_jue_chen* @Date: 2022/11/02/ 19:40* @Attention: 转载, 引用请注明出处*/public class GradientReciprocalWeighting {//加载本地动态链接库static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}//梯度倒数加权public Mat gradientReciprocalWeightingFilter(String path) {//使用Mat类存储图像信息Mat mat = Imgcodecs.imread(path);//图像的大小int rows = mat.rows();int cols = mat.cols();//获得原图像像素数组int[][] mat_arr = new int[rows][cols];for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {mat_arr[i][j] = (int) mat.get(i, j)[0];}}//用3×3窗口进行梯度倒数加权平滑int[][] mat_arr_gradientReciWeight = new int[rows][cols];for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {//处理非边缘像素if (i != 0 && i != rows - 1 && j != 0 && j != cols - 1) {//3×3窗口的原始图像梯度倒数double[][] temp = new double[3][3];temp[0][0] = judgment(mat_arr[i - 1][j - 1] , mat_arr[i][j]);temp[0][1] = judgment(mat_arr[i - 1][j] , mat_arr[i][j]);temp[0][2] = judgment(mat_arr[i - 1][j + 1] , mat_arr[i][j]);temp[1][0] = judgment(mat_arr[i][j - 1] , mat_arr[i][j]);temp[1][1] = 0;temp[1][2] = judgment(mat_arr[i][j + 1] , mat_arr[i][j]);temp[2][0] = judgment(mat_arr[i + 1][j - 1] , mat_arr[i][j]);temp[2][1] = judgment(mat_arr[i + 1][j] , mat_arr[i][j]);temp[2][2] = judgment(mat_arr[i + 1][j + 1] , mat_arr[i][j]);//得到梯度倒数之和double temp_sum = 0.0;for (double[] m : temp) {for (double n : m) {temp_sum += n;}}//归一化后的梯度权重矩阵double[][] temp_normalize = new double[3][3];for (int p = 0; p < temp_normalize.length; p++) {for (int q = 0; q < temp_normalize[0].length; q++) {if (p == 1 && q == 1) {temp_normalize[p][q] = 0.5;} else {temp_normalize[p][q] = temp[p][q] / (2 * temp_sum);}}}//得到新中心像素mat_arr_gradientReciWeight[i][j] = (int) (temp_normalize[0][0] * mat_arr[i - 1][j - 1]+ temp_normalize[0][1] * mat_arr[i - 1][j]+ temp_normalize[0][2] * mat_arr[i - 1][j + 1]+ temp_normalize[1][0] * mat_arr[i][j - 1]+ temp_normalize[1][1] * mat_arr[i][j]+ temp_normalize[1][2] * mat_arr[i][j + 1]+ temp_normalize[2][0] * mat_arr[i + 1][j - 1]+ temp_normalize[2][1] * mat_arr[i + 1][j]+ temp_normalize[2][2] * mat_arr[i + 1][j + 1]);} else {    //处理边缘像素mat_arr_gradientReciWeight[i][j] = mat_arr[i][j];}}}//合成图像Mat mat_gradientReciWeight = new Mat(rows, cols, CvType.CV_32SC1);//将像素放入图像for (int i = 0; i < rows; i++) {//一次放入一行像素值mat_gradientReciWeight.put(i, 0, mat_arr_gradientReciWeight[i]);}return mat_gradientReciWeight;}//进行判断中心像素与边缘像素的差值是否为0public static double judgment(int a, int b) {double c;if (a - b == 0) {c = 1.0;} else {c = 1.0 / (Math.abs(a - b));}return c;}public static void main(String[] args) {GradientReciprocalWeighting grw = new GradientReciprocalWeighting();Mat mat = grw.gradientReciprocalWeightingFilter("D:\\Project\\IDEA_Project\\RS01\\src\\rs01\\img\\2_gray1.png");//将经过梯度倒数加权平滑后的图像写入文件Imgcodecs.imwrite("D:\\Project\\IDEA_Project\\RS01\\src\\rs01\\img\\2_gray1_grw.png", mat);}
}

四、实验结果

1、读入的图像

2、经过梯度倒数加权平滑后的图像

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务demo(三)nacosfeign

一、feign使用 1、集成方法 1.1、pom consumer添加依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>2.2.6.RELEASE</version></dependency&…

STM32G473之flash存储结构汇总

STM32G4系列单片机&#xff0c;为32位的微控制器&#xff0c;理论上其内部寄存器地址最多支持4GB的命名及查找&#xff08;2的32次方&#xff0c;地址命名为0x00000000至0xFFFFFFFF&#xff09;。STM32官方对4GB的地址存储进行编号时&#xff0c;又分割成了8个block区域&#x…

Unity 渲染

渲染的三个阶段 1&#xff1a;应用阶段 1.1 数据的准备 遮挡剔除&#xff0c;层级剔除。 渲染顺序&#xff0c;UI在Herachy窗口按照层级渲染&#xff0c;其余物体由大概按照先近后远。 打包渲染数据发送给显存&#xff0c;主要包括有模型信息&#xff0c;变换矩阵&#xff0c…

学浪m3u8视频解密

学浪视频在网页上并不是mp4&#xff0c;而是以m3u8进行传输&#xff0c;使用m3u8可以有效解决服务器的压力&#xff0c;而且不仅仅是m3u8&#xff0c;还加密了key&#xff0c;需要逆向key算法得到真实key 下面是学浪m3u8视频解密的工具&#xff0c;全程自动化&#xff0c;不需…

【VMware Workstation】公司所有主机和虚拟机ip互通,以及虚拟机目录迁移

文章目录 1、场景2、环境3、实战3.1、所有主机和虚拟机ip互通Stage 1 : 【虚拟机】设置为桥接模式Stage 2 : 【虚拟机】设置ipStage 3 : 【路由器】ARP 静态绑定MACStage 3-1 ping 路由器 ipStage 3-2 【静态绑定】虚拟机查看mac地址Stage 3-3 【静态绑定】路由器ARP 静态绑定 …

CSS(一)---【CSS简介、导入方式、八种选择器、优先级】

零.前言 本系列适用于零基础小白&#xff0c;亦或是初级前端工程师提升使用。 知识点较为详细&#xff0c;如果追求非常详细&#xff0c;请移步官方网站或搬运网站。 1.CSS简介 CSS全称&#xff1a;“Cascading Style Sheets”&#xff0c;中文名&#xff1a;“层叠样式表”…

基于js css的瀑布流demo

要实现照片按照瀑布流展示&#xff0c;写个小demo&#xff0c;记录下。 瀑布流实现思路如下&#xff1a; CSS 弹性布局对 3 列按横向排列&#xff0c;对每一列内部按纵向排列 html代码&#xff1a; <div class"content"></div> css代码&#xff1a; …

力扣 718. 最长重复子数组

题目来源&#xff1a;https://leetcode.cn/problems/maximum-length-of-repeated-subarray/description/ C题解&#xff08;思路来源代码随想录&#xff09;&#xff1a;动态规划 确定dp数组&#xff08;dp table&#xff09;以及下标的含义。dp[i][j] &#xff1a;以下标i - …

IDEA跑Java后端项目提示内存溢出

要设置几个地方&#xff0c;都试一下吧&#xff1a; 1、默认是700&#xff0c;我们设置大一点&#xff08;上次配置了这儿就解决了&#xff09; 2、 3、 4、-Xmx4g

Linux基础篇:解析Linux命令执行的基本原理

Linux 命令是一组可在 Linux 操作系统中使用的指令&#xff0c;用于执行特定的任务&#xff0c;例如管理文件和目录、安装和配置软件、网络管理等。这些命令通常在终端或控制台中输入&#xff0c;并以文本形式显示输出结果。 Linux 命令通常以一个或多个单词的简短缩写或单词…

前端-深入探讨网络面试题

第一关 请求-文件、数据、连接 文件类的请求&#xff1a;加载HTMl、CSS 数据&#xff1a; ajax请求&#xff08;基于HTTP&#xff0c;HTTP基于TCP&#xff09;&#xff0c;如何建立连接的&#xff08;三次握手&#xff0c;为什么不是两次或者四次&#xff09;&#xff0c;sock…

FL Studio21中文版包含哪些强大的内置工具?有哪些新功能

FL Studio21中文版是一款功能强大的数字音频工作站&#xff08;DAW&#xff09;&#xff0c;专为音乐制作人、作曲家和声音工程师设计。该版本提供了直观且易于使用的界面&#xff0c;让用户能够快速上手并创作出专业水准的音乐作品。无论是新手还是专业音乐制作人&#xff0c;…