Gaussian blur
Gaussian Blur, also known as Gaussian smoothing, is a processing effect widely used in image processing software such as Adobe Photoshop, GIMP, and Paint.NET. It is usually used to reduce image noise and reduce the level of detail. The visual effect of the image generated by this blur technology is like observing the image through a translucent screen, which is significantly different from the lens out-of-focus imaging effect bokeh and ordinary lighting shadows. Gaussian smoothing is also used in pre-processing phases in computer vision algorithms to enhance image effects of images at different scales. From a mathematical perspective, the Gaussian blur process of an image is convolution with the normal distribution. Since normal distribution is also called Gaussian distribution, this technology is called Gaussian fuzzy. Convolution of the image and the circular square blur will generate a more accurate out-of-focus imaging effect. Since the Fourier transform of the Gaussian function is another Gaussian function, Gaussian blur is a low-pass filter for the image.
Gaussian fuzzing uses Gaussian's normal distribution density function to calculate the transformation of each pixel in the image.
Based on the one-dimensional Gaussian function, a two-dimensional Gaussian function can be derived:
where r is the fuzzy radius, r^2 = x^2 + y^2, and σ is the standard deviation of the normal distribution. In two-dimensional space, the contour lines of the surface generated by this formula are concentric circles that are normally distributed from the center. The convolution matrix composed of pixels with non-zero distribution is transformed with the original image. The value of each pixel is a weighted average of the values of neighboring pixels around. The value of the original pixel has the largest Gaussian distribution value, so it has the largest weight. As the adjacent pixels get farther and farther away from the original pixel, their weights become smaller and smaller. This fuzzing process preserves edge effects more than other equalization fuzzy filters.
In fact, it is easy to implement Gaussian blur on iOS. As early as iOS 5.0, there was a Core Image API, and a large number of filter implementations are provided in the CoreImage.framework library.
+(UIImage *)coreBlurImage:(UIImage *)image withBlurNumber:(CGFloat)blur { CIContext *context = [CIContext contextWithOptions:nil]; CIImage *inputImage= [CIImage imageWithCGImage:image.CGImage]; //Set filter CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"]; [filter setValue:inputImage forKey:kCIInputImageKey]; [filter setValue:@(blur) forKey: @"inputRadius"]; //BlurImage CIImage *result=[filter valueForKey:kCIOutputImageKey]; CGImageRef outImage=[context createCGImage:result fromRect:[result extent]]; UIImage *blurImage=[UIImage imageWithCGImage:outImage]; CGImageRelease(outImage); return blurImage;}You can also use the native API - RenderScript to implement Gaussian blur on Android, but the API of Android is above 17, which is Android version 4.2.
/** * Algorithm for implementing Gaussian fuzzy using RenderScript* @param bitmap * @return */public Bitmap blur(Bitmap bitmap){//Let's create an empty bitmap with the same size of the bitmap we want to blurBitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);//Instantiate a new RenderscriptRenderScript rs = RenderScript.create(getApplicationContext());//Create an Intrinsic Blur Script using the RenderscriptScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));//Create the Allocations (in/out) with the Renderscript and the in/out bitmapsAllocation allIn = Allocation.createFromBitmap(rs, bitmap);Allocation allOut = Allocation.createFromBitmap(rs, outBitmap);//Set the radius of the blur: 0 < radius <= 25blurScript.setRadius(20.0f);//Perform the RenderscriptblurScript.setInput(allIn);blurScript.forEach(allOut);//Copy the final bitmap created by the outAllocation to the outBitmapallOut.copyTo(outBitmap);//recycle the original bitmapbitmap.recycle();//After finishing everything, we destroy the Renderscript.rs.destroy();return outBitmap;}The image frame cv4j we developed also provides a filter to implement Gaussian blur.
GaussianBlurFilter filter = new GaussianBlurFilter();filter.setSigma(10);RxImageData.bitmap(bitmap).addFilter(filter).into(image2);
It can be seen that the Gaussian fuzzy implemented in cv4j is consistent with the effect of RenderScript implementation.
Among them, the code of GaussianBlurFilter is as follows:
public class GaussianBlurFilter implements CommonFilter {private float[] kernel;private double sigma = 2;ExecutorService mExecutor;CompletionService<Void> service;public GaussianBlurFilter() {kernel = new float[0];}public void setSigma(double a) {this.sigma = a;}@Override public ImageProcessor filter(final ImageProcessor src){final int width = src.getWidth();final int height = src.getHeight();final int size = width*height;int dims = src.getChannels();makeGaussianKernel(sigma, 0.002, (int)Math.min(width, height));mExecutor = TaskUtils.newFixedThreadPool("cv4j",dims);service = new ExecutorCompletionService<>(mExecutor);// save resultfor (int i=0; i<dims; i++) {final int temp = i;service.submit(new Callable<Void>() {public Void call() throws Exception {byte[] inPixels = src.tobyte(temp);byte[] temp = new byte[size];blur(inPixels, temp, width, height);// H Gaussianblur(temp, inPixels, height, width);// V Gaussainreturn null;}});}for (int i = 0; i < dims; i++) {try {service.take();}catch (InterruptedException e) {e.printStackTrace();}}mExecutor.shutdown();return src;}/** * <p> here is 1D Gaussian , </p> * * @param inPixels * @param outPixels * @param width * @param height */private void blur(byte[] inPixels, byte[] outPixels, int width, int height) {int subCol = 0;int index = 0, index2 = 0;float sum = 0;int k = kernel.length-1;for (int row=0; row<height; row++) {int c = 0;index = row;for (int col=0; col<width; col++) {sum = 0;for (int m = -k; m< kernel.length; m++) {subCol = col + m;if(subCol < 0 || subCol >= width) {subCol = 0;}index2 = row * width + subCol;c = inPixels[index2] & 0xff;sum += c * kernel[Math.abs(m)];}outPixels[index] = (byte)Tools.clamp(sum);index += height;}}} public void makeGaussianKernel(final double sigma, final double accuracy, int maxRadius) {int kRadius = (int)Math.ceil(sigma*Math.sqrt(-2*Math.log(accuracy)))+1;if (maxRadius < 50) maxRadius = 50;// too small maxRadius would result in inaccurate sum.if (kRadius > maxRadius) kRadius = maxRadius;kernel = new float[kRadius];for (int i=0; i<kRadius; i++) // Gaussian functionkernel[i] = (float)(Math.exp(-0.5*i*i/sigma/sigma));double sum;// sum over all kernel elements for normalizationif (kRadius < maxRadius) {sum = kernel[0];for (int i=1; i<kRadius; i++) sum += 2*kernel[i];} else sum = sigma * Math.sqrt(2*Math.PI); for (int i=0; i<kRadius; i++) {double v = (kernel[i]/sum);kernel[i] = (float)v;}return;}}Space convolution
Two-dimensional convolution is often encountered in image processing, and most of the discrete forms of two-dimensional convolution are used in image processing.
The following are various convolution effects implemented by cv4j.
cv4j currently supports the following spatial convolution filters
| filter | name | effect |
|---|---|---|
| ConvolutionHVFilter | convolution | Blur or noise reduction |
| MinMaxFilter | Maximum and minimum filtering | Denoising |
| SAPNoiseFilter | Salt and pepper noise | Increase noise |
| SharpFilter | Sharpen | Enhanced |
| MedimaFilter | Median filtering | Denoising |
| LaplasFilter | Laplace | Extract edges |
| FindEdgeFilter | Find the Edge | Gradient extraction |
| SobelFilter | gradient | Get gradient extraction in x and y directions |
| VarianceFilter | Variance filtering | High-pass filtering |
| MaerOperatorFilter | Mar operation | High-pass filtering |
| USMFilter | USM | Enhanced |
cv4j is an image processing library developed by gloomyfish and I, and is still in an early version.
Functions that have been implemented at present:
This week, we made major adjustments to cv4j and optimized the overall architecture. Spatial convolution function (image enhancement, sharpening, blurring, etc.) is also added. Next, we will do binary image analysis (corrosion, expansion, opening and closing operations, contour extraction, etc.)
Summarize
The above is all the content of this article about Java programming to implement Gaussian blur and spatial convolution of images. I hope it will be helpful to everyone. Interested friends can continue to refer to this site:
70 lines of Java code to implement deep neural network algorithm sharing
Java language implements the code example of Cruzkal algorithm based on undirected authorized graphs
The complete code example of the Java algorithm to implement red and black tree
If there are any shortcomings, please leave a message to point it out. Thank you friends for your support for this site!