【C++】B2108 图像模糊处理

news2025/1/9 10:47:21

在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: 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.coloradmin.cn/o/2273739.html

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

相关文章

selenium+pyqt5自动化工具总结

说明&#xff1a;本工具是&#xff0c;操作外部google浏览器、selenium是无法操作qt界面中嵌套的浏览器的&#xff0c; 工具在后面 1. 代码结构 pycharm打开的文件下&#xff0c;再写一个子文件&#xff0c;文件导入的时候把子文件名带上 这样就可以在 外层使用命令 pyinst…

经典多模态模型CLIP - 直观且详尽的解释

对比语言-图像预训练&#xff08;CLIP&#xff09;&#xff0c;这是一种创新的多模态建模策略&#xff0c;能够创建视觉和语言的联合表示。CLIP 的效果非常出色&#xff0c;可以用于构建高度特定且性能卓越的分类器&#xff0c;而无需任何训练数据。本文将深入探讨其理论基础&a…

新时期下k8s 网络插件calico 安装

1、k8s master节点初始化完毕以后一直处于notreadey状态&#xff0c;一直怀疑是安装有问题或者是初始化有问题&#xff08;当然&#xff0c;如果真有问题要先解决这些问题&#xff09;&#xff0c;经过不断探索才发现是网络插件没有安装导致的&#xff0c;根据建议安装calico插…

【图像加密解密】Logistic混沌映射的彩色图像加密算法复现(含相关性检验)【Matlab完整源码 1期】

1、说明 本文给出详细完整代码、完整的实验报告和PPT。 环境&#xff1a;MATLAB2019a 复现文献&#xff1a;[1]黄硕.基于改进的Logistic混沌映射彩色图像加密算法[J].河南工程学院学报(自然科学版),2015,27(02):63-67. 主要目的是为了快速了解何为混沌序列、混沌序列产生、…

[AUTOSAR 基础入门] - RTE虚拟总线详解

文章目录 一、什么是RTE二、RTE的作用三、RTE对Runnables的运行支撑四、RTE与通信4.1. RTE – ECU之间通信4.2. RTE - Sender/Receiver 通信4.2.1 不使用队列&#xff08;直接访问&#xff09;4.2.2 不使用队列&#xff08;缓存访问&#xff09;4.2.3 使用队列 4.3 RTE - Clien…

Linux下文件操作相关接口

文章目录 一 文件是什么普通数据文件 二 文件是谁打开的进程用户 三 进程打开文件的相关的接口c语言标准库相关文件接口1. fopen 函数2. fread 函数3. fwrite 函数4. fclose 函数5. fseek 函数 linux系统调用接口1. open 系统调用2. creat 系统调用3. read 系统调用4. write 系…

用Python实现简单的任务自动化

目录 1. 自动发送邮件提醒 2. 自动备份文件 3. 自动下载网页内容 总结 在现代工作和生活中,任务自动化可以极大地提高效率和准确性。Python,作为一种功能强大且易于学习的编程语言,是实现任务自动化的理想选择。本文将通过几个简单而实用的案例,展示如何用Python实现任…

小程序开发-页面事件之上拉触底实战案例

&#x1f3a5; 作者简介&#xff1a; CSDN\阿里云\腾讯云\华为云开发社区优质创作者&#xff0c;专注分享大数据、Python、数据库、人工智能等领域的优质内容 &#x1f338;个人主页&#xff1a; 长风清留杨的博客 &#x1f343;形式准则&#xff1a; 无论成就大小&#xff0c;…

Docker 服务、镜像、容器之命令(Docker Services, Images, and Container Commands)

Docker 服务、镜像、容器之命令 Docker是一个强大的容器化平台&#xff0c;能够帮助开发者高效地构建、部署和管理应用程序。本文将详细介绍Docker的服务命令、镜像命令和容器命令&#xff0c;帮助你快速上手Docker。 一、Docker的服务相关命令 在使用Docker之前&#xff0c…

STM32内置Flash

