Example #1
0
/*
in       input image
size     size of filter kernel
spatial  true if convolution shall be performed in spatial domain, false otherwise
return   smoothed image
*/
Mat Dip3::mySmooth(Mat& in, int size, bool spatial){

   // create filter kernel
   Mat kernel = createGaussianKernel(size);
 
   // perform convoltion
   if (spatial)
   return spatialConvolution(in, kernel);
   else
   return frequencyConvolution(in, kernel);
   
}
Example #2
0
void Dip3::test_createGaussianKernel(void){

   Mat k = createGaussianKernel(11);
   
   if ( abs(sum(k).val[0] - 1) > 0.0001){
      cout << "ERROR: Dip3::createGaussianKernel(): Sum of all kernel elements is not one!" << endl;
      return;
   }
   if (sum(k >= k.at<float>(5,5)).val[0]/255 != 1){
      cout << "ERROR: Dip3::createGaussianKernel(): Seems like kernel is not centered!" << endl;
      return;
   }
   cout << "Message: Dip3::createGaussianKernel() seems to be correct" << endl;
}
Example #3
0
pixel3f *Image::createGaussian(float sigma)
{
	pixel3f *gaussian = new pixel3f[_width * _height]();
	
	// Precompute constants.
	float variance = sigma * sigma;
	float denomiator = 2 * M_PI * variance;

	// Radius of filter.
	int r = 2.0f * sigma;
	float *kernel = createGaussianKernel(r + 1, variance);
	
	// Seperable x component of Gaussian filter.
	for (int x = 0; x < _width; x++) {
		for (int y = 0; y < _height; y++) {
			float sum = 0;
			
			for (int i = -r; i <= r; i++) {
				sum += pixelAt(_pixels, x + i, y)->L * kernel[abs(i)];
			}
			
			// Do not divide by the regular denominator.
			pixelAt(_copy, x, y)->L = sum;
		}
	}
	
	// Seperable y component of Gaussian filter.
	for (int x = 0; x < _width; x++) {
		for (int y = 0; y < _height; y++) {
			float sum = 0;
			
			for (int j = -r; j <= r; j++) {
				sum += pixelAt(_copy, x, y + j)->L * kernel[abs(j)];
			}
			
			// Divided by the denominator squared only once rather than twice.
			pixelAt(gaussian, x, y)->L = sum / denomiator;
		}
	}
	
	// Free temporary data.
	delete[] kernel;
	
	return gaussian;
}
Example #4
0
void Image::bilateral()
{
	// Gaussian kernel used to model geometric similarity.
	float *kernel = createGaussianKernel(RADIUS + 1, VARIANCE);
	
	for (int x = 0; x < _width; x++) {
		for (int y = 0; y < _height; y++) {
			pixel3f *center = pixelAt(_pixels, x, y);
			float numerator = 0;
			float denominator = 0;
			
			for (int i = -RADIUS; i <= RADIUS; i++) {
				pixel3f *neighbor = pixelAt(_pixels, x + i, y);
				
				// Compute euclidean distance between Lab colors to determine photometric similarity.
				float dL = center->L - neighbor->L;
				float da = center->a - center->a;
				float db = center->b - center->b;
				float distance = dL * dL + da * da + db * db;
				
				float photometric = expf(distance / PHOTOMETRIC);
				float similarity = photometric * kernel[abs(i)];
				
				// Denominator serves to normalize values.
				denominator += similarity;
				numerator += similarity * neighbor->L;
			}
			
			// Copy a and b data over as well to use for the y-filter pass.
			pixel3f *target = pixelAt(_copy, x, y);
			target->L = numerator / denominator;
			target->a = center->a;
			target->b = center->b;
		}
	}
	
	for (int x = 0; x < _width; x++) {
		for (int y = 0; y < _height; y++) {
			pixel3f *center = pixelAt(_copy, x, y);
			float numerator = 0;
			float denominator = 0;
			
			for (int j = -RADIUS; j <= RADIUS; j++) {
				pixel3f *neighbor = pixelAt(_copy, x, y + j);
				
				float dL = center->L - neighbor->L;
				float da = center->a - center->a;
				float db = center->b - center->b;
				float distance = dL * dL + da * da + db * db;
				
				float photometric = expf(distance / PHOTOMETRIC);
				float similarity = photometric * kernel[abs(j)];
				
				denominator += similarity;
				numerator += similarity * neighbor->L;
			}
			
			pixelAt(_pixels, x, y)->L = numerator / denominator;
		}
	}
	
	delete[] kernel;
}