学习DIP第32天
转载请标明本文出处:http://blog.csdn.net/tonyshengtan,欢迎大家转载,发现博客被某些论坛转载后,图像无法正常显示,无法正常表达本人观点,对此表示很不满意。有些网站转载了我的博文,很开心的是自己写的东西被更多人看到了,但不开心的是这段话被去掉了,也没标明转载来源,虽然这并没有版权保护,但感觉还是不太好,出于尊重文章作者的劳动,转载请标明出处!!!!
文章代码已托管,欢迎共同开发:https://github.com/Tony-Tan/DIPpro
//以下为低速普通中值滤波,排序使用计数排序
void initHist(int *hist,int size){
for(int i=0;i<size;i++)
hist[i]=0;
}
int sort(int *src,int size){
int hist[GRAY_LEVEL];
int m=0;
initHist(hist, GRAY_LEVEL);
for(int i=0;i<size;i++)
hist[src[i]]++;
for(int i=0;i<GRAY_LEVEL;i++){
m+=hist[i];
if(m>size/2)
return i;
}
return 0;
}
void MedianFilter(IplImage *src,IplImage *dst,int width,int height){
IplImage* temp=cvCreateImage(cvSize(src->width+width, src->height+height), src->depth, src->nChannels);
IplImage* dsttemp=cvCreateImage(cvSize(src->width+width, src->height+height), src->depth, src->nChannels);
cvZero(temp);
for(int j=0;j<src->height;j++){
for(int i=0;i<src->width;i++){
double value=cvGetReal2D(src, j, i);
cvSetReal2D(temp, j+height/2, i+width/2, value);
}
}
int *window=(int *)malloc(sizeof(int)*width*height);
if(window==NULL){
printf(" ");
exit(0);
}
for(int j=height/2;j<temp->height-height/2-1;j++){
for(int i=width/2;i<temp->width-width/2-1;i++){
for(int n=-height/2;n<height/2+1;n++)
for(int m=-width/2;m<width/2+1;m++){
window[(n+height/2)*width+m+width/2]=cvGetReal2D(temp, j+n, i+m);
}
double pix=sort(window,width*height);
cvSetReal2D(dsttemp, j, i, pix);
}
}
for(int j=height/2;j<temp->height-height/2-1;j++){
for(int i=width/2;i<temp->width-width/2-1;i++){
double value=cvGetReal2D(dsttemp, j, i);
cvSetReal2D(dst, j-height/2, i-width/2, value);
}
}
free(window);
}
int findMedian(int *hist,int *movein,int *moveout,int movesize,int *cursor,int median,int t){
for(int i=0;i<movesize;i++){
hist[movein[i]]++;
hist[moveout[i]]--;
if(movein[i]<median)
(*cursor)++;
if(moveout[i]<median)
(*cursor)--;
}
if((*cursor)<t){
for(int i=median;i<GRAY_LEVEL;i++){
(*cursor)+=hist[i];
if(*cursor>=t+1){
(*cursor)-=hist[i];
return i;
}
}
}else if((*cursor)>t){
for(int i=median-1;i>=0;i--){
(*cursor)-=hist[i];
if(*cursor<=t){
return i;
}
}
}
else if ((*cursor)==t){
for(int i=median;i<GRAY_LEVEL;i++){
if(hist[i]>0)
return i;
}
}
return -1;
}
//初始化一行
int InitRow(IplImage *src,int *hist,int row,int *cursor,int win_width,int win_height){
int t=win_width*win_height/2+1;
*cursor=0;
for(int i=0;i<GRAY_LEVEL;i++)
hist[i]=0;
for(int j=-win_height/2;j<win_height/2+1;j++)
for(int i=0;i<win_width;i++){
int pixvalue=cvGetReal2D(src, j+row, i);
hist[pixvalue]++;
}
for(int i=0;i<GRAY_LEVEL;i++){
*cursor+=hist[i];
if(*cursor>=t){
*cursor-=hist[i];
return i;
}
}
return -1;
}
void MedianFilter(IplImage *src,IplImage *dst,int width,int height){
int hist[GRAY_LEVEL];
int median;
int *movein=(int *)malloc(sizeof(int)*height);
int *moveout=(int *)malloc(sizeof(int)*height);
double *dsttemp=(double *)malloc(sizeof(double)*src->width*src->height);
int t=width*height/2;
for(int j=height/2;j<src->height-height/2-1;j++){
int cursor=0;
median=InitRow(src, hist, j, &cursor, width, height);
dsttemp[j*src->width+width/2]=median;
for(int i=width/2+1;i<src->width-width/2-1;i++){
for(int k=-height/2;k<height/2+1;k++){
movein[k+height/2]=cvGetReal2D(src, j+k, i+width/2);
moveout[k+height/2]=cvGetReal2D(src, j+k, i-width/2-1);
}
median=findMedian(hist, movein, moveout, height, &cursor, median, t);
dsttemp[j*src->width+i]=median;
}
}
for(int j=0;j<src->height;j++){
for(int i=0;i<src->width;i++){
cvSetReal2D(dst, j, i, dsttemp[j*src->width+i]);
}
}
free(dsttemp);
free(movein);
free(moveout);
}
原文地址:http://blog.csdn.net/tonyshengtan/article/details/43307619