Two-cube interpolation for image scale-down

Source: Internet
Author: User

Two-cube interpolation for image scale-down

I. Mathematical Principles

If a function f (x) and its derivative at x = 0, x = 1 are known, the function can be interpolated between [0, 1 ].

We call it cubic Interpolation when expressed as cubic polynomials. A cubic polynomial and its derivative:

F (x) = AX ^ 3 + bx ^ 2 + cx + d

F' (x) = 3ax ^ 2 + 2bx + c

The polynomial values at x = 0, x = 1 and their export values are:

F (0) = D;

F (1) = A + B + C + D;

F' (0) = C

F' (1) = 3A + 2B + c

 

The preceding four equations can be equivalent to the following:

A = 2f (0)-2f (1) + f' (0) + f' (1)

B =-3f (0) + 3f (1)-2f '(0)-f' (1)

C = f' (0)

D = f' (1)

Assume that you have four vertex values P0, P1, P2, and P3 in X =-1, x = 0, x = 1, x = 2, specify values to F (0), F (1), f' (0 ),

F' (1) is:

F (0) = p1

F (1) = P2

F' (0) = (P2-P0)/2

F' (1) = (p3-p1)/2

 

Our cubic Interpolation Formula becomes:

F (P0, P1, P2, P3, x) = (-1/2P0 + 3/2P1-3/2p2 + 1/2p3) x ^ 3 + (p0-5/2P1 + 2p2-1/2d) x ^ 2 + (-1/2P0 +

1/2p2) x + p1

 

Two-cube interpolation is the expression of cubic Interpolation in two-dimensional space. The interpolation formula can be expressed:

G (x, y) = f (p00, p01, p02, P03, Y), F (P10, P11, p12, P13, Y), F (P20, p21-p22, P23, Y), F (P30, P31, p32, p33, Y), X)

