使用VC++设计程序实现K近邻中值滤波器(KNNMF)、最小均方差滤波器、矢量中值滤波算法进行滤波

VC++实现若干种图像滤波技术2

获取源工程可访问gitee可在此工程的基础上进行学习。
该工程的其他文章:
01- 一元熵值、二维熵值
02- 图像平移变换,图像缩放、图像裁剪、图像对角线镜像以及图像的旋转
03-邻域平均平滑算法、中值滤波算法、K近邻均值滤波器
04-分段线性变换,直方图均衡化、锐化处理
05-基于拉普拉斯算子、Canny的边缘检测功能、实现Otsu分割方法
06-最近邻插值,双线性插值,立方卷积插值
07-全局固定阈值分割、自适应阈值分割

文章目录

  • VC++实现若干种图像滤波技术2
    • 实验要求
    • 一、K近邻中值滤波器(KNNMF)
      • 1. K近邻中值滤波器(KNNMF)原理
      • 2. K近邻中值滤波器(KNNMF)实验代码
      • 3. K近邻中值滤波器(KNNMF)实验现象
    • 二、 最小均方差滤波器
      • 1. 最小均方差滤波器原理
      • 2. 最小均方差滤波器实验代码
      • 3. 最小均方差滤波器实验现象
    • 彩色图像矢量中值滤波算法
      • 1. 矢量中值滤波算法原理
      • 2. 矢量中值滤波算法实验代码
      • 3. 矢量中值滤波算法实验现象

实验要求

B部分:
(1)包括A部分全部要求。
(2)使用VC++设计程序:对一幅256级灰度图像,分别使用K近邻中值滤波器(KNNMF)、最小均方差滤波器进行滤波。
(3)使用VC++设计程序:对一幅24位彩色图像,使用矢量中值滤波算法进行滤波。

一、K近邻中值滤波器(KNNMF)

1. K近邻中值滤波器(KNNMF)原理

KNNMF(K-Nearest Neighbors Mean Filter)是一种非线性滤波算法,它利用每个像素点周围的 K 个最近邻居的平均值进行图像平滑。与传统的平均滤波器不同,KNNMF选择最相似的像素进行平均,这有助于在滤波的同时更好地保留图像的细节。

以下是KNNMF的基本步骤:

  1. 选择邻居数量K和滤波器大小: 确定每个像素点周围邻居的数量 K,同时选择一个滤波器的大小,通常是一个 n × n n \times n n×n 的窗口,其中 n n n为奇数。

  2. 遍历图像像素: 对于图像中的每个像素,以其为中心取一个 n × n n \times n n×n 的窗口。

  3. 计算邻居的相似度: 计算窗口内每个像素与中心像素的相似度,可以使用像素值之间的距离来衡量相似度。

  4. 选择相似度最高的 K 个邻居: 选择相似度最高的 K 个邻居进行平均。

  5. 更新像素值: 将该像素的值替换为相似度最高的 K 个邻居的平均值。

KNNMF算法相对于传统的平均滤波器,更注重选择相似度高的邻居进行平均,这有助于更好地保留图像的特征。在实际应用中,相似度的计算可以采用不同的度量方式,例如欧氏距离、余弦相似度等,具体取决于图像的特点和应用场景。

2. K近邻中值滤波器(KNNMF)实验代码

