First, the algorithm
Gaussian blur algorithm see: Gaussian blur, the basic idea is to use the Gaussian function, a coordinate point of all the neighborhood of the weighted average value of these points are set to the color values.
The median filter algorithm is simpler: Set the average of all neighborhoods of a coordinate point to the pixel values of those points.
Second, the code implementation of the algorithm
Gaussian function:
To replace with a macro definition:
#define Pi<span style= "White-space:pre" ></span>3.1415926//Gaussian blur function # 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))// For the moment, define Sigma as 10const double sigma=10;
Gaussian blur algorithm for processing pixels
//Gaussian Blur, Nradius is the radius of the average value, the greater the radius, the more blurred the image, the longer the processing time 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) ;d total+=cd.ddistance;cd.dwcolor=* (pdata+n*nwidth+m); Cdlist.push_back (CD);}} if (Cdlist.size () >0) {//here to calculate the weighted average of all pixels within the entire neighborhood
Std::vector<color_data>::const_iterator itor=cdlist.begin ();d ouble r=0, g=0, B=0;for (; Itor!=cdList.end (); + + Itor) {Double drate=itor->ddistance/dtotal;//the farther away from the center point, the smaller the weight 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;}
The median filter function is very simple, not to elaborate
Median filter bool Medianfilter (dword* pData, dword* pcopy, const int nwidth, const int nheight, const int Nradius) {if (nwidth& lt;=0 | | nheight<=0 | | nradius<=0) return false;for (int ny=0; ny<nheight; ++ny) {for (int nx=0; nx<nwidth; ++nx) {//scans the neighborhood of each point, putting their pixel values Save them. 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 ());//Sort * (PCOPY+NY*NWIDTH+NX) =data[data.size ()/2];// Takes the median value of all pixel values as the pixel value for the entire region}}}return true;
The pixel in the thread function that processes the image, and updates the message notification interface after completion
DWORD __stdcall Gaussthread (lpvoid lpparam) {hlocal hmem=localalloc (lhnd, g_lbmpsize);D word* pbuffer= (DWORD*) LocalLock (HMEM); LONG lcopysize=::getbitmapbits (G_hbitmap1, G_lbmpsize, pbuffer); Hlocal Hmemcopy=localalloc (LHND, g_lbmpsize);D word* 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);::P ostmessage (G_hmainwnd, wm_gauss_msg, 0, 0); return 0;}
Three, the program operation: the neighborhood distance is 6 o'clock Gaussian blur processing effect:
Gaussian blur effect with a neighborhood distance of 12 o'clock:
Gaussian blur effect with a neighborhood distance of 24 o'clock:
At this point, threading takes several 10 seconds to process.
Then, compared with the median filter processing effect, the neighborhood distance is 6, 12, 24 o'clock of three, respectively:
Iv. PostScript
The comparison shows that the Gaussian filter blur effect is smoother and median filter is coarse. Of course, the Gaussian algorithm is relatively responsible for the time it takes to process it.
Fuzzy processing of image with VC + + Gaussian filter and median filter