【C++】图像模糊处理题目详解与实现


在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C++

文章目录

  • 💯前言
  • 💯题目描述
    • 题目内容
    • 输入格式
    • 输出格式
    • 示例
      • 输入:
      • 输出:
  • 💯题目分析
    • 问题拆解
  • 💯我的做法
    • 代码实现
    • 代码分析
  • 💯老师的做法
    • 代码实现
    • 代码分析
  • 💯两种实现的对比
  • 💯相关概念拓展
    • 1. 四舍五入的实现
    • 2. 二维数组的边界处理
  • 💯优化建议
  • 💯小结


在这里插入图片描述


💯前言

  • 在C++程序设计学习中,处理二维数组与图像问题是一个重要的实践内容,能够帮助我们熟悉矩阵操作、边界条件处理以及浮点运算等核心技能。本篇文章将以一个图像模糊处理的题目为切入点,详细剖析题目背景、解题思路与两种代码实现(我的做法与老师的代码),并对两者进行深入比较与优化。同时,还将补充相关概念的详细解析,以期让读者对问题有全面而深入的理解。
    C++ 参考手册
    在这里插入图片描述

💯题目描述

题目来源于一个二维矩阵的图像模糊处理问题,其具体要求如下:
B2108 图像模糊处理
在这里插入图片描述

题目内容

给定一个 nm 列的图像各像素点的灰度值,要求用如下方法对其进行模糊处理:

  1. 四周外围的像素点灰度值保持不变。
  2. 中间像素点新灰度值为该像素点及其上下左右相邻四个像素点灰度值的平均(包含到最近的整数)。

输入格式

  • 第一行包含两个整数 nm,表示图像像素点的行数和列数。 1 ≤ n , m ≤ 100 1 \leq n, m \leq 100 1n,m100
  • 接下来 n 行,每行包含 m 个整数,表示图像像素的灰度值。
  • 每个整数为 0 ∼ 255 0 \sim 255 0255 之间的值,相邻两个整数之间用单个空格隔开。

输出格式

  • n 行,每行 m 个整数,为模糊处理后的图像。相邻两个整数之间用单个空格隔开。

示例

输入:

4 5
100 100 100 100 50
50 50 50 50 50
50 50 100 200 200
100 100 50 50 100

输出:

100 100 100 100 50
50 80 80 60 50
50 80 90 90 200
100 100 50 50 100

💯题目分析

问题拆解

要解决这个问题,我们需要完成以下任务:

  1. 边界处理:外围像素点保持原始灰度值不变。
  2. 中间像素模糊处理
    • 计算公式为:
      模糊后的灰度值 = 当前像素点灰度值 + 上下左右相邻像素点灰度值 5 。 \text{模糊后的灰度值} = \frac{\text{当前像素点灰度值} + \text{上下左右相邻像素点灰度值}}{5}。 模糊后的灰度值=5当前像素点灰度值+上下左右相邻像素点灰度值
    • 结果需“包含到最近的整数”。

💯我的做法

以下是我实现该题目的代码。

代码实现

#include <iostream>
#include <cmath>
using namespace std;int arr1[105][105];
int arr2[105][105];int main()
{int n, m;cin >> n >> m;for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){cin >> arr1[i][j];}} for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){if(i == 0 || i == n - 1 || j == 0 || j == m - 1)arr2[i][j] = arr1[i][j];else{double result = (arr1[i - 1][j] + arr1 [i + 1][j] + arr1[i][j - 1] + arr1[i][j + 1] + arr1[i][j]) / 5.0;arr2[i][j] = (int)round(result);}}} for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){cout << arr2[i][j] << " ";}cout << endl;} return 0;	
} 

在这里插入图片描述

在这里插入图片描述

代码分析

  1. 输入部分
    • 通过两层循环读取矩阵的灰度值到 arr1 中。
  2. 模糊处理
    • 使用两层循环遍历矩阵的每一个像素点。
    • 边界点:直接将原始值赋值到结果矩阵 arr2 中。
    • 中间点:计算该点及其上下左右四个点的平均值,使用 round() 函数进行四舍五入,然后赋值到 arr2 中。
  3. 输出部分
    • 遍历 arr2 矩阵,将每行数据输出。

💯老师的做法

下面是老师的实现代码。

代码实现

#include <iostream>
using namespace std;const int N = 110;
int arr1[N][N]; // 旧数据
int arr2[N][N]; // 新数据
int n, m;int main() {cin >> n >> m;int i = 0;int j = 0;for (i = 0; i < n; i++) {for (j = 0; j < m; j++) {cin >> arr1[i][j];arr2[i][j] = arr1[i][j];}}for (i = 1; i < n - 1; i++) {for (j = 1; j < m - 1; j++) {arr2[i][j] = (arr1[i][j] + arr1[i - 1][j] + arr1[i + 1][j] + arr1[i][j - 1] + arr1[i][j + 1]) / 5.0 + 0.5;}}for (i = 0; i < n; i++) {for (j = 0; j < m; j++) {cout << arr2[i][j] << " ";}cout << endl;}return 0;
}

在这里插入图片描述

