cff 202104-2 邻域均值

试题编号: 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;
} 

————————————————
之前的笔记,当时没有记录是学习的哪位大佬的代码,如果侵犯到您的权益请联系我,马上删除或者标注出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值