/******************************************************************************* * PROCEDURE: gaussian_smooth * PURPOSE: Blur an image with a gaussian filter. * NAME: Mike Heath * DATE: 2/15/96 *******************************************************************************/ void gaussian_smooth(double *image, int rows, int cols, double sigma) { int r, c, rr, cc, /* Counter variables. */ windowsize, /* Dimension of the gaussian kernel. */ center; /* Half of the windowsize. */ double *tempim, /* Buffer for separable filter gaussian smoothing. */ *kernel, /* A one dimensional gaussian kernel. */ dot, /* Dot product summing variable. */ sum; /* Sum of the kernel weights variable. */ /**************************************************************************** * Create a 1-dimensional gaussian smoothing kernel. ****************************************************************************/ make_gaussian_kernel(sigma, &kernel, &windowsize); center = windowsize / 2; /**************************************************************************** * Allocate a temporary buffer image and the smoothed image. ****************************************************************************/ if((tempim = mxCalloc(rows*cols, sizeof(double))) == NULL){ mexErrMsgTxt("Memory allocation failed for the buffer image !"); } /**************************************************************************** * Blur in the x - direction. ****************************************************************************/ for(r=0;r<rows;r++){ for(c=0;c<cols;c++){ dot = 0.0; sum = 0.0; for(cc=(-center);cc<=center;cc++){ if(((c+cc) >= 0) && ((c+cc) < cols)){ dot += image[r*cols+(c+cc)] * kernel[center+cc]; sum += kernel[center+cc]; } } tempim[r*cols+c] = dot/sum; } } /**************************************************************************** * Blur in the y - direction. ****************************************************************************/ for(c=0;c<cols;c++){ for(r=0;r<rows;r++){ sum = 0.0; dot = 0.0; for(rr=(-center);rr<=center;rr++){ if(((r+rr) >= 0) && ((r+rr) < rows)){ dot += tempim[(r+rr)*cols+c] * kernel[center+rr]; sum += kernel[center+rr]; } } image[r*cols+c] = dot/sum; } } mxFree(tempim); mxFree(kernel); }
void gaussian_smooth(unsigned char *image, int rows, int cols, short int **smoothedim) { int r, c, rr, cc, /* Counter variables. */ windowsize, /* Dimension of the gaussian kernel. */ center; /* Half of the windowsize. */ float *tempim, /* Buffer for separable filter gaussian smoothing. */ *kernel, /* A one dimensional gaussian kernel. */ dot, /* Dot product summing variable. */ sum; /* Sum of the kernel weights variable. */ float sigma; sigma = SIGMA; make_gaussian_kernel(sigma, &kernel, &windowsize); center = windowsize / 2; tempim = (float *) calloc(rows*cols, sizeof(float)); (*smoothedim) = (short int *) calloc(rows*cols, sizeof(short int)); for(r=0;r<rows;r++){ for(c=0;c<cols;c++){ dot = 0.0; sum = 0.0; for(cc=(-center);cc<=center;cc++){ if(((c+cc) >= 0) && ((c+cc) < cols)){ dot += (float)image[r*cols+(c+cc)] * kernel[center+cc]; sum += kernel[center+cc]; } } tempim[r*cols+c] = dot/sum; } } for(c=0;c<cols;c++){ for(r=0;r<rows;r++){ sum = 0.0; dot = 0.0; for(rr=(-center);rr<=center;rr++){ if(((r+rr) >= 0) && ((r+rr) < rows)){ dot += tempim[(r+rr)*cols+c] * kernel[center+rr]; sum += kernel[center+rr]; } } (*smoothedim)[r*cols+c] = (short int)(dot*BOOSTBLURFACTOR/sum + 0.5); } } free(tempim); free(kernel); }
static GstFlowReturn gst_gaussianblur_transform_frame (GstVideoFilter * vfilter, GstVideoFrame * in_frame, GstVideoFrame * out_frame) { GstGaussianBlur *filter = GST_GAUSSIANBLUR (vfilter); GstClockTime timestamp; gint64 stream_time; gfloat sigma; guint8 *src, *dest; /* GstController: update the properties */ timestamp = GST_BUFFER_TIMESTAMP (in_frame->buffer); stream_time = gst_segment_to_stream_time (&GST_BASE_TRANSFORM (filter)->segment, GST_FORMAT_TIME, timestamp); GST_DEBUG_OBJECT (filter, "sync to %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp)); if (GST_CLOCK_TIME_IS_VALID (stream_time)) gst_object_sync_values (GST_OBJECT (filter), stream_time); GST_OBJECT_LOCK (filter); sigma = filter->sigma; GST_OBJECT_UNLOCK (filter); if (filter->cur_sigma != sigma) { g_free (filter->kernel); filter->kernel = NULL; g_free (filter->kernel_sum); filter->kernel_sum = NULL; filter->cur_sigma = sigma; } if (filter->kernel == NULL && !make_gaussian_kernel (filter, filter->cur_sigma)) { GST_ELEMENT_ERROR (filter, RESOURCE, NO_SPACE_LEFT, ("Out of memory"), ("Failed to allocation gaussian kernel")); return GST_FLOW_ERROR; } /* * Perform gaussian smoothing on the image using the input standard * deviation. */ src = GST_VIDEO_FRAME_COMP_DATA (in_frame, 0); dest = GST_VIDEO_FRAME_COMP_DATA (out_frame, 0); gst_video_frame_copy (out_frame, in_frame); gaussian_smooth (filter, src, dest); return GST_FLOW_OK; }
static GstFlowReturn gauss_blur_process_frame (GstBaseTransform * btrans, GstBuffer * in_buf, GstBuffer * out_buf) { GaussBlur *gb = GAUSS_BLUR (btrans); GstClockTime timestamp; gint64 stream_time; gfloat sigma; /* GstController: update the properties */ timestamp = GST_BUFFER_TIMESTAMP (in_buf); stream_time = gst_segment_to_stream_time (&btrans->segment, GST_FORMAT_TIME, timestamp); if (GST_CLOCK_TIME_IS_VALID (stream_time)) gst_object_sync_values (G_OBJECT (gb), stream_time); GST_OBJECT_LOCK (gb); sigma = gb->sigma; GST_OBJECT_UNLOCK (gb); if (gb->cur_sigma != sigma) { g_free (gb->kernel); gb->kernel = NULL; g_free (gb->kernel_sum); gb->kernel_sum = NULL; gb->cur_sigma = sigma; } if (gb->kernel == NULL && !make_gaussian_kernel (gb, gb->cur_sigma)) { GST_ELEMENT_ERROR (btrans, RESOURCE, NO_SPACE_LEFT, ("Out of memory"), ("Failed to allocation gaussian kernel")); return GST_FLOW_ERROR; } /* * Perform gaussian smoothing on the image using the input standard * deviation. */ memcpy (GST_BUFFER_DATA (out_buf), GST_BUFFER_DATA (in_buf), gb->height * gb->stride); gaussian_smooth (gb, GST_BUFFER_DATA (in_buf), GST_BUFFER_DATA (out_buf)); return GST_FLOW_OK; }
/******************************************************************************* * PROCEDURE: gaussian_smooth * PURPOSE: Blur an image with a gaussian filter. * NAME: Mike Heath * DATE: 2/15/96 *******************************************************************************/ void gaussian_smooth(unsigned char *image, int rows, int cols, float sigma, short int **smoothedim) { int r, c, rr, cc, /* Counter variables. */ windowsize, /* Dimension of the gaussian kernel. */ center; /* Half of the windowsize. */ float *tempim, /* Buffer for separable filter gaussian smoothing. */ *kernel, /* A one dimensional gaussian kernel. */ dot, /* Dot product summing variable. */ sum; /* Sum of the kernel weights variable. */ int tid; /**************************************************************************** * Create a 1-dimensional gaussian smoothing kernel. ****************************************************************************/ if(VERBOSE) printf(" Computing the gaussian smoothing kernel.\n"); make_gaussian_kernel(sigma, &kernel, &windowsize); center = windowsize / 2; /**************************************************************************** * Allocate a temporary buffer image and the smoothed image. ****************************************************************************/ if((tempim = (float *) calloc(rows*cols, sizeof(float))) == NULL){ fprintf(stderr, "Error allocating the buffer image.\n"); exit(1); } if(((*smoothedim) = (short int *) calloc(rows*cols, sizeof(short int))) == NULL){ fprintf(stderr, "Error allocating the smoothed image.\n"); exit(1); } #pragma omp parallel shared(image, rows, cols, tempim, smoothedim, center, kernel) private(tid, r, c, rr, cc, dot, sum) { tid = omp_get_thread_num(); /**************************************************************************** * Blur in the x - direction. ****************************************************************************/ if (tid == 0) if(VERBOSE) printf(" Bluring the image in the X-direction.\n"); #pragma omp for schedule(dynamic, CHUNKSIZE) for(r=0;r<rows;r++){ for(c=0;c<cols;c++){ dot = 0.0; sum = 0.0; for(cc=(-center);cc<=center;cc++){ if(((c+cc) >= 0) && ((c+cc) < cols)){ dot += (float)image[r*cols+(c+cc)] * kernel[center+cc]; sum += kernel[center+cc]; } } tempim[r*cols+c] = dot/sum; } } /**************************************************************************** * Blur in the y - direction. ****************************************************************************/ if (tid == 0) if(VERBOSE) printf(" Bluring the image in the Y-direction.\n"); #pragma omp for schedule(dynamic, CHUNKSIZE) for(c=0;c<cols;c++){ for(r=0;r<rows;r++){ sum = 0.0; dot = 0.0; for(rr=(-center);rr<=center;rr++){ if(((r+rr) >= 0) && ((r+rr) < rows)){ dot += tempim[(r+rr)*cols+c] * kernel[center+rr]; sum += kernel[center+rr]; } } (*smoothedim)[r*cols+c] = (short int)(dot*BOOSTBLURFACTOR/sum + 0.5); } } } //pragma omp parallel free(tempim); free(kernel); }
/******************************************************************************* * PROCEDURE: gaussian_smooth * PURPOSE: Blur an image with a gaussian filter. * NAME: Mike Heath * DATE: 2/15/96 *******************************************************************************/ short int* gaussian_smooth(unsigned char *image, int rows, int cols, float sigma) { int r, c, rr, cc, /* Counter variables. */ windowsize, /* Dimension of the gaussian kernel. */ center; /* Half of the windowsize. */ float *tempim,*tempim1, /* Buffer for separable filter gaussian smoothing. */ *kernel, /* A one dimensional gaussian kernel. */ dot, /* Dot product summing variable. */ sum; /* Sum of the kernel weights variable. */ /**************************************************************************** * Create a 1-dimensional gaussian smoothing kernel. ****************************************************************************/ if(VERBOSE) printf(" Computing the gaussian smoothing kernel.\n"); make_gaussian_kernel(sigma, &kernel, &windowsize); center = windowsize / 2; /**************************************************************************** * Allocate a temporary buffer image and the smoothed image. ****************************************************************************/ if((tempim = (float *) malloc(rows*cols* sizeof(float))) == NULL) { fprintf(stderr, "Error allocating the buffer image.\n"); exit(1); } short int* smoothedim; if(((smoothedim) = (short int *) malloc(rows*cols*sizeof(short int))) == NULL) { fprintf(stderr, "Error allocating the smoothed image.\n"); exit(1); } startTimer(&totalTime); //Neon impelementation of gaussian smooth starts here /**************************************************************************** * Blur in the x - direction. ****************************************************************************/ int loop; int floop; //Modification of input image for neon implementation //For Filter 1 float * new_image; //For Filter 2 float *new_image_col; //kernel is changed to 17 from 15 for neon (two 0s at the beginning and the end) float new_kernel[17]; //Generating now kernel filter for (floop = 0 ; floop < 17 ; floop++) { if(floop == 0 || floop == 16 ) new_kernel[floop] = 0 ; else new_kernel [floop] = kernel[floop -1]; } //For filter 1, new cols number for neon unsigned int new_cols; new_cols=cols+16; unsigned int i, k; unsigned int a; unsigned int m; unsigned int n, j; //Malloc of new image used by neon new_image = (float*)malloc(new_cols*rows*sizeof(float)); for( i =0; i<rows; i++){ memset(&new_image[i*new_cols],0,8*sizeof(float)); for( k=0; k<cols;k++){ new_image[i*new_cols+8+k] = (float)image[i*cols+k]; } memset(&new_image[i*new_cols+8+cols],0,8*sizeof(float)); } // Neon handles four piexel at a time float32x4_t neon_input; float32x4_t neon_filter; float32x4_t temp_sum; float32x2_t tempUpper; float32x2_t tempLower; float32_t zero = 0; float32_t temp_output; float Basekernel = 0.0f; float kernelSum; //When using the new filter, we always assume the image has more than 9 pixels in a row //Base sum for the filter for( a=8; a<=16; a++){ Basekernel += new_kernel[a]; } //Filter 1, filtering row by row for(m=0; m<rows; m++){ for( n=0; n<cols; n++){ temp_sum = vdupq_n_f32(0); if(n==0){ kernelSum = Basekernel; } else if(n <=8){ kernelSum += new_kernel[8-n]; } else if(n>=cols-8){ kernelSum -=new_kernel[cols-n+8]; } //For each pixel, filtering is performed four times for( j=0; j<4; j++) { int kk=0; if(j>=2) { kk=1; } neon_input = vld1q_f32(&new_image[m*new_cols+n+j*4+kk]); neon_filter = vld1q_f32(&new_kernel[j*4+kk]); temp_sum = vmlaq_f32(temp_sum,neon_input,neon_filter); } unsigned int t; for( t=0; t<=3; t++){ temp_output += vgetq_lane_f32(temp_sum,t ); } temp_output += new_image[m*new_cols+n+8] * new_kernel[8]; temp_output /= kernelSum; tempim[m*cols+n] = temp_output; temp_output=0; } } for(r=0; r<rows; r++) { for(c=0; c<cols; c++) { dot = 0.0; sum = 0.0; for(cc=(-center); cc<=center; cc++) { if(((c+cc) >= 0) && ((c+cc) < cols)) { dot += (float)image[r*cols+(c+cc)] * kernel[center+cc]; sum += kernel[center+cc]; } } tempim1[r*cols+c] = dot/sum; } } /**************************************************************************** * Blur in the y - direction. ****************************************************************************/ unsigned int new_rows; new_rows=rows+16; new_image_col = (float*)malloc(new_rows*cols*sizeof(float)); if(VERBOSE) printf(" Bluring the image in the Y-direction.\n"); for( i =0; i<cols; i++){//actually nember of new rows are the number of columns here memset(&new_image_col[i*new_rows],0,8*sizeof(float)); for( k=0; k<rows;k++){ new_image_col[i*new_rows+8+k] = tempim[k*cols+i]; //new_image_col[i*new_rows+8+k] = imagetest1[k*cols+i]; } memset(&new_image_col[i*new_rows+8+rows],0,8*sizeof(float)); } Basekernel = 0.0; for( a=8; a<=16; a++){ Basekernel += new_kernel[a]; } for(m=0; m<cols; m++){// it was rows at br for( n=0; n<rows; n++){ temp_sum = vdupq_n_f32(0); if(n==0){ kernelSum = Basekernel; } else if(n <=8){ kernelSum += new_kernel[8-n]; } else if(n>=rows-8){ kernelSum -=new_kernel[rows-n+8]; } for( j=0; j<4; j++) { int kk=0; if(j>=2) { kk=1; } neon_input = vld1q_f32(&new_image_col[m*new_rows+n+j*4+kk]); neon_filter = vld1q_f32(&new_kernel[j*4+kk]); temp_sum = vmlaq_f32(temp_sum,neon_input,neon_filter); } unsigned int t; for( t=0; t<=3; t++){ temp_output += vgetq_lane_f32(temp_sum,t ); } temp_output += new_image_col[m*new_rows+n+8] * new_kernel[8]; temp_output = (temp_output * BOOSTBLURFACTOR) / kernelSum + 0.5; smoothedim[n*cols+m] = (short int )temp_output; temp_output=0; } } stopTimer(&totalTime); printTimer(&totalTime); free(tempim); free(kernel); return smoothedim; }
int lsepgaussf_double(DBL_TYPE *input, /* input image */ int nx, int ny, int nz, double sigma, DBL_TYPE *smoothedim) /* output image */ { int r, c, z , rr, cc, zz; /* Counter variables. */ int windowsize; /* Dimension of the gaussian kernel. */ int center; /* Half of the windowsize. */ float *tempim; /* Buffer for separable filter gaussian smoothing. */ float *kernel; /* A one dimensional gaussian kernel. */ float dot; /* Dot product summing variable. */ float sum; /* Sum of the kernel weights variable. */ /**************************************************************************** * Create a 1-dimensional gaussian smoothing kernel. ****************************************************************************/ LIARdebug(" Computing the gaussian smoothing kernel.\n"); make_gaussian_kernel(sigma, &kernel, &windowsize); center = windowsize / 2; /**************************************************************************** * Allocate a temporary buffer image and the smoothed image. ****************************************************************************/ if((tempim = (float *) calloc(ny*nx*nz, sizeof(float))) == NULL){ LIARerror("Error allocating the buffer image.\n"); return(1); } /**************************************************************************** * Blur in the x - direction. ****************************************************************************/ LIARdebug(" Bluring the image in the X-direction.\n"); for(z=0;z<nz;z++){ for(r=0;r<ny;r++){ for(c=0;c<nx;c++) { dot = 0.0; sum = 0.0; for(cc=(-center);cc<=center;cc++){ if(((c+cc) >= 0) && ((c+cc) < nx)){ dot += input[z*(ny*nx)+r*nx+(c+cc)] * kernel[center+cc]; sum += kernel[center+cc]; } } tempim[z*(ny*nx)+r*nx+c] = dot/sum; } } } /**************************************************************************** * Blur in the y - direction. ****************************************************************************/ LIARdebug(" Bluring the image in the Y-direction.\n"); for(z=0;z<nz;z++){ for(c=0;c<nx;c++){ for(r=0;r<ny;r++){ sum = 0.0; dot = 0.0; for(rr=(-center);rr<=center;rr++){ if(((r+rr) >= 0) && ((r+rr) < ny)){ dot += tempim[z*(ny*nx)+(r+rr)*nx+c] * kernel[center+rr]; sum += kernel[center+rr]; } } tempim[z*(ny*nx)+r*nx+c] = dot/sum; } } } /**************************************************************************** * Blur in the z - direction. ****************************************************************************/ LIARdebug(" Bluring the image in the Z-direction.\n"); for(c=0;c<nx;c++){ for(r=0;r<ny;r++){ for(z=0;z<nz;z++){ sum = 0.0; dot = 0.0; for(zz=(-center);zz<=center;zz++){ if(((z+zz) >= 0) && ((z+zz) < nz)){ dot += tempim[(z+zz)*(ny*nx)+r*nx+c] * kernel[center+zz]; sum += kernel[center+zz]; } } smoothedim[z*(ny*nx)+r*nx+c] = dot/sum; } } } free(tempim); free(kernel); return 0; }
/******************************************************************************* * PROCEDURE: gaussian_smooth * PURPOSE: Blur an image with a gaussian filter. * NAME: Mike Heath * DATE: 2/15/96 *******************************************************************************/ short int* gaussian_smooth(unsigned char *image, int rows, int cols, float sigma) { int r, c, rr, cc, /* Counter variables. */ windowsize, /* Dimension of the gaussian kernel. */ center; /* Half of the windowsize. */ float *tempim, /* Buffer for separable filter gaussian smoothing. */ *kernel, /* A one dimensional gaussian kernel. */ dot, /* Dot product summing variable. */ sum; /* Sum of the kernel weights variable. */ int i; /**************************************************************************** * Create a 1-dimensional gaussian smoothing kernel. ****************************************************************************/ if(VERBOSE) printf(" Computing the gaussian smoothing kernel.\n"); make_gaussian_kernel(sigma, &kernel, &windowsize); for(i=0;i<16;i++){ printf("%d: %f, ",i,kernel[i]); printf("%lu, ",(unsigned short int)(kernel[i]*(1<<16))); printf("%lu, \n",(unsigned short int)(kernel[i]*(1<<17))); } center = windowsize / 2; /**************************************************************************** * Allocate a temporary buffer image and the smoothed image. ****************************************************************************/ if((tempim = (float *) malloc(rows*cols* sizeof(float))) == NULL) { fprintf(stderr, "Error allocating the buffer image.\n"); exit(1); } short int* smoothedim; if(((smoothedim) = (short int *) malloc(rows*cols*sizeof(short int))) == NULL) { fprintf(stderr, "Error allocating the smoothed image.\n"); exit(1); } MCPROF_ZONE_ENTER(1); /**************************************************************************** * Blur in the x - direction. ****************************************************************************/ if(VERBOSE) printf(" Bluring the image in the X-direction.\n"); for(r=0; r<rows; r++) { for(c=0; c<cols; c++) { dot = 0.0; sum = 0.0; for(cc=(-center); cc<=center; cc++) { if(((c+cc) >= 0) && ((c+cc) < cols)) { dot += (float)image[r*cols+(c+cc)] * kernel[center+cc]; sum += kernel[center+cc]; } } tempim[r*cols+c] = dot/sum; } } MCPROF_ZONE_EXIT(1); MCPROF_ZONE_ENTER(2); /**************************************************************************** * Blur in the y - direction. ****************************************************************************/ if(VERBOSE) printf(" Bluring the image in the Y-direction.\n"); for(c=0; c<cols; c++) { for(r=0; r<rows; r++) { sum = 0.0; dot = 0.0; for(rr=(-center); rr<=center; rr++) { if(((r+rr) >= 0) && ((r+rr) < rows)) { dot += tempim[(r+rr)*cols+c] * kernel[center+rr]; sum += kernel[center+rr]; } } smoothedim[r*cols+c] = (short int)(dot*BOOSTBLURFACTOR/sum + 0.5); } } MCPROF_ZONE_EXIT(2); free(tempim); free(kernel); return smoothedim; }