在这里插入图片描述

代码分析

  1. 边界初始化
    • 老师直接在输入矩阵时,将 arr1 的数据赋值给 arr2,实现了边界初始化。
  2. 模糊处理逻辑
    • 对中间像素点进行模糊计算时,将平均值的浮点结果直接加上 0.5,然后用强制类型转换 (int) 实现四舍五入。
  3. 输出部分
    • 同样使用两层循环输出结果矩阵 arr2

💯两种实现的对比

对比点我的做法老师的做法
边界处理使用条件语句单独处理边界像素。在输入时直接完成边界初始化。
模糊计算使用 round() 函数实现四舍五入。通过 + 0.5 与强制类型转换 (int) 实现四舍五入。
代码结构边界处理与模糊处理分开,逻辑清晰但略显冗余。将边界初始化与输入结合,更加简洁。
浮点运算使用浮点除法后取整,增加了一些计算开销。避免了额外函数调用,更高效。

💯相关概念拓展

1. 四舍五入的实现

两种方法:

  1. 使用数学库中的 round() 函数:
    • 直接返回最近的整数。
  2. 手动实现:
    • 对浮点数加 0.5,然后强制类型转换为整数。
    • 更高效,避免额外函数调用。

2. 二维数组的边界处理

在处理二维数组时,常见的边界条件有:

  • 边界像素点保持不变。
  • 超出边界时采取特殊值(例如零填充)。
  • 通过循环边界实现(例如,最后一行的邻居是第一行)。

💯优化建议

在已有代码的基础上,提出以下优化:

  1. 避免浮点运算

    • 使用整数除法和四舍五入的等效操作:
      arr2[i][j] = (arr1[i][j] + arr1[i - 1][j] + arr1[i + 1][j] + arr1[i][j - 1] + arr1[i][j + 1] + 2) / 5;
      
    • +2 是为了模拟加 0.5 的效果,且无需浮点运算。
  2. I/O 优化

    • 如果数据量较大,可以使用更高效的输入输出方法:
      ios::sync_with_stdio(false);
      cin.tie(nullptr);
      

💯小结

  • 在这里插入图片描述
    通过本文对图像模糊处理问题的详解,我们不仅学习了如何处理二维数组,还深入对比了两种实现方式,掌握了边界处理、四舍五入、浮点运算优化等技巧。这些经验可迁移至其他矩阵操作类题目中,为复杂问题的求解提供清晰的思路和工具。希望这篇文章对你有所启发!

在这里插入图片描述


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

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

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

相关文章

在 Ubuntu 22.04 上部署 AppArmor 应用安全教程

在这篇教程中&#xff0c;我们将为你设置 AppArmor 以增强应用程序的安全性。 AppArmor 是一个 Linux 安全模块&#xff0c;允许你限制各个程序的功能。通过强制执行强制访问控制策略&#xff0c;AppArmor 增强了你的应用程序和系统的安全性。 AppArmor 是一个易于使用的 Lin…

Nginx:动静分离

什么是动静分离? 动静分离 是指将网站中的静态资源(如图片、样式表、脚本等)和动态内容(如 PHP、Python、Node.js 等后端生成的内容)分开部署和处理。这样做的好处是可以利用不同的服务器或缓存策略来优化不同类型的资源。 动静分离的好处 提高性能:静态资源可以直接从…

每天40分玩转Django:Django插件开发

Django插件开发 一、插件开发概述表 阶段主要任务技术要点难度准备工作项目结构设计、环境配置项目布局、setup.py★★★☆☆开发实现功能开发、测试编写Django AppConfig、Signals★★★★☆文档编写API文档、使用说明Markdown、reStructuredText★★★☆☆发布部署PyPI打包…

什么是TDD测试驱动开发(Test Driven Development)?

什么是测试驱动开发&#xff1f; 软件开发团队通常会编写自动化测试套件来防止回归。这些测试通常是在编写应用程序功能代码之后编写的。我们将采用另一种方法&#xff1a;在实现应用程序代码之前编写测试。这称为测试驱动开发 (TDD)。 为什么要应用 TDD&#xff1f;通过在实…

后台管理系统用户退出登录方案实现

退出登录一直是一个通用的前端实现方案&#xff0c;对于退出登录而言&#xff0c;它的触发时机一般有两种&#xff1a; 1. 用户主动退出&#xff0c;即用户点击登录按钮之后退出&#xff1b; 2. 用户被动退出&#xff0c;Token过期或被 其他人"顶下来" 时退出&…

文献分享:BGE-M3——打通三种方式的嵌入模型

文章目录 1. \textbf{1. } 1. 背景与导论 1.1. \textbf{1.1. } 1.1. 研究背景 1.2. \textbf{1.2. } 1.2. 本文的研究 1.3. \textbf{1.3. } 1.3. 有关工作 2. M3-Embedding \textbf{2. M3-Embedding} 2. M3-Embedding 2.1. \textbf{2.1. } 2.1. 模型核心: 混合检索方式 2.1.1. \…

毛泽东思想概论