一、原理 利用flash存储用户数据需要注意查看&#xff0c;用户数据是否会覆盖芯片运行程序。 IAP&#xff08;在程序中编程&#xff09;利用程序修改程序本身&#xff0c;和OTA是一个原理。IAP在程序中编程支持任意一种通信下载。 ICP&#xff08;在电路中编程&#xff0c;通…

两种方式实现Kepware与PLC之间的心跳检测

两种方式实现Kepware与PLC之间的心跳检测 实现Kepware与PLC之间的心跳检测1.OPCUA 外挂程序2.Kepware Advanced Tag 实现Kepware与PLC之间的心跳检测 1.OPCUA 外挂程序 这是通过上位程序来触发心跳的一种机制&#xff0c;在C#中&#xff0c;可以利用OPC UAOPCAutodll的方式…

英伟达Project Digits赋能医疗大模型:创新应用与未来展望

英伟达Project Digits赋能医疗大模型&#xff1a;创新应用与未来展望 一、引言 1.1 研究背景与意义 在当今数字化时代&#xff0c;医疗行业作为关乎国计民生的关键领域&#xff0c;正面临着前所未有的挑战与机遇。一方面&#xff0c;传统医疗模式在应对海量医疗数据的处理、复…

中国省级产业结构高级化及合理化数据测算(2000-2023年)

一、数据介绍 数据名称&#xff1a;中国省级产业结构高级化、泰尔指数 数据年份&#xff1a;2000-2023年 数据范围&#xff1a;31个省份 数据来源&#xff1a;中国统计年鉴、国家统计局 数据整理&#xff1a;内含原始版本、线性插值版本、ARIMA填补版本 数据说明&#xf…

关于Mac使用VSCode连接虚拟机

1. 下载插件 输入Remote - SSH下载下图两个插件。 2. 配置虚拟机信息 按图示步骤点击完成后&#xff0c;进入到虚拟主机的配置页面。 其中Host可以自定义主机名&#xff0c;HostName是虚拟机ip&#xff0c;可以通过ifconfig eth0查看ip&#xff0c;User是虚拟机的用户名。…

GOGOGO 接口

低高耦合?【程序中追求低耦合,所以接口广用】 低耦合:关联依赖性弱(你走了我还在) 高耦合:关联依赖性强(牵一发而动全身) 接口 概念:多个抽象方法的集合,只有结构无具体实现,并交给实现类完成功能操作【接口写功能,实现类写具体实现】 语法结构: 定义接口的关…

nginx反向代理+缓存

1、nginx-LB配置页面缓存 [rootOldboy conf]# vi nginx.conf http {include mime.types;default_type application/octet-stream;sendfile on;keepalive_timeout 65;include proxy.conf; …

React中的合成事件

合成事件与原生事件 区别&#xff1a; 1. 命名不一样&#xff0c;原生用纯小写方式&#xff0c;react用小驼峰的方式 原生&#xff1a;onclick React的&#xff1a;onClick 2. 事件处理函数的写法不一样 原生的是传入一个字符串&#xff0c;react写法传入一个回调函数 3.…

智能安全帽_4G/5G智能安全帽主板方案定制开发

智能安全帽是一种先进的安全防护设备&#xff0c;主要以视频和语音通话为功能&#xff0c;能够全面记录施工现场的作业情况&#xff0c;并支持管理人员与现场工作人员之间的双向语音通话。这一创新设计使得项目管理人员能够实时、有效地掌握施工过程中的安全和质量情况。 这款智…

uni-app图文列表到详情页面切换

需求&#xff1a;参考若依框架后&#xff0c;想实现首页浏览文章列表&#xff0c;没有合适的样式参考&#xff0c;所以需要有效果做到“图文列表到详情页面切换”&#xff0c;查阅了一下案例 发现有相应的案例&#xff0c;在导航栏“模板”中找到了 DCloud 插件市场 PC电脑端访…

MySQL安装,配置教程

一、Linux在线yum仓库安装 打开MySQL官方首页&#xff0c;链接为&#xff1a;https://www.mysql.com/ 界面如下&#xff1a; 在该页面中找到【DOWNOADS】选项卡&#xff0c;点击进入下载页面。 在下载界面中&#xff0c;可以看到不同版本的下载链接&#xff0c;这里选择【My…