Exemple #1
0
/*******************************************************************************
* 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);
}
Exemple #2
0
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;
}
Exemple #4
0
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;
}