Median Filter

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1092    Accepted Submission(s): 269

Problem Description
Median filter is a cornerstone of modern image processing and is used extensively in

Given a black and white image of n by n pixels, the algorithm works as follow:
For each pixel p at the i‐th row and the j‐th column (1+ r <= i, j <= n – r), its gray level g[i,j] is replace by the median of gray levels of pixels in the (2r+1) by (2r+1) square centered at p. The square is called the filtering window and r is its radius.

Considering the above example, the gray level of the pixel at center will be changed from 150 to 124, which is the median of a filtering window of radius 1.

Note that the algorithm won’t be applied on the pixels near the boundary, for the filtering window lies outside the image. So you are actually asked to output the filtered sub-image which contains the pixels from (r+1, r+1) to (n-r, n-r).

 
Input
The input contains several test cases.
For each test case:

(a) The first line contains two integers, n and r, meaning that the size of image is n * n (3 <= n <= 500) and the radius of filtering window is r ( 3 <= 2r + 1 <= n).

(b) The following n lines contains the n by n gray level matrix presenting the image

(c) The gray level ranges from 0 to 1000000 The input ends by double 0s.

 
Output
For each test case output a (n – 2r) by (n – 2r) matrix presenting the sub-image after filtered.
 
Sample Input
3 1
1 1 1
1 1 1
1 1 1
3 1
1 9 6
4 5 2
3 7 8
3 1
0 0 0
255 255 255
0 255 0
5 1
0 0 1 1 0
1 0 1 0 1
0 0 1 1 1
1 1 1 0 1
1 0 0 0 1
0 0
 
Sample Output
1
5
0
0 1 1
1 1 1
1 0 1

Hint

The definition of “median”: One type of average, found by arranging the values in order and then selecting the one in the middle.
If the total number of values in the sample is even, then the median is the mean of the two middle numbers.
The median is a useful number in cases where the distribution has very large extreme values which would otherwise skew the data.

 
Source
 
Recommend
lcy   |   We have carefully selected several similar problems for you:  3641 3649 3647 3646 3645 
 

题意:

中值滤波,求在n*n的矩阵中,内(n-2*r)*(n-2*r)的中值滤波后的子矩阵。

中值滤波的方式就是对于每一个可以取到的以(i,j)为矩阵中心的(2*r+1)*(2*r+1)的子矩阵,将子矩阵中所有数排序后的中位数作为新值,新值不影响后面的值。

做法:

树状数组

这是一题比较有趣的题吧,一开始暴力试一下是TLE的,明显算法复杂都会很大。子矩阵的处理如果用到排序应该都会超时,因此看到了一个很高效的算法,就是利用树状数组和一个在树状树组中求第k大的数的函数,后来在采用S行遍历,代码因此有点长,还要注意一下输出。

 //1781MS    6196K    2399 B    G++
#include<stdio.h>
#include<string.h>
#define N 505
int g[N][N];
int ans[N][N];
int c[<<];
int n,r,M;
inline int lowbit(int k)
{
return k&(-k);
}
int getsum(int k)
{
int s=;
for(;k>;k-=lowbit(k))
s+=c[k];
return s;
}
void insert(int k,int detal)
{
for(;k<=M;k+=lowbit(k))
c[k]+=detal;
}
int find_kth(int k) //树状数组找第k大的数
{
int sum=,pos=;
for(int i=;i>=;i--){
pos+=(<<i);
if(pos>M || sum+c[pos]>=k)
pos-=(<<i);
else sum+=c[pos];
}
return pos+;
}
void solve()
{
int R=*r+;
int k=R*R/+;
for(int i=;i<=R;i++)
for(int j=;j<=R;j++)
insert(g[i][j],);
//for(int i=1;i<=2*(k-1);i++) printf("*%d\n",c[i]);
for(int i=r+;i<=n-r;i++){
if((i-r)&){ //奇数行,向右遍历
if(i!=r+){
for(int j=;j<=R;j++){
insert(g[i-r-][j],-);
insert(g[i+r][j],);
}
}
ans[i][r+]=find_kth(k);
for(int j=r+;j<=n-r;j++){
for(int ii=i-r;ii<=i+r;ii++){
insert(g[ii][j-r-],-);
insert(g[ii][j+r],);
}
ans[i][j]=find_kth(k);
}
}else{ //偶数行,向左遍历
for(int j=n;j>=n-R+;j--){
insert(g[i-r-][j],-);
insert(g[i+r][j],);
}
ans[i][n-r]=find_kth(k);
for(int j=n-r-;j>=r+;j--){
for(int ii=i-r;ii<=i+r;ii++){
insert(g[ii][j+r+],-);
insert(g[ii][j-r],);
}
ans[i][j]=find_kth(k);
}
}
}
}
int main(void)
{
while(scanf("%d%d",&n,&r),n+r)
{
M=;
memset(c,,sizeof(c));
for(int i=;i<=n;i++)
for(int j=;j<=n;j++){
scanf("%d",&g[i][j]);
g[i][j]++;
if(g[i][j]>M) M=g[i][j];
}
solve();
for(int i=r+;i<=n-r;i++)
for(int j=r+;j<=n-r;j++)
printf(j==n-r?"%d \n":"%d ",ans[i][j]-);
}
return ;
} /* 3 1
1 9 6
4 5 2
3 7 8 5 1
0 0 1 1 0
1 0 1 0 1
0 0 1 1 1
1 1 1 0 1
1 0 0 0 1 */

