算法题每日一练---第4天:图像模糊问题

「这是我参与2022首次更文挑战的5天,活动详情查看:2022首次更文挑战

一、问题描述

小蓝有一张黑白图像,由 n×m 个像素组成,其中从上到下共 n 行,每行从左到右 m 列。每个像素由一个 0 到 255 之间的灰度值表示。

现在,小蓝准备对图像进行模糊操作,操作的方法为:

对于每个像素,将以它为中心 3×3 区域内的所有像素(可能是 9 个像素或少于 9 个像素)求和后除以这个范围内的像素个数(取下整),得到的值就是模糊后的结果。

请注意每个像素都要用原图中的灰度值计算求和。

二、题目要求

输入:第一行输入两个整数n,m(其中,1≤n,m≤100),第二行到n+1包含m个正整数,代表每一个像素的灰度值

输出:输出 n 行,每行 m 个整数,相邻整数之间用空格分隔,表示模糊后的图像。

三、问题分析

使用二维数组存储要输入的像素,对于每一个像素而言,将它3×3 区域内的所有像素值全部相加再除以总数。

这里有一个问题,寻找的时候可能会越界。比如一个第一行的像素值,上面没有值,第一列的像素值,左边没有值。只有中间的才满足3×3。所以,在判断条件的时候要加一个是否超出范围。

定义一个8*2的数组,int c[8][2]={0,1,0,-1,-1,0,1,0,1,1,-1,1,-1,-1,1,-1};作为延伸的方向。 在for循环中 x=i+c[k][0],y=j+c[k][1],判断上下左右和其它总共8个方向坐标值。

对于x,y的范围x>=1&&x<=n&&y>=1&&y<=m;

像素值/像素个数的数值,题目要求向下取整,直接定义int型相除就行。对于平常的取整问题,可以调用#include<math.h>里面的floor(向下取整)和ceil(向上取整)。

四、编码实现

#include<iostream>
using namespace std;
int main()
{
	int a[105][105],b[105][105];//定义两个二维数组 
	int c[8][2]={0,1,0,-1,-1,0,1,0,1,1,-1,1,-1,-1,1,-1};//方向数组 
	int n,m,i,j,k;
	cin>>n>>m;//输入数据 
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			cin>>a[i][j];//输入 
		}
	}
	int ans,sum=0;//定义,周围的像素和和个数 
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			sum=a[i][j];//像素值初始化 
			ans=1;//像素个数初始化 
			for(k=0;k<8;k++)
			{
				int x=i+c[k][0];//x坐标 
				int y=j+c[k][1];//y坐标 
				if(x>=1&&x<=n&&y>=1&&y<=m)//判断坐标是否在范围 
				{
					ans++;//像素个数++ 
					sum+=a[x][y];//像素值++ 
				}
			}
			b[i][j]=sum/ans;//更新变量值 
		}
	}
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			cout<<b[i][j]<<" ";//输出数组 
		}cout<<"\n";
	}
	return 0;
}
复制代码

四、输出结果

测试用例:给定一个三行四列的数组,输出正确的结果

3 4

0 0 0 255

0 0 255 0

0 30 255 255

1.png

猜你喜欢

转载自juejin.im/post/7055840663484497933