Three common bicubic interpolation algorithms of image processing
A bicubic interpolation calculation involves 16 pixels, where (i ', J ') represents the pixels to be calculated in the source image containing
The pixel coordinate of the fractional part, DX represents the decimal coordinate in the x direction, and dy represents the decimal coordinate of the y direction. Specific
can see:
According to the above diagram and the mathematical expression of bicubic interpolation, we can see that the bicubic interpolation essence is like 16 pixels.
The sum of the weights convolution as the new pixel value.
where R (x) represents an interpolation expression and can be selected differently depending on the desired expression. There is a common triangle-based value, Bell
Distribution expression, B-spline curve expression.
1. Based on the triangle sampling mathematical formula
The simplest linear distribution, the code is implemented as follows:
Private double triangleinterpolation (double f) {f = f/2.0;if (F < 0.0) {return (F + 1.0);} Else{return (1.0-f);}}
2. The mathematical formula based on the bell distribution sampling is as follows:
The bell distribution sampling mathematical formula is based on the three-time convolution calculation. The code is implemented as follows:
Private double Bellinterpolation (double x) {double F = (x/2.0) * 1.5;IF (F > -1.5 && F < -0.5) {return ( 0.5 * MATH.POW (f + 1.5, 2.0));} else if (F > -0.5 && F < 0.5) {return 3.0/4.0-(f * f);} else if ((F > 0.5 && F < 1.5)) {return (0.5 * MATH.POW (f-1.5, 2.0));} return 0.0;}
3. The mathematical formula based on the sampling of B-spline curves is as follows:
is a polynomial-based four-time convolution of the sample calculation, the code is as follows:
Private double bsplineinterpolation (double f) {if (F < 0.0) {f = f;} if (f >= 0.0 && F <= 1.0) {return (2.0/3.0) + (0.5) * (f* f * f)-(f*f);} else if (F > 1.0 && F <= 2.0) {return 1.0/6.0 * MATH.POW ((2.0-f ), 3.0);} return 1.0;}
the complete source code for realizing the bicubic interpolation of the image is as follows:
Package Com.gloomyfish.zoom.study;import Java.awt.image.bufferedimage;import Java.awt.image.colormodel;import Com.gloomyfish.filter.study.abstractbufferedimageop;public class Bicubicinterpolationfilter extends Abstractbufferedimageop {public final static int triangle__interpolation = 1;public final static int bell__interpolation = 2;public final static int bspline__interpolation = 4;public final static int catmullroom__interpolation = 8; Public final static Double B = 0.0; Public final static Double C = 0.5; constantprivate int desth; Zoom Heightprivate int DESTW; Zoom widthprivate int Type;public bicubicinterpolationfilter () {this.type = bspline__interpolation;} public void SetType (int type) {this.type = type;} public void setdestheight (int desth) {this.desth = Desth;} public void setdestwidth (int destw) {THIS.DESTW = DESTW;} Private double Bellinterpolation (double x) {double F = (x/2.0) * 1.5;IF (F > -1.5 && F < -0.5) {return ( 0.5 * MATH.POW (f + 1.5, 2.0));} else if (F > -0.5 && F < 0.5) {return 3.0/4.0-(f * f);} else if ((F > 0.5 && F < 1.5)) {return (0.5 * MATH.POW (f-1.5, 2.0));} return 0.0;} Private double bsplineinterpolation (double f) {if (F < 0.0) {f = f;} if (f >= 0.0 && F <= 1.0) {return (2.0/3.0) + (0.5) * (f* f * f)-(f*f);} else if (F > 1.0 && F <= 2.0) {return 1.0/6.0 * MATH.POW ((2.0-F), 3.0);} return 1.0;} Private double triangleinterpolation (double f) {f = f/2.0;if (F < 0.0) {return (F + 1.0);} Else{return (1.0-f);}} Private double catmullrominterpolation (double f) {if (F < 0.0) {f = Math.Abs (f); if (F < 1.0) {return ((12-9 * B-6 * C) * (f * f * f) + ( -18 + * B + 6 *c) * ( f * f) + (6-2 * B))/6.0; } else if (F >= 1.0 && F < 2.0) {return ((-B-6 * C) * (f * f * f) + (6 * B + * C) * (f *f) + (-(* b)-* * c) * F + 8 * b + + * C)/6.0; } else {return 0.0; }} @Overridepublic bufferedimage filter (bufferedimage src, bufferedimage dest) {int width = src.getwidth (); int height = sr C.getheight (); if (dest = = null) Dest = createcompatibledestimage (src, null); int[] Inpixels = new Int[width * height];int[] Outpixels = new Int[desth * DESTW];GETRGB (src, 0, 0, width, height, inpixels); float Rowratio = ((float) height)/((float) DESTH) Float Colratio = ((float) width)/((float) destw); int index = 0;for (int row = 0; row < desth; row++) {int Ta = 0, tr = 0, TG = 0, TB = 0;double Srcrow = ((float) row) * rowratio;//gets the integer part coordinates row indexdouble j = Math.floor (Srcrow);// Gets the number of decimal parts of the row coordinates double t = srcrow-j;for (int col = 0; col < destw; col++) {Double srccol = ((float) col) * colratio;//gets the entire The number of part coordinates column indexdouble k = Math.floor (Srccol);//Gets the column's decimal part coordinates double u = srccol-k;double[] Rgbdata = new Double[3];d ouble Rgbcoffedata = 0.0;for (int m=-1; m<3; m++) {for (int n=-1; n<3; n++) {int[] rgb = GetPixel (J+m, k+n, width, height, inpixels);d ouble f1 = 0.0d;double F2 = 0.0d; if (type = = triangle__interpolation) {f1 = Triangleinterpolation ((double) m)-t); F2 = Triangleinterpolation (-(((Dou ble) (n)-u);} else if (type = = bell__interpolation) {f1 = Bellinterpolation ((double) m)-t); F2 = Bellinterpolation (-((double) n )-u);} else if (type = = bspline__interpolation) {f1 = Bsplineinterpolation ((double) m)-t); F2 = Bsplineinterpolation (-(((D ouble) n));} ELSE{F1 = Catmullrominterpolation ((double) m)-t); F2 = Catmullrominterpolation (-(((double) n)-u);} Sum of Weightrgbcoffedata + = f2*f1;//sum of the RGB valuesrgbdata[0] + = rgb[0] * F2 * f1;rgbdata[1] + = rgb[1] * F2 * f 1;RGBDATA[2] + = rgb[2] * F2 * F1;}} Ta = 255;//Get red/green/blue value for sample pixeltr = (int) (rgbdata[0]/rgbcoffedata); TG = (int) (rgbdata[1]/rgbcoffed ATA); tb = (int) (rgbdata[2]/rgbcoffedata); index = row * desTW + Col;outpixels[index] = (ta << 24) | (Clamp (TR) << 16) | (Clamp (TG) << 8) | Clamp (TB);}} Setrgb (dest, 0, 0, DESTW, Desth, outpixels); return dest;} public int clamp (int value) {return value > 255? 255:(value < 0? 0:value);} Private int[] GetPixel (Double J, double k, int width, int height,int[] inpixels) {int row = (int) j;int col = (int) k;if ( Row >= height) {row = height-1;} if (Row < 0) {row = 0;} if (Col < 0) {col = 0;} if (col >= width) {col = width-1;} int index = row * width + col;int[] rgb = new Int[3];rgb[0] = (Inpixels[index] >>) & 0xff;rgb[1] = (inpixels[ Index] >> 8) & 0xff;rgb[2] = Inpixels[index] & 0xff;return RGB;} Public bufferedimage createcompatibledestimage (bufferedimage src, ColorModel dstcm) {if (DSTCM = = null) DSTCM = Src.getcolormodel (); return new BufferedImage (DSTCM, Dstcm.createcompatiblewritableraster (DESTW, desth), Dstcm.isalphapremultip Lied (), null); }}
Operation Effect: Original
After the bicubic interpolation is enlarged:
Summarize:
Based on the three methods implemented here, the two-cubic interpolation has a certain blur compared to the original image.
In this case, the image sharpening and contrast enhancement can be achieved by subsequent processing to get the sharpen version.
It is also possible to preserve the double cubic convolution interpolation process by looking for a more appropriate r (x) function.
The edge and contrast of the image.
Reprint please be sure to indicate
Three common bicubic interpolation algorithms of image processing