文章目录
邻域均值
试题背景
顿顿在学习了数字图像处理后,想要对手上的一副灰度图像进行降噪处理。不过该图像仅在较暗区域有很多噪点,如果贸然对全图进行降噪,会在抹去噪点的同时也模糊了原有图像。因此顿顿打算先使用邻域均值来判断一个像素是否处于较暗区域,然后仅对处于较暗区域的像素进行降噪处理。
问题描述
现给定邻域参数 r 和阈值 t,试统计输入灰度图像中有多少像素处于较暗区域。
输入格式
输出格式
输出一个整数,表示输入灰度图像中处于较暗区域的像素总数。
样例输入
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
评测用例规模与约定
代码
#include <iostream>
#include<vector>
using namespace std;
int n, r, L, a;
int num = 0;
int arr[605][605];//存储初始的读取的数组
int vi[605][605];//存储前缀数组
int main()
{
cin >> n >> L >> r >> t;
for (int i = 1; i < n + 1; i++)
{
for (int j = 1; j < n + 1; j++)
{
cin >> arr[i][j];
vi[i][j] = vi[i][j - 1] + vi[i - 1][j] - vi[i - 1][j - 1] + arr[i][j];//计算当前位置前缀数组的值
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
int a = max(1, i - r), b = max(1, j - r);//a,b分别为阈值区间内的最小的x和y
int c = min(n, i + r), d = min(n, j + r);//c,d分别为阈值区间内的最大的x和y
int s = vi[c][d] - vi[c][b - 1] - vi[a - 1][d] + vi[a - 1][b - 1];//计算当前阈值区域的总值
int sum = (c - a + 1) * (d - b + 1);//计算阈值区域的数字个数
if (s <= t * sum)num++;
}
}
cout << num << endl;
return 0;
}
思路
采用前缀数组的方式存储对应的前缀数据,二维数组的前缀存储代表的是以当前位置为右下角,(0,0)为左上角的矩形区域内的数据的和。
例如计算某邻域的总和即为下图图示:
上图以计算(6,5)邻域并以r为1为例,图中红色即为目标的邻域,要计算该区域的总值,是用前缀数组vi表示为vi[7,6]-vi[5,6]-vi[7,4]+vi[5,4],即可计算出区域的总值,之后再根据区域的大小计算出邻域的均值即可。