void CImageProcessingView::OnEnhanceDenoiseKNNMF()
{// 实验 图像平滑 256级灰度图像 KNNMF滤波// 参考 CImageProcessingView::OnEnhanceDenoiseAverage()//MessageBox("请在这里设计 256级灰度图像 KNNMF滤波 算法");// 获得当前文档对象CImageProcessingDoc* pDoc = GetDocument();if( pDoc->m_pDibInit->IsEmpty() ){MessageBox("图像未加载");return;}// 获得图像的基本信息int width = pDoc->m_pDibInit->GetWidth();int height = pDoc->m_pDibInit->GetHeight();int bitCount = pDoc->m_pDibInit->GetBitCount();// 程序只支持处理灰度图像if( bitCount!=8 ){MessageBox("目前只支持256级灰度图像");return;}// 将图像信息复制至 m_pDibTestpDoc->m_pDibTest->CloneDib(pDoc->m_pDibInit);//**********KNNMF滤波 算法**************//int i,j,m,n;BYTE grays[100];int graysSize = 100;int templateWidth = 3;int templateHeight = 3;int templateElementCnt = templateWidth*templateHeight;BYTE tempByte1;int kNN = 3;for(i=templateWidth/2; i<pDoc->m_pDibInit->m_lpBMIH->biWidth-templateWidth/2; i++){for(j=templateHeight/2; j<pDoc->m_pDibInit->m_lpBMIH->biWidth-templateHeight/2; j++){    memset(grays, 0, graysSize*sizeof(BYTE));for(n=0; n<templateHeight; n++){for(m=0; m<templateWidth; m++){    grays[n*templateWidth+m] = pDoc->m_pDibInit->GetPixelGray(i-templateWidth/2+m, j-templateHeight/2+n);}}BYTE centerGray = pDoc->m_pDibInit->GetPixelGray(i, j);for(m=0; m<templateElementCnt-1; m++){for(n=m+1; n<templateElementCnt; n++){if( abs(grays[m]-centerGray) > abs(grays[n]-centerGray) ){tempByte1 = grays[m];grays[m] = grays[n];grays[n] = tempByte1;}}}int midgray = 0;//中值for (m = 1; m <= kNN/2 ; m++)midgray = grays[m];pDoc->m_pDibTest->SetPixelGray(i, j, midgray);}}// 交换指针CDib* pTmpDib = pDoc->m_pDibTest;pDoc->m_pDibTest = pDoc->m_pDibInit;pDoc->m_pDibInit = pTmpDib; // 设置脏标记pDoc->SetModifiedFlag(TRUE);// 更新视图pDoc->UpdateAllViews(NULL);
}

3. K近邻中值滤波器(KNNMF)实验现象

在这里插入图片描述

二、 最小均方差滤波器

1. 最小均方差滤波器原理

最小均方差滤波是一种图像处理中常用的滤波方法,其目标是通过在像素邻域内选择合适的权重,使得滤波后的像素值与邻域内的像素值之间的均方差最小。

滤波过程中,对于每个像素,通过选取邻域内的像素进行加权平均,其中每个像素的权重由该像素与中心像素之间的差异以及一个权重函数决定。权重函数通常是关于像素差异的一个单调递减函数,以便更重视与中心像素相似的像素。

最小均方差滤波的目标函数可以表示为:

E ( u , v ) = ∑ i = − N N ∑ j = − N N w [ i , j ] ( I ( u + i , v + j ) − T ( u , v ) ) 2 E(u,v) = \sum_{i=-N}^{N} \sum_{j=-N}^{N} w[i,j](I(u+i,v+j) - T(u,v))^2 E(u,v)=i=NNj=NNw[i,j](I(u+i,v+j)T(u,v))2

其中:

  • $ (u,v) $ 是滤波后图像中的像素位置。
  • $ (i,j) $ 是邻域内像素的偏移。
  • $ I(u+i,v+j) $ 是邻域内某个像素的灰度值。
  • $ T(u,v) $ 是中心像素的灰度值。
  • $ w(i,j) $ 是权重函数。

最小均方差滤波的目标是找到使得目标函数 ( E(u,v) ) 最小的滤波器系数。这通常通过最小化目标函数的导数为零来实现。

具体实现最小均方差滤波需要对权重函数、邻域大小等进行合理的选择,以适应不同的图像处理任务。

2. 最小均方差滤波器实验代码

