传送门:图像模糊处理 - 洛谷
审题
(说明)模糊化处理:
1. 四周最外侧的像素点灰度值不变;
2. 中间各像素点新灰度值为该像素点及其上下左右相邻四个像素点原灰度值的平均(舍入到最接近的整数)。
变量要求:行数n列数m(1≤n≤100,1≤m≤100)储存图像的矩阵a[101][101]以及新的矩阵b[101][101]
“该像素点及其上下左右相邻四个像素点”的意思是什么呢,博主一开始还没看懂,大概意思如下
a[ i+1 ][ j ](上) | ||
a[ i-1 ][ j-1 ](左) | a[ i ][ j ](本身) | a[ i ][ j+1 ](右) |
a[ i-1 ][ j ](下) | “四个相邻的像素点” |
把这 5 个格内的数据算平均数放在新的矩阵中,也就是 b[ i ][ j ]。
简单来说就是把数组 a 中不在边缘的数据,都如上处理一遍,放进数组 b 中或直接输出就行了
解题思路
本题的核心就在于这 5 个数取平均值
但是……
这 5 个数的求和有点麻烦
你说用循环吧 数据量又不大
说纯手打吧 重复的步骤字又多
经过一番纠结,博主选择了复制,一段一段复制下来,稍加修改
加上循环,取平均值的代码就出来了
//b[101][101]就是处理过的图像矩阵
for(int i=2;i<n;i++){//掐头去尾 ,去掉边缘数据
for(int j=2;j<m;j++){
int sum=a[i][j]+a[i][j+1]+a[i][j-1]+a[i+1][j]+a[i-1][j];
b[i][j]=round(sum/5.0);//round() 求四舍五入的函数
}
}
因为这里仅仅是对不在边缘的数据进行处理 所以要加上边缘数据的直接赋值
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(i==1||i==n||j==1||j==m)
b[i][j]=a[i][j];
else{
int sum=a[i][j]+a[i][j+1]+a[i][j-1]+a[i+1][j]+a[i-1][j];
b[i][j]=round(sum/5.0);
}
}
}//也可以把第一行和最后一行的赋值分离出来,变成三个循环
加上输入输出,整道题就差不多了
代码展示
#include<bits/stdc++.h>
using namespace std;
int n,m,a[101][101],b[101][101];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(i==1||i==n||j==1||j==m)
b[i][j]=a[i][j];
else{
int sum=a[i][j]+a[i][j+1]+a[i][j-1]+a[i+1][j]+a[i-1][j];
b[i][j]=round(sum/5.0);
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<b[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
代码进阶
在以上示例代码中,我们可以观察到
把处理好的数据放入数组 b 后,不需要对数组 b 进行任何处理
于是我们便可以把输出与处理数据放在一块,这样就可免去数组 b 储存的过程,减少了空间浪费
就像下面代码,在找到或算出结果就输出
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(i==1||i==n||j==1||j==m)
cout<<a[i][j]<<" ";
else{
int sum=a[i][j]+a[i][j+1]+a[i][j-1]+a[i+1][j]+a[i-1][j];
cout<<round(sum/5.0)<<" ";
}
}
cout<<endl;
}
综合在一起就如下
#include<bits/stdc++.h>
using namespace std;
int n,m,a[101][101];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(i==1||i==n||j==1||j==m)
cout<<a[i][j]<<" ";
else{
int sum=a[i][j]+a[i][j+1]+a[i][j-1]+a[i+1][j]+a[i-1][j];
cout<<round(sum/5.0)<<" ";
}
}
cout<<endl;
}
return 0;
}