XDOJ 485 排序中值滤波

题面

排序中值滤波题面1

排序中值滤波题面2

问题描述

排序中值滤波是图像处理中常用的滤波方法之一,它具有以下主要特点:对大的边缘 高度,中值滤波较邻域均值好,对于较小边缘高度,两种滤波有很少的差别;中值滤波是非 线性的,整个处理过程也稍微麻烦一些;在抑制图像随机脉冲噪声方面特别是椒盐噪声等比 较好,去除孤立线或污点效果比较好,但是不适合点、线等细节多的图像。

假设原图像(灰度图像为例)幅度为 16x16,即包含 16 行 16 列像素点。每个像素值为 0~255,第𝑖行𝑗列像素表示为𝑎𝑖𝑗, (0 ≤ 𝑖 ≤ 15,0 ≤ 𝑗 ≤ 15,0 ≤ 𝑎𝑖𝑗 ≤ 255)。滤波器选择 3x3 窗 口。假设滤波后的图像幅度仍为 16x16,其第𝑖行𝑗列像素表示为𝑏𝑖𝑗,滤波算法描述如下:

原图像中首行、末行、首列、末列的元素不做处理,其余元素均为以其为中心的周围 9 个元素排序后的中值。即,

1) 𝑏𝑖𝑗 = 𝑎𝑖𝑗, (𝑖 = 0,15;𝑗 = 0,15);

2) 将下列九个元素从小到大排序, 𝑎𝑖−1,𝑗−1, 𝑎𝑖−1,𝑗 , 𝑎𝑖−1,𝑗+1, 𝑎𝑖,𝑗−1, 𝑎𝑖,𝑗 , 𝑎𝑖,𝑗+1, 𝑎𝑖+1,𝑗−1, 𝑎𝑖+1,𝑗 , 𝑎𝑖+1,𝑗+1, (𝑖 ≠ 0,15;𝑗 ≠ 0,15) 假设排序后的结果为: 𝑎(0) , 𝑎(1) , 𝑎(2) , 𝑎(3) , 𝑎(4) , 𝑎(5) , 𝑎(6) , 𝑎(7) , 𝑎(8) ;

3) 则:𝑏𝑖𝑗 = 𝑎(4) , (𝑖 ≠ 0,15;𝑗 ≠ 0,15)

请编程序完成对输入图像的排序中值滤波,并输出滤波后的图像。

输入格式

16x16 矩阵,矩阵元素值为 0~255,元素间以一个空格分隔。

输出格式

16x16 矩阵,矩阵元素值为 0~255,元素间以一个空格分隔。

样例输入

96 50 12 240 209 225 154 60 153 255 96 171 10 139 135 172
79 195 248 97 246 247 91 55 214 8 62 14 168 108 65 235
85 90 215 156 10 168 245 213 66 215 24 162 254 81 72 143
2 216 71 251 216 78 242 249 136 17 141 16 210 218 113 93
83 83 69 113 210 202 138 227 30 209 33 253 154 96 187 34
52 150 78 198 82 149 166 45 45 131 126 129 250 191 78 93
144 14 144 12 40 254 162 212 148 158 63 113 48 201 185 101
7 33 7 113 144 150 191 82 10 88 46 110 76 102 102 46
56 236 159 81 126 193 101 186 86 59 3 188 82 95 86 139
174 123 78 156 65 129 9 231 173 171 157 245 40 216 8 5
101 92 45 130 147 92 231 185 30 88 186 115 113 119 174 54
237 172 141 111 239 122 100 87 42 155 33 154 55 43 143 186
37 134 1 82 86 234 55 131 108 190 90 221 122 180 178 164
151 228 111 48 97 21 80 247 95 52 207 156 146 193 183 131
111 237 19 0 190 93 110 205 70 182 117 199 118 202 248 240
11 165 136 217 249 229 127 247 42 83 237 77 216 144 227 169

样例输出

