Quick Gaussian filter function [improved version]
Corrected and optimized the variables. Previously, the author's function only supports 2nd-power images. This correction (the bitmap row width in windows is 4-byte aligned ).
It is basically perfect, but in some conditions, the bottom edge of the Y direction will still be biased. The reason cannot be found at the moment. I hope someone will remind me.
The function structure is quite clear and easy to read.
Int gauss_blur (byte_t * image, // bitmap data int linebytes, // bitmap row bytes, BMP data is 4 bytes aligned in windows. Otherwise, int width, // bitmap width int height, // bitmap height int cbyte, // Number of Color Channels float sigma // Gaussian coefficient will be involved when processing non-quadratic power images) {int x = 0, y = 0, n = 0; int channel = 0; int srcline = 0, dstline = 0; int channelsize = width * height; int bufsize = width> height? Width + 4: height + 4; float * w1 = NULL, * w2 = NULL, * imgbuf = NULL; int time = 0; # if defined (_ INC_WINDOWS) time = GetTickCount (); # elif defined (_ CLOCK_T) time = clock (); # endifw1 = (float *) malloc (bufsize * sizeof (float); if (! W1) {return-1;} w2 = (float *) malloc (bufsize * sizeof (float); if (! W2) {free (w1); return-1;} imgbuf = (float *) malloc (channelsize * sizeof (float); if (! Imgbuf) {free (w1); free (w2); return-1 ;}// ------------------ calculate Gaussian Kernel --------------------------------------- // float q = 0; float q2 = 0, q3 = 0; float b0 = 0, b1 = 0, b2 = 0, b3 = 0; float B = 0; if (sigma> = 2.5f) {q = 0.98711f * sigma-0.96330f;} else if (sigma> = 0.5f) & (sigma <2.5f) {q = 3.97156f-4.14554f * (float) sqrt (1.0f-0.26891f * sigma);} else {q = 0.1147705018520355224609375f;} q2 = q * q; q3 = q * q2; b0 = (1.57825 + (2.44413f * q) + (1.4281f * q2) + (0.422205f * q3); b1 = (2.44413f * q) + (2.85619f * q2) + (1.26661f * q3 )); b2 = (-(1.4281f * q2) + (1.26661f * q3); b3 = (0.422205f * q3 )); B = 1.0-(b1 + b2 + b3)/b0); b1/= b0; b2/= b0; b3/= b0; // ---------------- calculate the Gaussian Kernel end ----------------------------------------- // multiple channels for image processing (channel = 0; channel <cbyte; ++ channel) {// obtain all the pixel values of a channel and pre-process for (y = 0; y
= 0; -- y) {(imgbuf + x) [y * width] = w2 [y] = B * w1 [y + 3] + (b1 * w2 [y + 1] + b2 * w2 [y + 2] + b3 * w2 [y + 3]) ;}} // perform horizontal processing for (y = 0; y
= 0; -- x) {// (imgbuf + dstline) [x] = w2 [x] = B * w1 [x + 3] + (b1 * w2 [x + 1] + b2 * w2 [x + 2] + b3 * w2 [x + 3]); w2 [x] = B * w1 [x + 3] + (b1 * w2 [x + 1] + b2 * w2 [x + 2] + b3 * w2 [x + 3 ]); // store the returned data (image + dstline) [x * cbyte + channel] = w2 [x]-1 ;}} // vertical processing/* // storage processing channel for (int y = 0; y