hdu 3648 Median Filter (树状数组)的更多相关文章

  1. HDU 3333 | Codeforces 703D 树状数组、离散化

    HDU 3333:http://acm.hdu.edu.cn/showproblem.php?pid=3333 这两个题是类似的,都是离线处理查询,对每次查询的区间的右端点进行排序.这里我们需要离散化 ...

  2. HDU 3333 - Turing Tree (树状数组+离线处理+哈希+贪心)

    题意:给一个数组,每次查询输出区间内不重复数字的和. 这是3xian教主的题. 用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理.在线很难下手,考虑离线处理. 将所有查询区间从右端点由 ...

  3. HDU 3333 Turing Tree (树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3333 题意就是询问区间不同数字的和. 比较经典的树状数组应用. //#pragma comment(l ...

  4. HDU 4325 Flowers(树状数组+离散化)

    http://acm.hdu.edu.cn/showproblem.php?pid=4325 题意:给出n个区间和m个询问,每个询问为一个x,问有多少个区间包含了x. 思路: 因为数据量比较多,所以需 ...

  5. hdu 5775 Bubble Sort 树状数组

    Bubble Sort 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5775 Description P is a permutation of t ...

  6. HDU - 1541 Stars 【树状数组】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1541 题意 求每个等级的星星有多少个 当前这个星星的左下角 有多少个 星星 它的等级就是多少 和它同一 ...

  7. HDU 3854 Glorious Array(树状数组)

    题意:给一些结点,每个结点是黑色或白色,并有一个权值.定义两个结点之间的距离为两个结点之间结点的最小权值当两个结点异色时,否则距离为无穷大.给出两种操作,一种是将某个结点改变颜色,另一个操作是询问当前 ...

  8. HDU 3874 Necklace (树状数组 | 线段树 的离线处理)

    Necklace Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  9. HDU 5101 Select --离散化+树状数组

    题意:n 组,每组有一些值,求 在不同的两组中每组选一个使值的和大于k的方法数. 解法:n * Cnt[n] <= 1000*100 = 100000, 即最多10^5个人,所以枚举每个值x,求 ...

随机推荐

  1. 为什么我用了$().height()还是对不齐呢?

    有一个这样的需求:有两个显示内容的框,要使他们高度一致,因为他们存放的内容多少和结构不一样,左边内容少,右边内容多.这就导致了右边会比左边高,解决方法就是超出部分用滚轮显示,那这时就先要调整右边的高度 ...

  2. (转)IP地址分配原理

    网络模型介绍 在计算机网络中有著名的OSI七层协议体系结构,概念清楚,理论完整,但是它既复杂又不实用.TCP/IP体系结构则不同,得到的广泛的应用.最终结合OSI和TCP/IP的优点,采用了一种只有五 ...

  3. 基于pyecharts的IT各行业薪资展示

    我们的项目是一个信息采集系统,采集的是51job招聘网站,我爬取了Python,Java,C++,PHP还有北京各地区的职位数量,以及经验要求,和学历要求等等. 网页头; <!DOCTYPE h ...

  4. python3 练习题100例 (二十六)回文数判断

    题目内容: 给一个5位数,判断它是不是回文数,是则输出yes,不是则输出no. 例如12321是回文数,它的个位与万位相同,十位与千位相同. 输入格式: 共一行,为一个5位数. 输出格式: 共一行,y ...

  5. python 装饰器 (多个装饰器装饰一个函数---装饰器前套一个函数)

    #带参数的装饰器 #500个函数 # import time # FLAGE = False # def timmer_out(flag): # def timmer(func): # def inn ...

  6. Leecode刷题之旅-C语言/python-104二叉树最大深度

    /* * @lc app=leetcode.cn id=104 lang=c * * [104] 二叉树的最大深度 * * https://leetcode-cn.com/problems/maxim ...

  7. 多线程编程之Apue3rd_Chapter11之互斥锁_读写锁_自旋锁

    学习了apue3rd的第11章,主要讲的是多线程编程.因为线程共享进程的资源比如堆和全局变量,多线程编程最重要的是,使用各种锁进行线程同步. 线程编程首先要学习的三个函数如下: #include &l ...

  8. 141. 环形链表 LeetCode报错:runtime error: member access within null pointer of type 'struct ListNode'

    /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode ...

  9. windows程序内部运行机制

    Windows程序内部运行机制 2007-10-21 19:52 1010人阅读 评论(0) 收藏 举报 windowsvc++applicationcallbackwinapistructure W ...

  10. 嵌入式框架Zorb Framework搭建二:环形缓冲区的实现

    我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮. 嵌入式框架Zorb Framework搭建过程 嵌入式框架Zorb Framework搭建一:嵌入式环境搭建.调试输出和建立时间系 ...