96 50 12 240 209 225 154 60 153 255 96 171 10 139 135 172
79 90 156 209 209 209 168 153 153 96 96 96 139 108 135 235
85 90 195 215 168 216 213 213 136 66 24 141 162 113 108 143
2 83 113 156 168 202 213 213 209 66 141 154 162 154 96 93
83 78 113 113 198 166 166 138 131 126 129 141 191 187 96 34
52 83 83 82 149 162 166 148 148 126 129 126 154 185 101 93
144 52 78 82 144 150 162 148 88 88 113 110 113 102 102 101
7 56 81 113 126 150 186 148 88 63 88 76 102 95 102 46
56 78 113 113 129 129 150 101 88 86 110 82 102 86 95 139
174 101 123 126 129 126 185 173 171 88 157 115 115 95 95 5
101 123 123 130 129 122 122 100 155 155 155 115 115 113 119 54
237 101 111 111 122 122 122 100 108 90 154 115 119 122 164 186
37 141 111 97 97 97 100 95 108 95 155 146 154 146 178 164
151 111 82 82 86 93 110 108 131 108 182 146 180 180 183 131
111 136 136 111 97 110 127 110 95 95 156 156 156 193 193 240
11 165 136 217 249 229 127 247 42 83 237 77 216 144 227 169

样例说明

输入向量的元素以一个空格分隔,末尾无其他符号; 评测用例规模与约定 输入输出均为 16x16 矩阵;元素值 0~255。

题解 

题目分析:

本题可简化为

实现中间区域内,取3*3区域中位数并输出

思路:

  • 将矩阵存入二位数组
  • 如果是第一排、最后一排、第一列、最后一列就直接输出;
  • 如果是中间区域的数,取其周围3*3区域的数放入容器,排序并输出中位数

满分代码(含注释) 

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

vector <int > tmp; // vector 容器,用于存储当前3*3区域内的数 

int a[20][20]; // 存放矩阵的二维数组 

int main()
{
	for (int i = 0; i < 16; i++)
	{
		for (int j = 0; j < 16; j++)
		{
			cin >> a[i][j];
		}
	}
	
	for (int i = 0; i < 16; i++)
	{
		for (int j = 0; j < 16; j++)
		{
			if (i == 0 || i == 15 || j == 0 || j == 15) // 如果是第一行、最后一行、第一列、最后一列,输出原数 
			{
				cout << a[i][j];
				if (j == 15) // 行末换行 
				{
					cout << '\n';
				}
				else
				{
					cout << ' '; // 同行数之间的空格 
				}
				continue;
			}
			
			for (int k = i - 1; k <= i + 1; k++)
			{
				for (int l = j - 1; l <= j + 1; l++)
				{
					tmp.push_back(a[k][l]); // 存储当前3*3区域内的数,每次向容器末尾放入一个数 
				}
			}
			
			sort (tmp.begin(), tmp.end()); // 将当前3*3区域内的数排序 
			
			cout << tmp[4] << ' '; // 输出中位数 
			
			tmp.clear(); // 清空容器 
		}
	}
	return 0;
}

纯享版代码(不含注释) 

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

vector <int > tmp;

int a[20][20];

int main()
{
	for (int i = 0; i < 16; i++)
	{
		for (int j = 0; j < 16; j++)
		{
			cin >> a[i][j];
		}
	}
	
	for (int i = 0; i < 16; i++)
	{
		for (int j = 0; j < 16; j++)
		{
			if (i == 0 || i == 15 || j == 0 || j == 15)
			{
				cout << a[i][j];
				if (j == 15)
				{
					cout << '\n';
				}
				else
				{
					cout << ' ';
				}
				continue;
			}
			
			for (int k = i - 1; k <= i + 1; k++)
			{
				for (int l = j - 1; l <= j + 1; l++)
				{
					tmp.push_back(a[k][l]);
				}
			}
			
			sort (tmp.begin(), tmp.end());
			
			cout << tmp[4] << ' ';
			
			tmp.clear();
		}
	}
	return 0;
}

date:20240104

  • 21
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bbw20110110

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值