试题编号: 202104-2
试题名称: 邻域均值
时间限制: 1.0s
内存限制: 512.0MB
问题描述:
试题背景
顿顿在学习了数字图像处理后,想要对手上的一副灰度图像进行降噪处理。不过该图像仅在较暗区域有很多噪点,如果贸然对全图进行降噪,会在抹去噪点的同时也模糊了原有图像。因此顿顿打算先使用邻域均值来判断一个像素是否处于较暗区域,然后仅对处于较暗区域的像素进行降噪处理。
问题描述
待处理的灰度图像长宽皆为n个像素,可以表示为一个n×n大小的矩阵A,其中每个元素是一个[0,L)范围内的整数,表示对应位置像素的灰度值。
对于矩阵中任意一个元素Aij(0≤i,j<n),其邻域定义为附近若干元素的集和:
这里使用了一个额外的参数r来指明Aij附近元素的具体范围。根据定义,易知Neighbor(i,j,r)最多有(2r+1)2个元素。
如果元素Aij邻域中所有元素的平均值小于或等于一个给定的阈值t,我们就认为该元素对应位置的像素处于较暗区域。
下图给出了两个例子,左侧图像的较暗区域在右侧图像中展示为黑色,其余区域展示为白色。
现给定邻域参数r和阈值t,试统计输入灰度图像中有多少像素处于较暗区域。
输入格式
输入共n+1行。
输入的第一行包含四个用空格分隔的正整数n、L、r和t,含义如前文所述。
第二到第n+1行输入矩阵A。
第i+2(0≤i<n)行包含用空格分隔的n个整数,依次为Ai0,Ai1,…,Ai(n-1)。
输出格式
输出一个整数,表示输入灰度图像中处于较暗区域的像素总数。
样例输入
4 16 1 6
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
样例输出
7
样例输入
11 8 2 2
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 7 0 0 0 7 0 0 7 7 0
7 0 7 0 7 0 7 0 7 0 7
7 0 0 0 7 0 0 0 7 0 7
7 0 0 0 0 7 0 0 7 7 0
7 0 0 0 0 0 7 0 7 0 0
7 0 7 0 7 0 7 0 7 0 0
0 7 0 0 0 7 0 0 7 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
样例输出
83
评测用例规模与约定
70%的测试数据满足n≤100、r≤10。
全部的测试数据满足0<n≤600、 0<r≤100且2≤t<L≤256。
C:
//先使用邻域均值来判断一个像素是否处于较暗区域,
//然后仅对处于较暗区域的像素进行降噪处理。
#include<stdio.h>
int main()
{
int n,L,r,t,i,j,t1,t2,end=0;
int a,b,c,d;//对于中心元素,邻域左上元素为s[a][b],右下角元素为s[c][d]
int a1,b1,c1,d1;// 对于新的中心元素,邻域左上元素为s[a1][b1],右下元素为s[c1][d1]
float sum,num;//sum为目前元素总值,num为目前元素总个数
scanf("%d%d%d%d",&n,&L,&r,&t);
int s[n][n];
//存储
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&s[i][j]);
}
}
//计算
for(i=0;i<n;i++)//上下
{
j=0;sum=0;num=0;//每一行先对第一个元素计算,重新赋初值
//确定邻域范围a,b,c,d
a=i-r;if(a<0)a=0;//上
b=j-r;if(b<0)b=0;//左
c=i+r;if(c>=n)c=n-1;//下
d=j+r;if(d>=n)d=n-1;//右
//计算第一个元素的领域
for(t1=a;t1<c+1;t1++) //t1是行数 相当于i 0-2*r
{
for(t2=b;t2<d+1;t2++)//t2是列数
{
sum+=s[t1][t2];
num++;
}
}
if(sum/num<=t) end++;
//计算本行之后元素的邻域
for(j=1;j<n;j++)//左右
{
//确定新的邻域范围a1,b1,c1,d1
a1=i-r;if(a1<0) a1=0;
b1=j-r;if(b1<0) b1=0;
c1=i+r;if(c1>=n) c1=n-1;
d1=j+r;if(d1>=n) d1=n-1;
//判断左边界是否变化,若变化则减去
if(b1!=b)//左
{
for(t1=a;t1<c+1;t1++)
{
sum-=s[t1][b];//竖着 行标动 列标不动
num--;
}
}
// 判断右边界是否变化,若变化则加上
if(d1!=d){
for(t1=c;t1>=a;t1--){
sum+=s[t1][d1];
num++;
}
}
if(sum/num<=t)end++;
a=a1;b=b1;c=c1;d=d1;//重新定义目前邻域范围
}
}
printf("%d",end);
return 0;
}
————————————————
之前的笔记,当时没有记录是学习的哪位大佬的代码,如果侵犯到您的权益请联系我,马上删除或者标注出处。