学习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