快速中值滤波算法
南昌大学实验报告
学生姓名: 洪僡婕 学 号: 6100411159 专业班级: 数媒111班 实验类型:■ 验证 □ 综合 □ 设计 □ 创新 实验日期: 4.29 实验成绩:
一、实验项目名称
数字图像处理
二、实验目的
实现快速中值滤波算法
三、实验内容
用VC++实现中值滤波的快速算法
四、主要仪器设备及耗材
PC机一台
五、实验步骤
// ImageProcessingDoc.cpp : implementation of the CImageProcessingDoc class// #include \"stdafx.h\"
#include \"ImageProcessing.h\" #include \"ImageProcessingDoc.h\" #include \"GreyRatio.h\" #include #define PI (acos(0.0) * 2) #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CImageProcessingDoc IMPLEMENT_DYNCREATE(CImageProcessingDoc, CDocument) BEGIN_MESSAGE_MAP(CImageProcessingDoc, CDocument) //{{AFX_MSG_MAP(CImageProcessingDoc) ON_COMMAND(ID_HISTOGRAM_ADJUSTIFCATION, OnHistogramAdjustifcation) ON_COMMAND(ID_FFT, OnFft) ON_COMMAND(ID_SALT_PEPPER_NOICE, OnSaltPepperNoice) ON_COMMAND(ID_RANDOM_NOISE, OnRandomNoise) ON_COMMAND(ID_MEDIAN_FILTERING, OnMedianFiltering) ON_COMMAND(ID_DCT, OnDct) ON_COMMAND(ID_FWT, OnFwt) ON_COMMAND(ID_DHT, OnDht) ON_COMMAND(ID_WAVELET_TRANSFORM, OnWaveletTransform) ON_COMMAND(ID_GREY_ADJUSTIFCATION, OnGreyAdjustifcation) ON_COMMAND(ID_GREY_LINEAR_ADJUSTIFCATION, OnGreyLinearAdjustifcation) ON_COMMAND(ID_GREY_SEGLINEAR_ADJUSTIFCATION, OnGreySeglinearAdjustifcation) ON_COMMAND(ID_2DGRAD, On2dgrad) ON_COMMAND(ID_ROBERT, OnRobert) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CImageProcessingDoc construction/destruction CImageProcessingDoc::CImageProcessingDoc(){ // TODO: add one-time construction code here mImageFile = NULL; bFileIsLoad = FALSE; nRows = 256; nCols = 256; mSourceData = NULL; pSourceData = NULL; bDataIsProcessed = FALSE; mResultData = FALSE; pResultData = FALSE; FourierDataR = NULL; FourierDataI = NULL; } CImageProcessingDoc::~CImageProcessingDoc(){ } BOOL CImageProcessingDoc::OnNewDocument(){ if (!CDocument::OnNewDocument()) return FALSE; // TODO: add reinitialization code here // (SDI documents will reuse this document) return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CImageProcessingDoc serialization void CImageProcessingDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: add storing code here } else{ // TODO: add loading code here } } ///////////////////////////////////////////////////////////////////////////// // CImageProcessingDoc diagnostics #ifdef _DEBUG void CImageProcessingDoc::AssertValid() const{ CDocument::AssertValid(); } void CImageProcessingDoc::Dump(CDumpContext& dc) const{ CDocument::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CImageProcessingDoc commands BOOL CImageProcessingDoc::OnOpenDocument(LPCTSTR lpszPathName) { int x; int y; if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE; // TODO: Add your specialized creation code here if(mSourceData) { free(mSourceData); mSourceData = NULL; } if (!(mSourceData = (unsigned char *)malloc(nRows*nCols*sizeof(unsigned char)))) return FALSE; if (pSourceData) { free(pSourceData); pSourceData = NULL; } if (!(pSourceData = (unsigned char *)malloc(3*nRows*nCols*sizeof(unsigned char)))) return FALSE; if (mResultData) { free(mResultData); mResultData = NULL; } if (!(mResultData = (unsigned char *)malloc(nRows*nCols*sizeof(unsigned char)))) return FALSE; if (pResultData) { free(pResultData); pResultData = NULL; } if (!(pResultData = (unsigned char *)malloc(3*nRows*nCols*sizeof(unsigned char)))) return FALSE; if (mImageFile) { fclose(mImageFile); mImageFile = NULL; } if (!(mImageFile = fopen(lpszPathName,\"rb\"))){ free(mSourceData); return FALSE; } if (fread(mSourceData,sizeof(unsigned char),nRows*nCols,mImageFile) != (unsigned)nCols*nRows) { free(mSourceData); fclose(mImageFile); mImageFile = NULL; bFileIsLoad = false; return FALSE; } for(y = 0; y < nRows; y++){ for(x = 0; x < nCols; x++){ pSourceData[3*y*nCols+3*x] = mSourceData[y*nCols+x]; pSourceData[3*y*nCols+3*x+1] = mSourceData[y*nCols+x]; pSourceData[3*y*nCols+3*x+2] = mSourceData[y*nCols+x]; } bFileIsLoad = TRUE; return TRUE; } void CImageProcessingDoc::OnHistogramAdjustifcation(){ // TODO: Add your command handler code here int x,y; double *mR; double *mS; mR = new double[256]; mS = new double[256]; for(x=0;x<256;x++){ mR[x] = mS[x] = 0.0; } //统计直方图 for(y = 0; y < nRows; y++){ for(x = 0; x < nCols; x++){ mR[mSourceData[y*nCols+x]] ++; } for(x=0;x<256;x++){ for(y=0;y for(y = 0; y < nRows; y++) for(x = 0; x < nCols; x++) mResultData[y*nRows+x] = (char) (255* mS[mSourceData[y*nRows+x]]); //灰度计算 for(y = 0; y < nRows; y++){ for(x = 0; x < nCols; x++){ pResultData[3*y*nCols+3*x] = mResultData[y*nCols+x]; pResultData[3*y*nCols+3*x+1] = mResultData[y*nCols+x]; pResultData[3*y*nCols+3*x+2] = mResultData[y*nCols+x]; } //更新显示 UpdateAllViews(NULL); } // FFTandIFFT 一维傅立叶变换与逆变换函数 // 输入时域数据实部Tr,虚部Ti // 输出频域数据实部Tr,虚部Ti // 序列长度N,N等于2的r次幂 // FFTorIFFT,逻辑变量,非零做正变换,零做反变换 void CImageProcessingDoc::FFTandIFFT(float *Tr, float *Ti, int N, bool FFTorIFFT) { int r; //迭代次数 int l,j,k;//循环变量 int p; //用于蝶形计算加权系数的指数 int B; //对偶结点距离 float X,Y,XX,YY; float w; float cosw,sinw; if (!FFTorIFFT) { //如果做傅立叶逆变换,则必须对数列除以N for(l=0;l for (i=1;i j = j + k; if (i<=j) { temp = Tr[i]; Tr[i] = Tr[j]; Tr[j] = temp; temp = Ti[i]; Ti[i] = Ti[j]; Ti[j] = temp; } } for(l=0; l <= r; l++) //共r级{ B = 1<<(l-1); // 第l层对偶结点距离为2^(l-1) for(j=0; j < B;j++){ p = j*(1<<(r-l)); w = 2*PI*p/N; for(k=j;k else{ //傅立叶反变换 cosw =cos(w); sinw =sin(w); } X * sinw; Y * cosw; XX = Tr[k] - Tr[k+B]*cosw + Ti[k+B] * sinw; YY * cosw; Ti[k] = Y; Tr[k+B] = XX; Ti[k+B] = YY; } } } = Tr[k] + Tr[k+B]*cosw - Ti[k+B] = Ti[k] + Tr[k+B]*sinw + Ti[k+B] = Ti[k] - Tr[k+B]*sinw - Ti[k+B] Tr[k] = X; } void CImageProcessingDoc::OnFft(){ // TODO: Add your command handler code here int i,j; int ii,jj; float temp; float *Tr; float *Ti; Tr = new float[nCols]; Ti = new float[nCols]; if ( FourierDataR) { delete FourierDataR; FourierDataR = NULL; } if ( FourierDataI) { delete FourierDataI; FourierDataR = NULL; } FourierDataR = new float[nRows*nCols]; FourierDataI = new float[nRows*nCols]; for(i=0;i FourierDataR[i*nCols+j] = (float) mSourceData[i*nCols+j]; FourierDataI[i*nCols+j] = 0.0; } for (i=0;i FFTandIFFT(Tr,Ti,nCols,1); for (j=0;j delete Tr; delete Ti; Tr = new float[nRows]; Ti = new float[nRows]; for(j=0;j FFTandIFFT(Tr,Ti,nRows,1); for (i=0;i for (i=0;i if(temp > 255.0) temp = 255.0; ii = nRows - 1 - (i pResultData[3*ii*nCols+3*jj+1] = (int) temp; pResultData[3*ii*nCols+3*jj+2] = (int) temp; } //更新显示 UpdateAllViews(NULL); delete FourierDataR; delete FourierDataI; FourierDataI = NULL; FourierDataR = NULL; return; } void CImageProcessingDoc::OnSaltPepperNoice(){ // TODO: Add your command handler code here // TODO: Add your command handler code here int x; int y; Salt_Pepper_Noise(mSourceData,nCols,nRows); for(y = 0; y < nRows; y++){ for(x = 0; x < nCols; x++){ pSourceData[3*y*nCols+3*x] = (unsigned char) mSourceData[y*nCols+x]; pSourceData[3*y*nCols+3*x+1] = (unsigned char) mSourceData[y*nCols+x]; pSourceData[3*y*nCols+3*x+2] = (unsigned char) mSourceData[y*nCols+x]; } UpdateAllViews(NULL); } void CImageProcessingDoc::OnRandomNoise(){ // TODO: Add your command handler code here int x; int y; Random_Noise(mSourceData,nRows,nCols); for(y = 0; y < nRows; y++){ for(x = 0; x < nCols; x++){ pSourceData[3*y*nCols+3*x] = (unsigned char) mSourceData[y*nCols+x]; pSourceData[3*y*nCols+3*x+1] = (unsigned char) mSourceData[y*nCols+x]; pSourceData[3*y*nCols+3*x+2] = (unsigned char) mSourceData[y*nCols+x]; } UpdateAllViews(NULL); } void CImageProcessingDoc::Salt_Pepper_Noise(unsigned char *mdata, int nHeight, int nWidth) { unsigned char* lpSrc; //循环变量 long i; long j; //生成伪随机种子 srand((unsigned)time(NULL)); //在图像中加噪 for (j = 0;j < nHeight ;j++){ for(i = 0;i < nWidth ;i++){ if(rand()>31500) { // 指向源图像倒数第j行,第的指针 lpSrc = (unsigned char *)&mdata[j*nWidth + i]; //图像中当前点置为黑 *lpSrc = 0; } } i个象素 } // 返回 return ; } void CImageProcessingDoc::Random_Noise(unsigned char *mdata, int nHeight, int nWidth) { // 指向源图像的指针 unsigned char* lpSrc; //循环变量 long i; long j; //像素值 unsigned char pixel; //噪声 BYTE NoisePoint; //生成伪随机种子 srand((unsigned)time(NULL)); //在图像中加噪 for (j = 0;j < nHeight ;j++){ for(i = 0;i < nWidth ;i++){ NoisePoint=rand()/1024; // 指向源图像倒数第j行,第i个象素的指针 lpSrc = (unsigned char *)&mdata[nWidth * j + i]; //取得像素值 pixel = (unsigned char)*lpSrc; *lpSrc = (unsigned char)(pixel*224/256 + NoisePoint); } }// 返回 return ; } void CImageProcessingDoc::MedianFiltering(unsigned char *sourcedata, unsigned char *resultdata,int nHeight, int nWidth, int nR){ int i,j,m,n,r; unsigned tmp; unsigned char* mdata = new unsigned char[(2*nR+1)*(2*nR+1)]; for (i=0;i resultdata[i*nWidth+j] = 0; else { for(m=-nR;m<=nR;m++) for(n=-nR;n<=nR;n++) mdata[(m+nR)*(2*nR+1)+n+nR] =sourcedata[(i+m)*nWidth+(j+n)]; //排序 for(m=0;m<(2*nR+1)*(2*nR+1)-2;m++){ r = 1; for (n=m+1;n<(2*nR+1)*(2*nR+1);n++){ if (mdata[n] mResultData[i*nWidth+j] = mdata[nR*(2*nR+1)+nR]; } } } void CImageProcessingDoc::OnMedianFiltering() { // TODO: Add your command handler code here int x; int y; MedianFiltering(mSourceData,mResultData,nRows,nCols,1); for(y = 0; y < nRows; y++){ for(x = 0; x < nCols; x++){ pResultData[3*y*nCols+3*x] = (unsigned char) mResultData[y*nCols+x]; pResultData[3*y*nCols+3*x+1] = (unsigned char) mResultData[y*nCols+x]; pResultData[3*y*nCols+3*x+2] = (unsigned char) mResultData[y*nCols+x]; } UpdateAllViews(NULL); } void CImageProcessingDoc::OnDct() { // TODO: Add your command handler code here } void CImageProcessingDoc::OnFwt() { // TODO: Add your command handler code here } void CImageProcessingDoc::OnDht() { // TODO: Add your command handler code here } void CImageProcessingDoc::OnWaveletTransform() { // TODO: Add your command handler code here } void CImageProcessingDoc::OnGreyAdjustifcation() { // TODO: Add your command handler code here } void CImageProcessingDoc::OnGreyLinearAdjustifcation() { // TODO: Add your command handler code here int x; int y; int tmp; CGreyRatio mdlg; mdlg.DoModal(); for(y=0;y tmp = tmp>255?255:tmp; pResultData[3*y*nCols+3*x] = tmp; pResultData[3*y*nCols+3*x+1] = tmp; pResultData[3*y*nCols+3*x+2] = tmp; } UpdateAllViews(NULL); } void CImageProcessingDoc::OnGreySeglinearAdjustifcation() { // TODO: Add your command handler code here } void CImageProcessingDoc::On2dgrad() { // TODO: Add your command handler code here int x; int y; int dx; int dy; int tmp; for(y=0;y dy = mSourceData[y*nCols+x] - mSourceData[(y+1)*nCols+x]; tmp = (int) sqrt(dx*dx+dy*dy); tmp = tmp>255?255:tmp; pResultData[3*y*nCols+3*x] = tmp; pResultData[3*y*nCols+3*x+1] = tmp; pResultData[3*y*nCols+3*x+2] = tmp; } UpdateAllViews(NULL); } void CImageProcessingDoc::OnRobert() { // TODO: Add your command handler code here int x; int y; int dx; int dy; int tmp; for(y=0;y tmp = (int) sqrt(dx*dx+dy*dy); tmp = tmp>255?255:tmp; pResultData[3*y*nCols+3*x] = tmp; pResultData[3*y*nCols+3*x+1] = tmp; pResultData[3*y*nCols+3*x+2] = tmp; } UpdateAllViews(NULL); } void CImageProcessingDoc::DCTandIDCT(float *Ff, int N, bool bDctIDct){ float *mR; float *mI; int i; float Ff0 = 0; mR = new float[N*2]; mI = new float[N*2]; if(bDctIDct){ for(i=0;i<2*N;i++){ if(i mR[i] = 0; mI[i] = 0; } for(i=0;i for(i=0;i<2*N;i++){ if(i mR[i] = 0; mI[i] = 0; } } for(i=0;i 六、实验数据 七、思考及体会 在设计算法编制程序的时候,我们充分考虑到程序运行的时间复杂度和 空间复杂度问题,在解决问题的前提下,使算法尽量简单,使程序运行占有的空间尽量的小,这样来减少不必要的时问浪费和空间浪费,从而太大的提高程 序执行的效率。采用迭代,逐次逼近的方法得到本次的中值,在一行处理完毕后转人下一行也采用走S型的方法.这样除第一个窗口采用了一伏排序得到中值外,其它的窗口都利用上伏的窗口的象素删除无用的3个象素后再加人新的3个象素,利用迭代的方法得到本次窗口的中值.这样太大地提高了程序执行的效率。本实验充分考虑到程序运行的时间复杂度和空间复杂度问题。解决了图象大而内存不足的问题。对中值滤波的普通算法采用一般的常规算法,而对其快速算法采用走S型并且迭代的方法。采用对程序运行计时的方法.对中值滤波的快速算法和普通算法进行精确的比较,结论可靠。 因篇幅问题不能全部显示,请点此查看更多更全内容