• 图像放缩------临近点插值 分类: 视频图像处理 2015-07-24 09:16 25人阅读 评论(0) 收藏


    一:数学原理

    当一幅二维数字图像从源图像N*M被放为(j*N) * (k*M)目标图像是,参照数学斜率计算公式

    必然有:

    (X1 – Xmin)/(Xmax - Xmin) = (Y1 - Ymin)/(Ymax-Ymin)

     

    当Xmin 和 Ymin均为从零开始的像素点时,公式可以简化为:

             X=Y1 (Xmax/Ymax)

     

    对于任意一幅源图像来说,假设放大后目标图像的宽为Dw高为Dh,任意目标像素点(Dx, Dy)

    在源图像上的位置为:

             Sx= Dx * (Sh/Dh) // row

             Sy= Dy * (Sw/Dw) // column

     

    其中,(Sx,Sy)为对于的源图像上的像素点,Sw和Sh分别为源图像的宽度和高度。最终有

             Dpixel(Dx,Dy) = Spixel(Sx, Sy);

     

    二:临近点插值算法的缺点

    临近点插值算法会产生锯齿效果, 不是一个很好的图像放缩算法,临近点插值算法不改变源

    像素点到目标像素点的值,只是最简单的位置匹配而已,相比之下,双线性内插值算法和双

    立方插值算法效果更好,但是计算量更大,临近点插值是计算量最小的防缩算法。

     

    三:关键程序代码解释

    从BufferedImage对象中获取像素数组的代码如下:

    int type = img.getType();

    if ( type == BufferedImage.TYPE_INT_ARGB ||

    type == BufferedImage.TYPE_INT_RGB ) {

        img.getRaster().setDataElements(x, y,width,height, pixelsData);

    }

    else {

        img.setRGB(x, y, width, height, pixelsData, 0, width);

    }

     

    从源图像对象一维像素数组转换为三维对象数组,代码如下:

    int[][][] tempData = new int[imgRows][imgCols][4];

    tempData[row][col][0] =(aRow[col] >> 24) & 0xFF; // alpha

    tempData[row][col][1] =(aRow[col] >> 16) & 0xFF; // red

    tempData[row][col][2] =(aRow[col] >> 8) & 0xFF;  // green

    tempData[row][col][3] = (aRow[col]) &0xFF;       // blue

     

    首先要计算行与列的缩放比例,计算代码如下:

    float rowRatio = ((float)srcH)/((float)destH);

    float colRatio = ((float)srcW)/((float)destW);

     

    计算源像素点的行位置:

    int srcRow = Math.round(((float)row)*rowRatio);

     

    计算源像素点的列位置:

    int srcCol = Math.round(((float)col)*colRatio);

     

    四:程序效果



    五:程序源代码

    1. <span style="font-weight: normal;">public class NearNaighborZoom implements ImageScale {  
    2.       
    3.     public NearNaighborZoom() {  
    4.           
    5.     }  
    6.   
    7.     /** 
    8.      * (X-Xmin)/(Xmax-Xmin) = (Y-Ymin)/(Ymax-Ymin) 
    9.      * assume Xmin and Ymin are zero, then the formula will be f(x) = kx (k - coefficent, slope) 
    10.      *  
    11.      */  
    12.     @Override  
    13.     public int[] imgScale(int[] inPixelsData, int srcW, int srcH, int destW, int destH) {  
    14.         int[][][] inputThreeDeminsionData = processOneToThreeDeminsion(inPixelsData, srcH, srcW);  
    15.         int[][][] outputThreeDeminsionData = new int[destH][destW][4];  
    16.         float rowRatio = ((float)srcH)/((float)destH);  
    17.         float colRatio = ((float)srcW)/((float)destW);  
    18.         for(int row=0; row<destH; row++) {  
    19.             // convert to three dimension data  
    20.             int srcRow = Math.round(((float)row)*rowRatio);  
    21.             if(srcRow >=srcH) {  
    22.                 srcRow = srcH - 1;  
    23.             }  
    24.             for(int col=0; col<destW; col++) {  
    25.                 int srcCol = Math.round(((float)col)*colRatio);  
    26.                 if(srcCol >= srcW) {  
    27.                     srcCol = srcW - 1;  
    28.                 }  
    29.                 outputThreeDeminsionData[row][col][0] = inputThreeDeminsionData[srcRow][srcCol][0]; // alpha  
    30.                 outputThreeDeminsionData[row][col][1] = inputThreeDeminsionData[srcRow][srcCol][1]; // red  
    31.                 outputThreeDeminsionData[row][col][2] = inputThreeDeminsionData[srcRow][srcCol][2]; // green  
    32.                 outputThreeDeminsionData[row][col][3] = inputThreeDeminsionData[srcRow][srcCol][3]; // blue  
    33.             }  
    34.         }  
    35.         return convertToOneDim(outputThreeDeminsionData, destW, destH);  
    36.     }  
    37.       
    38.     /* <p> The purpose of this method is to convert the data in the 3D array of ints back into </p> 
    39.      * <p> the 1d array of type int. </p> 
    40.      *  
    41.      */  
    42.     public int[] convertToOneDim(int[][][] data, int imgCols, int imgRows) {  
    43.         // Create the 1D array of type int to be populated with pixel data  
    44.         int[] oneDPix = new int[imgCols * imgRows * 4];  
    45.   
    46.         // Move the data into the 1D array. Note the  
    47.         // use of the bitwise OR operator and the  
    48.         // bitwise left-shift operators to put the  
    49.         // four 8-bit bytes into each int.  
    50.         for (int row = 0, cnt = 0; row < imgRows; row++) {  
    51.             for (int col = 0; col < imgCols; col++) {  
    52.                 oneDPix[cnt] = ((data[row][col][0] << 24) & 0xFF000000)  
    53.                         | ((data[row][col][1] << 16) & 0x00FF0000)  
    54.                         | ((data[row][col][2] << 8) & 0x0000FF00)  
    55.                         | ((data[row][col][3]) & 0x000000FF);  
    56.                 cnt++;  
    57.             }// end for loop on col  
    58.   
    59.         }// end for loop on row  
    60.   
    61.         return oneDPix;  
    62.     }// end convertToOneDim  
    63.       
    64.     private int[][][] processOneToThreeDeminsion(int[] oneDPix2, int imgRows, int imgCols) {  
    65.         int[][][] tempData = new int[imgRows][imgCols][4];  
    66.         for(int row=0; row<imgRows; row++) {  
    67.               
    68.             // per row processing  
    69.             int[] aRow = new int[imgCols];  
    70.             for (int col = 0; col < imgCols; col++) {  
    71.                 int element = row * imgCols + col;  
    72.                 aRow[col] = oneDPix2[element];  
    73.             }  
    74.               
    75.             // convert to three dimension data  
    76.             for(int col=0; col<imgCols; col++) {  
    77.                 tempData[row][col][0] = (aRow[col] >> 24) & 0xFF// alpha  
    78.                 tempData[row][col][1] = (aRow[col] >> 16) & 0xFF// red  
    79.                 tempData[row][col][2] = (aRow[col] >> 8) & 0xFF;  // green  
    80.                 tempData[row][col][3] = (aRow[col]) & 0xFF;       // blue  
    81.             }  
    82.         }  
    83.         return tempData;  
    84.     }  
    85.   
    86. }  
    87. </span>  

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    对结对编程的测试
    用例
    结对编程 一
    个人项目总结与结对编程的开始
    7-6随便写写
    7-5个人日报
    7-4个人报告
    7.1-7.3个人日报
    6-30个人日报
    6-29个人日报
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706384.html
Copyright © 2020-2023  润新知