VC++高斯滤波\中值滤波实现图像模糊处理
2015-02-14 16:18
381 查看
一、算法
高斯模糊算法 详见:高斯模糊,基本思想就是利用高斯函数,将一个坐标点的所有邻域的加权平均值设置为这些点的颜色值。中值滤波算法就更简单了:将一个坐标点的所有邻域的平均值设置为这些点的像素值。
二、算法的代码实现
高斯函数:使用宏定义来替换:
#define PI<span style="white-space:pre"> </span>3.1415926 //高斯模糊函数 #define GAUSS_FUN(x, y) (exp(-(x*x)/(double)(2*y*y)))/(sqrt(2.0*PI)*y) #define SQUARE(x)<span style="white-space:pre"> </span>((x)*(x)) //暂且定义sigma为10 const double sigma=10;
高斯模糊算法处理像素
//高斯模糊,nRadius为平均取值的半径,半径越大,图像越模糊,处理时间也越长 bool GaussFilter( DWORD* pData, DWORD* pCopy, const int nWidth, const int nHeight, const int nRadius/*=1*/ ) { if ( nWidth<=0 || nHeight<=0 || nRadius<=0 ) return false; for ( int ny=0; ny<nHeight; ++ny ) { for ( int nx=0; nx<nWidth; ++nx ) { vector<COLOR_DATA> cdList; cdList.reserve(200); COLOR_DATA cd; double dTotal=0; for ( int m=nx-nRadius; m<=nx+nRadius; ++m ) { if ( m<0 || m>=nWidth ) continue; for ( int n=ny-nRadius; n<=ny+nRadius; ++n ) { if ( n<0 || n>=nHeight ) continue; cd.dDistance=GAUSS_FUN(sqrt((double)(SQUARE(m-nx)+SQUARE(n-ny))), sigma); dTotal+=cd.dDistance; cd.dwColor=*(pData+n*nWidth+m); cdList.push_back(cd); } } if ( cdList.size()>0 ) {//这里来计算整个邻域内所有像素点的加权平均值
std::vector<COLOR_DATA>::const_iterator itor=cdList.begin(); double r=0, g=0, b=0; for ( ; itor!=cdList.end(); ++itor ) { double dRate=itor->dDistance/dTotal;//距离中心点越远,权值越小 r+=GetRValue(itor->dwColor)*dRate; g+=GetGValue(itor->dwColor)*dRate; b+=GetBValue(itor->dwColor)*dRate; } *(pCopy+ny*nWidth+nx)=RGB((int)r, (int)g, (int)b); } } } return true; }中值滤波函数就很简单了,不细说
//中值滤波 bool MedianFilter( DWORD* pData, DWORD* pCopy, const int nWidth, const int nHeight, const int nRadius ) { if ( nWidth<=0 || nHeight<=0 || nRadius<=0 ) return false; for ( int ny=0; ny<nHeight; ++ny ) { for ( int nx=0; nx<nWidth; ++nx ) {//扫描每一个点的邻域,把他们的像素值保存起来。 vector<DWORD> data; for ( int m=nx-nRadius; m<=nx+nRadius; ++m ) { if ( m<0 || m>=nWidth || (m==nx) ) continue; for ( int n=ny-nRadius; n<=ny+nRadius; ++n ) { if ( n<0 || n>=nHeight || (n==ny) ) continue; data.push_back(*(pData+n*nWidth+m)); } } if ( data.size()>0 ) { std::sort(data.begin(), data.end());//排序 *(pCopy+ny*nWidth+nx)=data[data.size()/2];//取所有像素值的中值作为整个区域的像素值 } } } return true; }
线程函数中处理图像的像素,完成后发消息通知界面更新
DWORD __stdcall GaussThread(LPVOID lpParam) { HLOCAL hMem=LocalAlloc(LHND, g_lBmpSize); DWORD* pBuffer=(DWORD*)LocalLock(hMem); LONG lCopySize=::GetBitmapBits(g_hBitmap1, g_lBmpSize, pBuffer); HLOCAL hMemCopy=LocalAlloc(LHND, g_lBmpSize); DWORD* pBufferCopy=(DWORD*)LocalLock(hMemCopy); //MedianFilter(pBuffer, bmMetric.bmWidth, bmMetric.bmHeight, 1); //MedianFilter(pBuffer, pBufferCopy, g_nBmpWidth, g_nBmpHeight, 3); //MedianFilterRGB(pBuffer, pBufferCopy, g_nBmpWidth, g_nBmpHeight, 10); GaussFilter(pBuffer, pBufferCopy, g_nBmpWidth, g_nBmpHeight, 6); ::SetBitmapBits(g_hBitmap1, g_lBmpSize, pBufferCopy); LocalUnlock(hMem); LocalFree(hMem); LocalUnlock(hMemCopy); LocalFree(hMemCopy); ::PostMessage(g_hMainWnd, WM_GAUSS_MSG, 0, 0); return 0; }
三、程序运行效果图:
邻域距离为6时的高斯模糊处理效果:邻域距离为12时的高斯模糊处理效果:
邻域距离为24时的高斯模糊处理效果:
这时候,线程处理得花好几十秒时间了。
接着,对比中值滤波处理效果,邻域距离为6、12、24时的三张效果图分别为:
四、后记
对比效果图可以看出,高斯滤波模糊效果比较平滑,中值滤波则比较粗糙。当然了,高斯算法相对负责,其处理时也很花费的时间。相关文章推荐
- [图像处理] 高斯模糊的C++实现(Gaussian Blur)
- Android图像处理 - 高斯模糊的原理及实现
- 运动模糊图像处理(一)----- 模糊角度估计的算法研究及matlab实现
- Android图像处理 - 高斯模糊的原理及实现
- (转载)利用C语言实现计算机图像处理的方法
- 在Visual C#下实现图像的透明处理
- 文档图像处理系统的设计与实现
- 用于海洋搜救的多片DSP图像处理识别系统的实现
- 32位图像处理库 delphi简单实现(转贴)
- 图形处理 - 实现渐变色与图像叠加效果
- 如何实现C#.net图像处理
- Java实现数字图像处理的困惑
- 《Visual C++ 数字图像处理典型算法及实现》学习记录
- QT实现图像处理-傅立叶变换、傅立叶反变换、平滑、锐化与模板匹配
- VC++实现Contourlet图像处理
- 图像处理中聚类分析算法---C均值算法实现
- VC++实现Contourlet图像处理[转载自http://blog.sina.com.cn/aclon]支持原创
- “共轭变换”图像处理算法在FPGA 上实现的研究
- Visual C++实现视频图像处理技术
- OPENCV下针对IplImage实现图像增强处理