马克思主义中国化时代化的内涵&#xff1f; 马克思主义中国化时代化的科学内涵集中体现为三个“就是”&#xff1a;①解决中国问题&#xff1a;就是运用马克思主义的立场、观点、方法&#xff0c;观察时代、把握时代、引领时代&#xff0c;解决中国革命、建设、改革中的实际问…

Hadoop•FinalShell连接VMware免密登录

听说这是目录哦 FinalShell连接VMware&#x1f324;️解决重连失效FinalShell的使用 免密登录⛈️能量站&#x1f61a; FinalShell连接VMware&#x1f324;️ 保持虚拟机的开机状态&#xff0c;打开FinalShell&#xff0c;如果虚拟机关机或者挂起&#xff0c;连接就会断开。 …

一个在ios当中采用ObjectC和opencv来显示图片的实例

前言 在ios中采用ObjectC编程利用opencv来显示一张图片&#xff0c;并简单绘图。听上去似乎不难&#xff0c;但是实际操作下来&#xff0c;却不是非常的容易的。本文较为详细的描述了这个过程&#xff0c;供后续参考。 一、创建ios工程 1.1、选择ios工程类型 1.2、选择接口模…

《Rust权威指南》学习笔记(五)

高级特性 1.在Rust中&#xff0c;unsafe是一种允许绕过Rust的安全性保证的机制&#xff0c;用于执行一些Rust默认情况下不允许的操作。unsafe存在的原因是&#xff1a;unsafe 允许执行某些可能被 Rust 的安全性检查阻止的操作&#xff0c;从而可以进行性能优化&#xff0c;如手…

【顶刊TPAMI 2025】多头编码(MHE)之极限分类 Part 3:算法实现

目录 1 三种多头编码&#xff08;MHE&#xff09;实现1.1 多头乘积&#xff08;MHP&#xff09;1.2 多头级联&#xff08;MHC&#xff09;1.3 多头采样&#xff08;MHS&#xff09;1.4 标签分解策略 论文&#xff1a;Multi-Head Encoding for Extreme Label Classification 作者…

行为模式1.模板方法模式

行为型模式 模板方法模式&#xff08;Template Method Pattern&#xff09;命令模式&#xff08;Command Pattern&#xff09;迭代器模式&#xff08;Iterator Pattern&#xff09;观察者模式&#xff08;Observer Pattern&#xff09;中介者模式&#xff08;Mediator Pattern…

PHP语言的计算机基础

计算机基础与PHP语言入门 在当今信息技术高速发展的时代&#xff0c;计算机已经成为我们日常生活中不可或缺的重要工具。学习计算机基础知识&#xff0c;不仅能增强我们对信息技术的理解&#xff0c;还会为我们后续学习编程语言打下良好的基础。本文将以PHP语言为切入点&#…

docker中使用Dockerfile设置Volume挂载点

关于在docker中如何使用Volume&#xff0c;可以参考文章&#xff1a; docker中使用Volume完成数据共享-CSDN博客 如果想在生成docker镜像的时候设置好挂载点&#xff0c;而不是在运行镜像生成容器时生成。 下面以自建一个tomcat镜像为例&#xff0c;演示如何在生成镜像时设置…

在Mac电脑上搭建Gradle

1. 检查是否已安装Homebrew 打开终端&#xff0c;输入以下命令检查Homebrew是否已安装&#xff1a; brew -v如果显示版本号&#xff0c;则表示已安装。如果未安装&#xff0c;请运行以下命令安装Homebrew&#xff1a; /bin/bash -c "$(curl -fsSL https://raw.githubus…

springboot548二手物品交易boot代码(论文+源码)_kaic

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统二手物品交易信息管理难度大&#xff0c;容错率低&#x…

仿生的群体智能算法总结之三(十种)

群体智能算法是一类通过模拟自然界中的群体行为来解决复杂优化问题的方法。以下是30种常见的群体智能算法,本文汇总第21-30种。接上文 : 编号 算法名称(英文) 算法名称(中文) 年份 作者 1 Ant Colony Optimization (ACO) 蚁群优化算法 1991 Marco Dorigo 2 Particle Swar…

通往O1开源之路

“Scaling of Search and Learning: A Roadmap to Reproduce o1 from Reinforcement Learning Perspective”由复旦大学和上海人工智能实验室的研究者撰写。该论文从强化学习视角出发&#xff0c;深入分析了实现类似OpenAI o1模型性能的路线图&#xff0c;聚焦于策略初始化、奖…

AF3 AtomAttentionEncoder类的init_pair_repr方法解读

AlphaFold3 的 AtomAttentionEncoder 类中,init_pair_repr 方法方法负责为原子之间的关系计算成对表示(pair representation),这是原子转变器(atom transformer)模型的关键组成部分,直接影响对蛋白质/分子相互作用的建模。 init_pair_repr源代码: def init_pair_repr(…

DS复习提纲模版

数组的插入删除 int SeqList::list_insert(int i, int item) { //插入if (i < 1 || i > size 1 || size > maxsize) {return 0; // Invalid index or list is full}for (int j size-1; j > i-1; j--) { // Shift elements to the rightlist[j1] list[j];}li…