//**********最小均方差滤波算法**************//
int templateWidth = 3;
int templateHeight = 3;for (int i = templateWidth / 2; i < width - templateWidth / 2; i++)
{for (int j = templateHeight / 2; j < height - templateHeight / 2; j++){double minMSE = DBL_MAX; // 最小均方差初始化为最大值int optimalGray = 0;// 尝试所有可能的灰度值for (int k = 0; k <= 255; k++){double mse = 0.0;// 计算邻域内所有像素与当前灰度值的均方差for (int n = 0; n < templateHeight; n++){for (int m = 0; m < templateWidth; m++){BYTE pixelValue = pDoc->m_pDibInit->GetPixelGray(i - templateWidth / 2 + m, j - templateHeight / 2 + n);mse += pow(pixelValue - k, 2);}}mse /= (templateWidth * templateHeight); // 均方差// 更新最小均方差和对应的灰度值if (mse < minMSE){minMSE = mse;optimalGray = k;}}// 将最小均方差对应的灰度值设置为新的像素值pDoc->m_pDibTest->SetPixelGray(i, j, optimalGray);}
}

3. 最小均方差滤波器实验现象

左:加入噪声的图像
右:进行滤波后的图像

在这里插入图片描述

彩色图像矢量中值滤波算法

1. 矢量中值滤波算法原理

矢量中值滤波算法是一种基于中值运算的图像平滑处理方法。其原理可以概括为以下几个步骤:

  1. 选择邻域: 对于图像中的每个像素,定义一个邻域,包含该像素及其周围的像素。邻域的大小由窗口大小确定。

  2. 构建邻域矩阵: 将邻域内的像素值按某种顺序排列,形成一个矢量。这个矢量包含了邻域内所有像素的灰度值。

  3. 中值运算: 对构建的矢量进行中值运算,即找到矢量中的中间值。这可以通过对矢量进行排序,然后选择排序后的中间值来实现。

  4. 更新像素值: 将中值作为原始像素的新值,用于替代原始像素的灰度值。这样,经过矢量中值滤波处理后,图像中的每个像素都会得到一个中值平滑的结果。

矢量中值滤波的优点在于对图像进行平滑处理的同时能有效抑制噪声,特别适用于去除图像中的椒盐噪声等离群点。这种滤波方法在一些图像处理任务中取得了较好的效果,但也需要根据具体应用场景选择合适的窗口大小和滤波算法。

举个例子说明一下
假设我们有一个3x3的邻域矩阵,其像素值如下:

[ 10 20 15 30 25 40 35 15 20 ] \begin{bmatrix} 10 & 20 & 15 \\ 30 & 25 & 40 \\ 35 & 15 & 20 \\ \end{bmatrix} 103035202515154020

现在我们要进行矢量中值滤波,按照步骤来进行处理:

  1. 选择邻域: 我们选择一个3x3的邻域,以中心像素25为例。

  2. 构建邻域矩阵: 将邻域内的像素值按顺序排列成矢量:

$ \text{矢量} = [10, 20, 15, 30, 25, 40, 35, 15, 20] $

  1. 中值运算: 对矢量进行排序,得到:
    $\text{矢量} = [10, 15, 15, 20, 20, 25, 30, 35, 40] $

中值是排序后的中间值,即 $\text{中值} = 20 $。

  1. 更新像素值: 将中值20作为原始像素25的新值。

这样,经过矢量中值滤波处理后,中心像素的值由原来的25变为20。这个过程对图像中的每个像素都进行,以达到平滑图像的目的。这种方法在处理一些椒盐噪声等离群点时具有较好的效果。

2. 矢量中值滤波算法实验代码

//**********矢量中值滤波算法**************//int templateWidth = 3;int templateHeight = 3;int templateElementCnt = templateWidth * templateHeight;int color_r[100][100] = { 0 };int color_g[100][100] = { 0 };int color_b[100][100] = { 0 };for (int i = templateWidth / 2; i < pDoc->m_pDibInit->m_lpBMIH->biWidth - templateWidth / 2; i++){for (int j = templateHeight / 2; j < pDoc->m_pDibInit->m_lpBMIH->biWidth - templateHeight / 2; j++){// 获取当前像素点邻域的颜色信息for ( n = 0; n < templateHeight; n++)for ( m = 0; m < templateWidth; m++){RGBQUAD quad;quad = pDoc->m_pDibInit->GetPixelColor(i - templateWidth / 2 + m, j - templateHeight / 2 + n);color_r[n][m] = quad.rgbRed;color_g[n][m] = quad.rgbGreen;color_b[n][m] = quad.rgbBlue;}int sum_r = 0, sum_g = 0, sum_b = 0;for ( n = 0; n < templateHeight; n++)for ( m = 0; m < templateWidth; m++){sum_r += color_r[n][m];sum_g += color_g[n][m];sum_b += color_b[n][m];}int avl_r = sum_r / templateElementCnt;int avl_g = sum_g / templateElementCnt;int avl_b = sum_b / templateElementCnt;float min = 255;  //最小的rRGBQUAD Quad;for ( n = 0; n < templateHeight; n++)for ( m = 0; m < templateWidth; m++){// 计算中值float temp = (pow((color_r[n][m] - avl_r), 2) + pow((color_g[n][m] - avl_g), 2) + pow((color_b[n][m] - avl_b), 2)) / 2;if (temp < min){Quad.rgbRed = color_r[n][m];Quad.rgbGreen = color_g[n][m];Quad.rgbBlue = color_b[n][m];min = temp;}}pDoc->m_pDibTest->SetPixelColor(i, j, &Quad);}}

3. 矢量中值滤波算法实验现象

在这里插入图片描述

左:添加噪声的灰度图
右:使用矢量中值滤波算法后

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

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

相关文章

【Flink】容错机制

目录 1、检查点 ​编辑1.1 检查点的保存 1.1.1 周期性的触发保存 1.1.2 保存的时间点 1.1.3 时间点的保存与恢复 1.1.3.1保存 ​编辑 1.1.3.2 恢复的具体步骤: 1.2 检查点算法 1.2.1 检查点分界线(Barrier) 1.2.2 分布式快照算法(Barrier对齐的精准一次) 1.2.…

HTML简介

1&#xff0c;网页 网页的相关概念 1.1&#xff0c;什么是网页&#xff1f; 网页是构成网站的基本元素&#xff0c;它通常由图片&#xff0c;链接&#xff0c;文字&#xff0c;声音&#xff0c;视频等元素组成。其实就是一个常见以.htm或.html后缀结尾的文件&#xff0c;因此…

页面表格高度自适应

前言 现在后端管理系统主页面基本都是由三部分组成 查询条件&#xff0c;高度不固定&#xff0c;可能有的页面查询条件多&#xff0c;有的少表格&#xff0c;高度不固定&#xff0c;占据页面剩余高度分页&#xff0c;高度固定 这三部分加起来肯定是占满全屏的&#xff0c;那么我…

零基础上手,秒识别检测,IDEA研究院发布全新T-Rex模型

目标检测作为当前计算机视觉落地的热点技术之一&#xff0c;已被广泛应用于自动驾驶、智慧园区、工业检测和卫星遥感等场景。开发者在研究相关目标检测技术时&#xff0c;通常需熟练掌握图像目标检测框架&#xff0c;如通用目标检测框架 YOLO 系列&#xff0c;旋转目标检测框架…

『Nginx安全访问控制』利用Nginx实现账号密码认证登录的最佳实践

&#x1f4e3;读完这篇文章里你能收获到 如何创建用户账号和密码文件&#xff0c;并生成加密密码配置Nginx的认证模块&#xff0c;实现基于账号密码的登录验证 文章目录 一、创建账号密码文件1. 安装htpasswd工具1.1 CentOS1.2 Ubuntu 二、配置Nginx三、重启Nginx 在Web应用程…

SpringAMQP入门案例——发送消息

依赖 <!--SpringAMQP起步依赖--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </dependency> yml配置文件 自行修改 spring:rabbitmq:host: 192.168.220.130 # …

CyclicBarrier实战应用——批量数据多线程协调异步处理(子线程执行事务回滚)

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; CountDownLatch实战应用——批量数据多线程协调异步处理(子线程执行事务…

【源码篇】基于SpringBoot+thymeleaf实现的大学生自习室座位预定系统

文章目录 系统介绍管理员学生 技术选型成果展示账号地址及其他说明 系统介绍 基于SpringBootthymeleaf实现的大学生自习室座位预定系统是为座位管理打造的一款在线管理平台&#xff0c;它可以实时完成信息处理&#xff0c;使其系统化和规范化。 系统功能说明 管理员 1、用户…

误用STM32串口发送标志位 “USART_FLAG_TXE” “USART_FLAG_TC”造成的BUG

当你使用串口发送数据时是否出现过这样的情况&#xff1a; 1.发送时第一个字节丢失。 2.发送时出现莫名的字节丢失。 3.各种情况字节丢失。 1.先了解一下串口发送的流程图&#xff08;手动描绘&#xff09;&#xff1a; 可以假想USART_FLAG_TXE是用于检测"弹仓"&…

【STM32F103】GPIO通用输入输出口

GPIO 简介 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口是微控制器&#xff08;MCU&#xff09;必备的片上外设&#xff0c;可以实现微控制器与外部设备的数字交换。 STM32F103系列的芯片最多可以提供112个多功能双向IO引脚&#xff0c;但是显然…

机器学习-回归问题(Regression)

前言 与KNN分类任务预测的输出为离散型不同. 在机器学习中&#xff0c;回归任务是用于预测连续数值型变量的任务。回归任务在很多领域都有着广泛的应用. 回归问题求解 在一个回归问题中&#xff0c;很显然模型选择和好坏会直接关系到将来预测结果的接近程度&#xff0c;举个…

规则引擎专题---2、开源规则引擎对比

开源规则引擎 开源的规则引擎整体分为下面几类&#xff1a; 通过界面配置的成熟规则引擎&#xff0c;这种规则引擎相对来说就比较重&#xff0c;但功能全&#xff0c;比较出名的有:drools, urule。 基于jvm脚本语言&#xff0c;互联网公司会觉得drools太重了&#xff0c;然后…

常见的AI安全风险(数据投毒、后门攻击、对抗样本攻击、模型窃取攻击等)

文章目录 数据投毒&#xff08;Data Poisoning&#xff09;后门攻击&#xff08;Backdoor Attacks&#xff09;对抗样本攻击&#xff08;Adversarial Examples&#xff09;模型窃取攻击&#xff08;Model Extraction Attacks&#xff09;参考资料 数据投毒&#xff08;Data Poi…

GEE:不同方向的线性检测算子

作者:CSDN @ _养乐多_ 本文将介绍在 Google Earth Engine(GEE)平台上,使用不同方向的线性检测算子进行卷积操作的代码框架、核心函数和多种卷积核,比如 E-W、NE-SW、N-S、NW-SE 方向检测算子等。 结果如下图所示, 文章目录 一、定向检测算子二、完整代码三、代码链接一…

JAVA代码优化:CommandLineRunner(项目启动之前,预先加载数据)

CommandLineRunner接口是Spring Boot框架中的一个接口&#xff0c;用于在应用程序启动后执行一些特定的代码逻辑。它是一个函数式接口&#xff0c;只包含一个run方法&#xff0c;该方法在应用程序启动后被自动调用。可以帮助我们在应用程序启动后自动执行一些代码逻辑&#xff…

Java(十)(网络编程,UDP,TCP)

目录 网络编程 两种软件架构 网络通信的三要素 IP IPv4的地址分类 特殊IP 端口号 协议 用UDP协议发送数据 用UDP接收数据 TCP接收和发送数据 TCP通信--支持与多个客户端同时通信 网络编程 可以让设备中的程序与网络上其他设备的程序进行数据交互(实现网络通信) 两…

【面试经典150 | 二分查找】搜索二维矩阵

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;二分查找 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等…

Fiddler抓包工具之fiddler的composer可以简单发送http协议的请求

一&#xff0c;composer的详解 右侧Composer区域&#xff0c;是测试接口的界面&#xff1a; 相关说明&#xff1a; 1.请求方式&#xff1a;点开可以勾选请求协议是get、post等 2.url地址栏&#xff1a;输入请求的url地址 3.请求头&#xff1a;第三块区域可以输入请求头信息…

springmvc+mybatis+mysql8+idea+jqgrid前端

一、背景 主要是为了学习jqgrid前端技术&#xff0c;熟练一下前后端交互数据 二、效果图 访问地址&#xff1a;http://localhost:8080/cr/views/jqGridDemo.jsp 三、代码展示 控制层JqGridController.java Controller RequestMapping("/jqgrid") public class Jq…

拥抱变化,良心AI工具推荐

文章目录 &#x1f4a5; 简介&#x1f344; 工具介绍&#x1f353; 功能特点&#x1f957; 使用场景&#x1f389; 用户体验&#x1f9e9; 下载地址&#x1f36d; 总结 &#x1f4a5; 简介 我是一名资深程序员&#xff0c;但薪资缺对不起资深两个字&#xff0c;为了生存&#x…