高效中值滤波

  • B5_450289
    了解作者
  • 42.4KB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-05-14 12:26
    上传日期
基于直方图的高效中值滤波算法,执行速度快,稍加修改即可生成最大值和最小值滤波算法。
test.rar
  • test
  • test.opt
    47.5KB
  • test.cpp
    8.2KB
  • 8u.bmp
    50.2KB
  • test.plg
    242B
  • test.dsw
    531B
  • test.dsp
    4.2KB
  • test.ncb
    49KB
内容介绍
#include <windows.h> #include <stdio.h> #include <iostream> #include <time.h> #include "cxcore.h" #include "cv.h" #include "highgui.h" using namespace std; #define WIDTH 208 //注意修改 #define HEIGHT 242 BYTE *Read8BitBmpFile2Img(const char * filename,int *width,int *height) { FILE *BinFile; BITMAPFILEHEADER FileHeader; BITMAPINFOHEADER BmpHeader; BYTE *pImg; unsigned int size; int Suc=1,w,h; // Open File *width=*height=0; if((BinFile=fopen(filename,"rb"))==NULL) return NULL; // Read Struct Info if (fread((void *)&FileHeader,1,sizeof(FileHeader),BinFile)!=sizeof(FileHeader)) Suc=-1; if (fread((void *)&BmpHeader,1,sizeof(BmpHeader),BinFile)!=sizeof(BmpHeader)) Suc=-1; if ( (Suc==-1) || (FileHeader.bfOffBits<sizeof(FileHeader)+sizeof(BmpHeader) ) ) { fclose(BinFile); return NULL; } // Read Image Data *width=w=(BmpHeader.biWidth+3)/4*4; *height=h=BmpHeader.biHeight; size=(BmpHeader.biWidth+3)/4*4*BmpHeader.biHeight; fseek(BinFile,FileHeader.bfOffBits,SEEK_SET); if ( (pImg=new BYTE[size])!=NULL) { for(int i=0;i<h;i++) // 0,1,2,3,4(5): 400-499 { if (fread(pImg+(h-1-i)*w,sizeof(BYTE),w,BinFile)!=w) { fclose(BinFile); delete pImg; pImg=NULL; return NULL; } } } fclose(BinFile); return pImg; } bool WriteByteImg2BmpFile(BYTE *pImg,int width,int height,const char * filename) // 当宽度不是4的倍数时自动添加成4的倍数 { FILE * BinFile; BITMAPFILEHEADER FileHeader; BITMAPINFOHEADER BmpHeader; int i,extend; bool Suc=true; BYTE p[4],*pCur; // Open File if((BinFile=fopen(filename,"w+b"))==NULL) { return false; } // Fill the FileHeader FileHeader.bfType= ((WORD) ('M' << 8) | 'B'); FileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*4L; FileHeader.bfSize=FileHeader.bfOffBits+width*height ; FileHeader.bfReserved1=0; FileHeader.bfReserved2=0; if (fwrite((void *)&FileHeader,1,sizeof(FileHeader),BinFile)!=sizeof(FileHeader)) Suc=false; // Fill the ImgHeader BmpHeader.biSize = 40; BmpHeader.biWidth = width; BmpHeader.biHeight = height; BmpHeader.biPlanes = 1 ; BmpHeader.biBitCount = 8 ; BmpHeader.biCompression = 0 ; BmpHeader.biSizeImage = 0 ; BmpHeader.biXPelsPerMeter = 0; BmpHeader.biYPelsPerMeter = 0; BmpHeader.biClrUsed = 0; BmpHeader.biClrImportant = 0; if (fwrite((void *)&BmpHeader,1,sizeof(BmpHeader),BinFile)!=sizeof(BmpHeader)) Suc=false; // write Pallete for (i=0,p[3]=0;i<256;i++) { p[3]=0; p[0]=p[1]=p[2]=i; // blue,green,red; if (fwrite((void *)p,1,4,BinFile)!=4) { Suc=false; break; } } // write image data extend=(width+3)/4*4-width; if (extend==0) { for(pCur=pImg+(height-1)*width;pCur>=pImg;pCur-=width) { if (fwrite((void *)pCur,1,width,BinFile)!=(unsigned int)width) Suc=false; // 真实的数据 } } else { for(pCur=pImg+(height-1)*width;pCur>=pImg;pCur-=width) { if (fwrite((void *)pCur,1,width,BinFile)!=(unsigned int)width) Suc=false; // 真实的数据 for(i=0;i<extend;i++) // 扩充的数据 if (fwrite((void *)(pCur+width-1),1,1,BinFile)!=1) Suc=false; } } // return; fclose(BinFile); return Suc; } void max_filter(BYTE *pImg,int m,int n) { int th=m*n-1,lt_med,L,C,i,j,lt_mpre; BYTE med,*pCur,resImg[HEIGHT][WIDTH],medpre; unsigned int H[256],h[256]; memset(H,0,sizeof(int)*256); //求第一个m*n窗口的直方图 for(i=0;i<m;i++) { for(pCur=pImg+i*WIDTH,j=0;j<n;j++) { H[*(pCur)]++; pCur++; } } //求出med及lt_med for(med=255,lt_med=0;lt_med<=th;med--) { lt_med+=H[med]; if (H[med]) break; } for(L=0,C=0;L+m<=HEIGHT;L++,C=0)//纵向循环(大循环) { if(L)//第一个窗口不能下移,应直接跳到下面做横向处理 { lt_med=lt_mpre; med=medpre; for(pCur=pImg+(L-1)*WIDTH,j=0;j<n;j++) { if(*pCur<=med)lt_med--; H[*(pCur++)]--; } for(pCur=pImg+(L+m-1)*WIDTH,j=0;j<n;j++) { if(*pCur<=med)lt_med++; H[*(pCur++)]++; } while(lt_med>th) lt_med-=H[med--]; while(lt_med<=th) lt_med+=H[++med]; } lt_mpre=lt_med; medpre=med; //求得的中值先赋给resImg,以免破坏pImg的数据 resImg[L+m/2][n/2]=med; memcpy(h,H,sizeof(int)*256); while((++C)+n<=WIDTH)//横向循环(小循环) { for(pCur=pImg+L*WIDTH+C-1,i=0;i<m;i++,pCur+=WIDTH) { h[*pCur]--; if(*pCur<=med)lt_med--; } for(pCur=pImg+L*WIDTH+C+n-1,i=0;i<m;i++,pCur+=WIDTH) { h[*pCur]++; if(*pCur<=med)lt_med++; } while(lt_med>th) lt_med-=h[med--]; while(lt_med<=th) lt_med+=h[++med]; resImg[L+m/2][C+n/2]=med; } } int rWIDTH=WIDTH-(n/2)*2; for(i=m/2;i<HEIGHT-m/2;i++) memcpy(pImg+i*WIDTH+n/2,&resImg[i][n/2],rWIDTH); } void min_filter(BYTE *pImg,int m,int n) { int th=0,lt_min,L,C,i,j,lt_mpre; BYTE min,*pCur,resImg[HEIGHT][WIDTH],minpre; unsigned int H[256],h[256]; memset(H,0,sizeof(int)*256); //求第一个m*n窗口的直方图 for(i=0;i<m;i++) { for(pCur=pImg+i*WIDTH,j=0;j<n;j++) { H[*(pCur)]++; pCur++; } } //求出min及lt_min for(min=0,lt_min=H[0];lt_min<=th;min++) { lt_min+=H[min]; if (H[min]) break; } for(L=0,C=0;L+m<=HEIGHT;L++,C=0)//纵向循环(大循环) { if(L)//第一个窗口不能下移,应直接跳到下面做横向处理 { lt_min=lt_mpre; min=minpre; for(pCur=pImg+(L-1)*WIDTH,j=0;j<n;j++) { if(*pCur<=min)lt_min--; H[*(pCur++)]--; } for(pCur=pImg+(L+m-1)*WIDTH,j=0;j<n;j++) { if(*pCur<=min)lt_min++; H[*(pCur++)]++; } while(lt_min>th) lt_min-=H[min--]; while(lt_min<=th) lt_min+=H[++min]; } lt_mpre=lt_min; minpre=min; //求得的中值先赋给resImg,以免破坏pImg的数据 resImg[L+m/2][n/2]=min; memcpy(h,H,sizeof(int)*256); while((++C)+n<=WIDTH)//横向循环(小循环) { for(pCur=pImg+L*WIDTH+C-1,i=0;i<m;i++,pCur+=WIDTH) { h[*pCur]--; if(*pCur<=min)lt_min--; } for(pCur=pImg+L*WIDTH+C+n-1,i=0;i<m;i++,pCur+=WIDTH) { h[*pCur]++; if(*pCur<=min)lt_min++; } while(lt_min>th) lt_min-=h[min--]; while(lt_min<=th) lt_min+=h[++min]; resImg[L+m/2][C+n/2]=min; } } int rWIDTH=WIDTH-(n/2)*2; for(i=m/2;i<HEIGHT-m/2;i++) memcpy(pImg+i*WIDTH+n/2,&resImg[i][n/2],rWIDTH); } void mid_filter(BYTE *pImg,int m,int n) { int th=m*n/2,lt_med,L,C,i,j,lt_mpre; BYTE med,*pCur,resImg[HEIGHT][WIDTH],medpre; unsigned int H[256],h[256]; memset(H,0,sizeof(int)*256); //求第一个m*n窗口的直方图 for(i=0;i<m;i++) { for(pCur=pImg+i*WIDTH,j=0;j<n;j++) { H[*(pCur)]++; pCur++; } } //求出med及lt_med for(med=0,lt_med=H[0];lt_med<=th;) lt_med+=H[++med]; for(L=0,C=0;L+m<=HEIGHT;L++,C=0)//纵向循环(大循环) { if(L)//第一个窗口不能下移,应直接跳到下面做横向处理 { lt_med=lt_mpre; med=medpre; for(pCur=pImg+(L-1)*WIDTH,j=0;j<n;j++) { if(*pCur<=med)lt_med--; H[*(pCur++)]--; } for(pCur=pImg+(L+m-1)*WIDTH,j=0;j<n;j++) { if(*pCur<=med)lt_med++; H[*(pCur++)]++; } while(lt_med>th) lt_med-=H[med--]; while(lt_med<=th) lt_med+=H[++med]; } lt_mpre=lt_med; medpre=med; //求得的中值先赋给resImg,以免破坏pImg的数据 resImg[L+m/2][n/2]=med; memcpy(h,H,sizeof(int)*256); while((++C)+n<=WIDTH)//横向循环(小循环) { for(pCur=pImg+L*WIDTH+C-1,i=0;i<m;i++,pCur+=WIDTH) { h[*pCur]--; if(*pCur<=med)lt_med--; } for(pCur=pImg+L*WIDTH+C+n-1,i=0;i<m;i++,pCur+=WIDTH) { h[*pCur]++; if(*pCur<=med)lt_med++; } while(lt_med>th) lt_med-=h[med--]; while(lt_med<=th) lt_med+=h[++med]; resImg[L+m/2][C+n/2]=med; } } int rWIDTH=WIDTH-(n/2)*2; for(i=m/2;i<HEIGHT-m/2;i++) memcpy(pImg+i*WIDTH+n/2,&resImg[i][n/2],rWIDTH
评论