Solve the 16 parameters to obtain the value of the target interpolation point with g (x, y.

 

Ii. Advantages and Disadvantages of Dual-cube interpolation

In the process of image enlargement, the dual-cube interpolation can retain more image details, and the enlarged image has the anti-sawtooth function,

At the same time, the image is more realistic than the source image, but the disadvantage is that the computation is relatively large.

It is said that image enlargement in Photoshop is an optimization algorithm based on two-cube interpolation.

3. The program running effect is as follows:

4. key code parsing

Do not want to explain too much. The most important thing is to calculate the fractional part of the floating point coordinate, that is, the value range of X and Y is between [0, 1 ].

V. full source code of Java-based programs

public class BiCubicInterpolationScale implements ImageScale {private double a00, a01, a02, a03;private double a10, a11, a12, a13;private double a20, a21, a22, a23;private double a30, a31, a32, a33;private int srcWidth;private int srcHeight;@Overridepublic int[] imgScale(int[] inPixelsData, int srcW, int srcH, int destW, int destH) {double[][][] input3DData = processOneToThreeDeminsion(inPixelsData, srcH, srcW);int[][][] outputThreeDeminsionData = new int[destH][destW][4];double[][] tempPixels = new double[4][4];float rowRatio = ((float)srcH)/((float)destH);float colRatio = ((float)srcW)/((float)destW);this.srcWidth = srcW;this.srcHeight = srcH;for(int row=0; row<destH; row++) {// convert to three dimension datadouble srcRow = ((float)row)*rowRatio;double j = Math.floor(srcRow);double t = srcRow - j;for(int col=0; col<destW; col++) {double srcCol = ((float)col)*colRatio;double k = Math.floor(srcCol);double u = srcCol - k;for(int i=0; i<4; i++) {tempPixels[0][0] = getRGBValue(input3DData,j-1, k-1,i);tempPixels[0][1] = getRGBValue(input3DData,j-1, k, i);tempPixels[0][2] = getRGBValue(input3DData, j-1,k+1, i);tempPixels[0][3] = getRGBValue(input3DData, j-1, k+2,i);tempPixels[1][0] = getRGBValue(input3DData, j, k-1, i);tempPixels[1][1] = getRGBValue(input3DData, j, k, i);tempPixels[1][2] = getRGBValue(input3DData, j, k+1, i);tempPixels[1][3] = getRGBValue(input3DData, j, k+2, i);tempPixels[2][0] = getRGBValue(input3DData, j+1,k-1,i);tempPixels[2][1] = getRGBValue(input3DData, j+1, k, i);tempPixels[2][2] = getRGBValue(input3DData, j+1, k+1, i);tempPixels[2][3] = getRGBValue(input3DData, j+1, k+2, i);tempPixels[3][0] = getRGBValue(input3DData, j+2, k-1, i);tempPixels[3][1] = getRGBValue(input3DData, j+2, k, i);tempPixels[3][2] = getRGBValue(input3DData, j+2, k+1, i);tempPixels[3][3] = getRGBValue(input3DData, j+2, k+2, i);// update coefficientsupdateCoefficients(tempPixels);outputThreeDeminsionData[row][col][i] = getPixelValue(getValue(t, u));}}}return convertToOneDim(outputThreeDeminsionData, destW, destH);}public double getRGBValue(double[][][] input3DData, double row, double col, int index) {if(col >= srcWidth) {col = srcWidth - 1;}if(col < 0) {col = 0;}if(row >= srcHeight) {row = srcHeight - 1;}if(row < 0) {row = 0;}return input3DData[(int)row][(int)col][index];}public int getPixelValue(double pixelValue) {return pixelValue < 0 ? 0: pixelValue >255.0d ?255:(int)pixelValue;}public void updateCoefficients (double[][] p) {a00 = p[1][1];a01 = -.5*p[1][0] + .5*p[1][2];a02 = p[1][0] - 2.5*p[1][1] + 2*p[1][2] - .5*p[1][3];a03 = -.5*p[1][0] + 1.5*p[1][1] - 1.5*p[1][2] + .5*p[1][3];a10 = -.5*p[0][1] + .5*p[2][1];a11 = .25*p[0][0] - .25*p[0][2] - .25*p[2][0] + .25*p[2][2];a12 = -.5*p[0][0] + 1.25*p[0][1] - p[0][2] + .25*p[0][3] + .5*p[2][0] - 1.25*p[2][1] + p[2][2] - .25*p[2][3];a13 = .25*p[0][0] - .75*p[0][1] + .75*p[0][2] - .25*p[0][3] - .25*p[2][0] + .75*p[2][1] - .75*p[2][2] + .25*p[2][3];a20 = p[0][1] - 2.5*p[1][1] + 2*p[2][1] - .5*p[3][1];a21 = -.5*p[0][0] + .5*p[0][2] + 1.25*p[1][0] - 1.25*p[1][2] - p[2][0] + p[2][2] + .25*p[3][0] - .25*p[3][2];a22 = p[0][0] - 2.5*p[0][1] + 2*p[0][2] - .5*p[0][3] - 2.5*p[1][0] + 6.25*p[1][1] - 5*p[1][2] + 1.25*p[1][3] + 2*p[2][0] - 5*p[2][1] + 4*p[2][2] - p[2][3] - .5*p[3][0] + 1.25*p[3][1] - p[3][2] + .25*p[3][3];a23 = -.5*p[0][0] + 1.5*p[0][1] - 1.5*p[0][2] + .5*p[0][3] + 1.25*p[1][0] - 3.75*p[1][1] + 3.75*p[1][2] - 1.25*p[1][3] - p[2][0] + 3*p[2][1] - 3*p[2][2] + p[2][3] + .25*p[3][0] - .75*p[3][1] + .75*p[3][2] - .25*p[3][3];a30 = -.5*p[0][1] + 1.5*p[1][1] - 1.5*p[2][1] + .5*p[3][1];a31 = .25*p[0][0] - .25*p[0][2] - .75*p[1][0] + .75*p[1][2] + .75*p[2][0] - .75*p[2][2] - .25*p[3][0] + .25*p[3][2];a32 = -.5*p[0][0] + 1.25*p[0][1] - p[0][2] + .25*p[0][3] + 1.5*p[1][0] - 3.75*p[1][1] + 3*p[1][2] - .75*p[1][3] - 1.5*p[2][0] + 3.75*p[2][1] - 3*p[2][2] + .75*p[2][3] + .5*p[3][0] - 1.25*p[3][1] + p[3][2] - .25*p[3][3];a33 = .25*p[0][0] - .75*p[0][1] + .75*p[0][2] - .25*p[0][3] - .75*p[1][0] + 2.25*p[1][1] - 2.25*p[1][2] + .75*p[1][3] + .75*p[2][0] - 2.25*p[2][1] + 2.25*p[2][2] - .75*p[2][3] - .25*p[3][0] + .75*p[3][1] - .75*p[3][2] + .25*p[3][3];}public double getValue (double x, double y) {double x2 = x * x;double x3 = x2 * x;double y2 = y * y;double y3 = y2 * y;return (a00 + a01 * y + a02 * y2 + a03 * y3) +       (a10 + a11 * y + a12 * y2 + a13 * y3) * x +       (a20 + a21 * y + a22 * y2 + a23 * y3) * x2 +       (a30 + a31 * y + a32 * y2 + a33 * y3) * x3;}/* <p> The purpose of this method is to convert the data in the 3D array of ints back into </p> * <p> the 1d array of type int. </p> *  */public int[] convertToOneDim(int[][][] data, int imgCols, int imgRows) {// Create the 1D array of type int to be populated with pixel dataint[] oneDPix = new int[imgCols * imgRows * 4];// Move the data into the 1D array. Note the// use of the bitwise OR operator and the// bitwise left-shift operators to put the// four 8-bit bytes into each int.for (int row = 0, cnt = 0; row < imgRows; row++) {for (int col = 0; col < imgCols; col++) {oneDPix[cnt] = ((data[row][col][0] << 24) & 0xFF000000)| ((data[row][col][1] << 16) & 0x00FF0000)| ((data[row][col][2] << 8) & 0x0000FF00)| ((data[row][col][3]) & 0x000000FF);cnt++;}// end for loop on col}// end for loop on rowreturn oneDPix;}// end convertToOneDimprivate double [][][] processOneToThreeDeminsion(int[] oneDPix2, int imgRows, int imgCols) {double[][][] tempData = new double[imgRows][imgCols][4];for(int row=0; row> 24) & 0xFF; // alphatempData[row][col][1] = (aRow[col] >> 16) & 0xFF; // redtempData[row][col][2] = (aRow[col] >> 8) & 0xFF;  // greentempData[row][col][3] = (aRow[col]) & 0xFF;       // blue}}return tempData;}}

Vi. Conclusion

These three articles discuss the basic principles, methods, and implementations of Image Resizing. If you want to obtain all the source code

You can contact me. If the article has any errors, please note.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.