当前位置:   article > 正文

图像处理之插值运算_图像的插值运算

图像的插值运算

图像处理之插值运算

     插值是根据抽样函数或信号估计连续位置的数值,或者是根据一系列离散采样点重构出原始的连续函数。在图像几何变换中,经过几何变换后的图像像素可能在原始图像中并没有对应的像素点,那么,在目标图像中这些没有对应点的像素灰度值该如何取值呢?通过图像的插值。图像插值对于目标图像像素点的任何连续位置,都可以获得一个较为精确的插值。而插值函数需要尽可能的保留图像的细节,并且尽可能的少引入人为噪声。


                                                                 

目标---原始图像的映射。对于目标图像中的每一个离散的像素位置(u`,v`),通过逆变换函数,对应

于原始图像中连续的位置(x,y)。目标图像中的I(u`,v`)像素灰度值可以根据原始图像坐标(x,y)的某些邻域插值获得。

1.一维插值

    一维平面中一些简单的插值算法,是根据离散函数g(u)(u属于整数),插值生成任意连续位置对应的数值。

最近邻插值

    在所有插值算法中,最简单的就是最近邻插值算法。最近邻插值算法中,对连续坐标x向下取整,得到与之最近的整数u0,再根据离散采样函数g(u0)作为连续坐标x的估算值。即:

                                                                     

线性插值

    另一种比较简单的插值算法是线性插值。线性插值的估算值是根据最近两个采样点的采样值g(u0)和g(u0+1),u0为x向下取整,根据采样点离连续x的距离进行加权求和,得到其最终的估计值。


    类似这种线性插值:已知数据 (x0, y0) 与 (x1, y1),要计算 [x0, x1] 区间内某一位置 x 在直线上的y值(反过来也是一样,略):

  上面比较好理解吧,仔细看就是用x和x0,x1的距离作为一个权重,用于y0和y1的加权。假设x倾向靠近x1,那么最终计算出来的y值也是应该倾向靠近于y1,;故其权重应该比较大,取其权重值应该为x2-x,;假设x倾向靠近X2,那么计算出来的Y也是应该更靠近于y2,其权重应该取其较大值x-x1。即不管X是倾向靠近x1,还是倾向靠近x2,上式线性插值公式总是成立。而双线性插值本质上就是在两个方向上做线性插值。



   两种一维插值如下图所示:



给定的离散函数g(u)(a),插值目标是估算其原始函数f(x)在任意连续坐标位置的数值,x属于实数 。(b)



最近邻插值算法(a)和线性插值算法(b)

2.理想的插值

      显然,上述简单的线性插值并不能准确的估算原始的连续函数。当原始连续函数并不知晓的情况下,如何根据离散的采样点或采样函数更为准确的估算其原始的连续函数呢?初看起来是没有一点头绪,因为离散的采样函数g(u)可能从任何在离散采样位置有确定值的连续函数f(x)中采样获得。

      但是,我们如果从频域角度尝试解决这个问题,那么这个问题将豁然开朗。倘若原始连续信号f(x)根据抽样定理进行离散化,那么函数f(x)有频带限制的特性-----不可能包含任意高于采样频率一半的频率的信号。这就意味着,重构出来的信号只包含某一限制区域的频率。

     数字信号中所有频率只与采样频率有关。假设我们以t = 1为采样间隔,采样频率即为:

    那么,根据抽样定理可知,原始信号最大的频率为wmax=π,,为了分离傅里叶频谱(周期性的)中对应的频谱范围-wmax………. wmax,我们把频谱函数G(w)乘以宽度为正负Pid的一个方形窗口函数,即

      这被称之为理想的低通滤波。它把所有频率高于π的信号切除,只保留频率小于等于π以内的信号。根据卷积特性,如果两个原始函数服从线性卷积,那么它们卷积的傅里叶变换结果即为两个原始函数频谱函数的点积,即:

离散信号的插值原理:时域和频域之间的关系


      由此,我们可以得出,在时域中对应的窗口频谱函数为:

     理论上来说,对于重构符合抽烟定理的连续信号,Sinc(x)是一个理想的插值函数。为了利用离散函数g(u) 计算任意位置x0的插值,Sinc函数必须移位x0,之后乘以离散函数的所有离散值,其最后的插值为所有乘积之和。假设g(u) 和Sinc(x)符合线性卷积,那么插值之后的值,可以表示为:

    由插值公式可知,利用离散函数g(u)计算任意位置x0的插值时,不仅仅只是利用采样点周围的领域各点,而是利用的离散函数中无限多个采样点,每个采样的权重为采样点与插值点x0之间的距离函数计算而得(距离函数为1/Pi*(x0-u))

     如果连续函数符合抽样定理,那么它能够通过Sinc(x)函数进行插值,从离散的信号中准确的重构出来。如下图所示:


                                            Sinc(x)在不同类型信号中进行插值。重构的函数(a),符合抽c频率限制。阶跃函数(b)和脉冲函数(c)通过Sinc(x)进行插值时,将产生振铃效应。


3.通过卷积进行插值

     如前所述,重构连续信号可以描述为一种线性卷积的操作。因此,我们可以把插值看作为离散函数g(u)和某一连续插值核函数做卷积,即

   插值函数Sinc(x)显然是插值核函数的一种特例。相类似的,对于一维函数的最近邻插值运算中,其插值核函数可以表示为:


  对于一维函数中的线性插值运算总,其插值核函数可以表示为:

最近邻插值卷积核函数(a),线性插值卷积核函数(b)


最近邻插值示例(a-c),线性插值示例(d-f)


4.三次多项式插值

      由于Sinc(x)函数的无限性和其衰减所带来的振铃效应,在实际应用中,我们并不使用Sinc(x)作为其插值核函数。因此,实际应用中常常使用Sinc函数的截断版本或Sinc函数的近似函数作为插值核函数。三次多项式插值一种常用的近似于Sinc截断版本的卷积核函数,其卷积核函数是由三次多项式组成:

    实际应用当中,常常使用a为1的三次多项式组成的卷积函数。即上式改写为:


    与Sinc函数相反,三次多项式插值卷积核函数取值范围比较小,因此很方便计算。由于当x>=2的时候,其权重值为0,因此,在插值计算的时候只考虑一下四点即可:

    因此,一维立方插值函数可以表示为

5.二维插值

    上述各个章节中,只是考虑了从一维离散信号中进行插值运算。而数字图像是二维离散信号,对二维离散信号进行插值运算类似于一维插值运算。在二维信号中,理想的插值函数为:

   

    同一维插值中Sinc函数特性一样,在二维插值应用中,我们并不是使用SINC作为插值函数,而是使用类似一维中的其他插值函数。比如最近邻插值函数、线性插值函数、三次多项式插值函数等。

二维最近邻插值

对于给定的连续坐标点(x0,y0),与其最近的像素坐标即为分别对x坐标方向和y坐标方向进行取整。即


     二维最近邻插值中,其卷积核函数可以表示为:

    二维最近邻插值中,插值生成的图像将产生比较明显的马赛克,效果不是很好。

   最近邻插值关键代码:

  1. /*
  2. input: 8bit gray BMP Source image and zoom width and height
  3. output: 8bit gray BMP Out Image
  4. */
  5. #include"Bilateral_Filter.h"
  6. #include"YUV2BMP.h"
  7. double Wcub_Function(double x)
  8. {
  9. double ReturnValue = 0;
  10. if (fabs(x)>=0 && fabs(x)<1)
  11. {
  12. ReturnValue = pow(fabs(x),3)-2*pow(fabs(x),2)+1;
  13. }
  14. if (fabs(x)>=1 && fabs(x)<2)
  15. {
  16. ReturnValue = -pow(fabs(x),3)+5*pow(fabs(x),2)-8*fabs(x)+4;
  17. }
  18. if (fabs(x)>2)
  19. {
  20. ReturnValue = 0;
  21. }
  22. return ReturnValue;
  23. }
  24. double Wbil_Function(double x)
  25. {
  26. double Return_Value =0;
  27. if (fabs(x)<1)
  28. {
  29. Return_Value = 1-x;
  30. }
  31. if (fabs(x)>=1)
  32. {
  33. Return_Value = 0;
  34. }
  35. return Return_Value;
  36. }
  37. int Image_Interpolation(IMAGE_TYPE *BMP8_img,DWORD Zoom_width, DWORD Zoom_height)
  38. {
  39. DWORD Source_width,Source_height;
  40. WORD Source_biBitCount,Zoom_biBitCount;
  41. T_U32 Source_linebyte,Zoom_linebyte;
  42. T_U8 *Source_dst,*Zoom_dst,*source_img,*Zoom_img;
  43. double p,q,Zoon_Coff_x,Zoom_Coff_y,a,b,TempValue,MidLeft_Point,MidRight_Point;
  44. int InterX0,InterY0,x0,y0,i,j,Row,Col,UpRight_Point,UpLeft_Point,BottomLeft_Point,BottomRight_Point;
  45. BITMAPFILEHEADER Source_bf,Zoom_bf;
  46. BITMAPINFOHEADER Source_bi,Zoom_bi;
  47. FILE *InterpolationBMP_fp = fopen("Interpolation_Image.bmp","wb");
  48. RGBQUAD colortable[256];
  49. RGBQUAD* pColorTable1 = colortable;
  50. if(NULL == InterpolationBMP_fp)
  51. {
  52. printf("Can't open Interpolation_Image.bmp.\n");
  53. return -1;
  54. }
  55. for (i = 0; i<256; ++i)
  56. {
  57. colortable[i].rgbBlue = i;
  58. colortable[i].rgbGreen = i;
  59. colortable[i].rgbRed = i;
  60. colortable[i].rgbReserved = 0;
  61. }
  62. memset(&Source_bf, 0, sizeof(Source_bf));
  63. memset(&Source_bi, 0, sizeof(Source_bi));
  64. source_img = BMP8_img;
  65. memcpy(&Source_bf,source_img,14);
  66. memcpy(&Source_bi,&source_img[14],40);
  67. Source_height = Source_bi.biHeight;
  68. Source_width = Source_bi.biWidth;
  69. Source_biBitCount = Source_bi.biBitCount;//每一个像素由24 bits表示,即RGB分量每一个分量用8 bits表示
  70. Source_linebyte = (Source_width * Source_bi.biBitCount / 8 + 3) / 4 * 4;
  71. Source_dst = source_img+54+1024;
  72. memset(&Zoom_bf, 0, sizeof(Source_bf));
  73. memset(&Zoom_bi, 0, sizeof(Source_bi));
  74. Zoom_linebyte = (Zoom_width * Source_bi.biBitCount / 8 + 3) / 4 * 4;
  75. Zoom_bf.bfType = Source_bf.bfType;
  76. Zoom_bf.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+1024+Zoom_linebyte*Zoom_height;
  77. Zoom_bf.bfReserved1 = Source_bf.bfReserved1;
  78. Zoom_bf.bfReserved2 = Source_bf.bfReserved2;
  79. Zoom_bf.bfOffbits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+1024;
  80. Zoom_bi.biSize = 40;
  81. Zoom_bi.biHeight = Zoom_height;
  82. Zoom_bi.biWidth = Zoom_width;
  83. Zoom_bi.biBitCount = Source_bi.biBitCount;;//每一个像素由24 bits表示,即RGB分量每一个分量用8 bits表示
  84. Zoom_bi.biPlanes = 1;
  85. Zoom_bi.biCompression = 0;
  86. Zoom_bi.biCompression = 0;
  87. Zoom_bi.biSizeImage = 1024+Zoom_linebyte*Zoom_bi.biHeight;
  88. Zoom_bi.biXPelsPerMeter = 0;
  89. Zoom_bi.biYPelsPerMter = 0;
  90. Zoom_bi.biClrImportant = 0;
  91. Zoom_bi.biClrUsed = 0;
  92. fwrite(&Zoom_bf,sizeof(BITMAPFILEHEADER),1,InterpolationBMP_fp);
  93. fwrite(&Zoom_bi,sizeof(BITMAPINFOHEADER),1,InterpolationBMP_fp);
  94. fwrite(pColorTable1, sizeof(RGBQUAD), 256, InterpolationBMP_fp);
  95. Zoom_img = (T_U8*)malloc(Zoom_linebyte*Zoom_height);
  96. memset(Zoom_img,0,Zoom_height*Zoom_linebyte);
  97. Zoom_Coff_y = (double)Source_height/Zoom_height;
  98. Zoon_Coff_x = (double)Source_width/Zoom_width;
  99. //Nearest-neighbor interpolation
  100. for(i = 0;i < Zoom_height;i++)
  101. {
  102. y0 = floor(Zoom_Coff_y*i+0.5);
  103. for(j = 0;j < Zoom_width;j++)
  104. {
  105. x0 = floor(Zoon_Coff_x*j+0.5);
  106. Zoom_img[i*Zoom_linebyte+j] = Source_dst[y0*Source_linebyte+x0];
  107. }
  108. }
  109. fwrite(Zoom_img,Zoom_height*Zoom_linebyte,1,InterpolationBMP_fp);
  110. fclose(InterpolationBMP_fp);
  111. InterpolationBMP_fp = NULL;
  112. free(Zoom_img);
  113. return 0;
  114. }


双线性插值

    在二维中与一维线性插值对应的是双线性插值。其插值过程可以表示为:

双线性插值原理图

    双线性插值中,对于给定的插值点(x0,y0),我们首先在原始图像中找到其最近的四个像素A、B、C、D:

   其中u0为x0向下取整,v0为y0向下取整,四个像素点的灰度值分别中水平方向和竖直方向进行插值。中间点E、F是由插值点坐标(x0,y0)与u0之间的水平距离决定,a = x0-u0:

由前面小结中讲述的线性插值原理,可得,


同理可得:




  最后插值灰度值G在竖直方向进行再次插值,b = y0-v0:



  双线性插值中,其卷积核函数可以表示为:

双线性插值关键代码:

  1. /*
  2. input: 8bit gray BMP Source image and zoom width and height
  3. output: 8bit gray BMP Out Image
  4. */
  5. #include"Bilateral_Filter.h"
  6. #include"YUV2BMP.h"
  7. double Wcub_Function(double x)
  8. {
  9. double ReturnValue = 0;
  10. if (fabs(x)>=0 && fabs(x)<1)
  11. {
  12. ReturnValue = pow(fabs(x),3)-2*pow(fabs(x),2)+1;
  13. }
  14. if (fabs(x)>=1 && fabs(x)<2)
  15. {
  16. ReturnValue = -pow(fabs(x),3)+5*pow(fabs(x),2)-8*fabs(x)+4;
  17. }
  18. if (fabs(x)>2)
  19. {
  20. ReturnValue = 0;
  21. }
  22. return ReturnValue;
  23. }
  24. double Wbil_Function(double x)
  25. {
  26. double Return_Value =0;
  27. if (fabs(x)<1)
  28. {
  29. Return_Value = 1-x;
  30. }
  31. if (fabs(x)>=1)
  32. {
  33. Return_Value = 0;
  34. }
  35. return Return_Value;
  36. }
  37. int Image_Interpolation(IMAGE_TYPE *BMP8_img,DWORD Zoom_width, DWORD Zoom_height)
  38. {
  39. DWORD Source_width,Source_height;
  40. WORD Source_biBitCount,Zoom_biBitCount;
  41. T_U32 Source_linebyte,Zoom_linebyte;
  42. T_U8 *Source_dst,*Zoom_dst,*source_img,*Zoom_img;
  43. double p,q,Zoon_Coff_x,Zoom_Coff_y,a,b,TempValue,MidLeft_Point,MidRight_Point;
  44. int InterX0,InterY0,x0,y0,i,j,Row,Col,UpRight_Point,UpLeft_Point,BottomLeft_Point,BottomRight_Point;
  45. BITMAPFILEHEADER Source_bf,Zoom_bf;
  46. BITMAPINFOHEADER Source_bi,Zoom_bi;
  47. FILE *InterpolationBMP_fp = fopen("Interpolation_Image.bmp","wb");
  48. RGBQUAD colortable[256];
  49. RGBQUAD* pColorTable1 = colortable;
  50. if(NULL == InterpolationBMP_fp)
  51. {
  52. printf("Can't open Interpolation_Image.bmp.\n");
  53. return -1;
  54. }
  55. for (i = 0; i<256; ++i)
  56. {
  57. colortable[i].rgbBlue = i;
  58. colortable[i].rgbGreen = i;
  59. colortable[i].rgbRed = i;
  60. colortable[i].rgbReserved = 0;
  61. }
  62. memset(&Source_bf, 0, sizeof(Source_bf));
  63. memset(&Source_bi, 0, sizeof(Source_bi));
  64. source_img = BMP8_img;
  65. memcpy(&Source_bf,source_img,14);
  66. memcpy(&Source_bi,&source_img[14],40);
  67. Source_height = Source_bi.biHeight;
  68. Source_width = Source_bi.biWidth;
  69. Source_biBitCount = Source_bi.biBitCount;//每一个像素由24 bits表示,即RGB分量每一个分量用8 bits表示
  70. Source_linebyte = (Source_width * Source_bi.biBitCount / 8 + 3) / 4 * 4;
  71. Source_dst = source_img+54+1024;
  72. memset(&Zoom_bf, 0, sizeof(Source_bf));
  73. memset(&Zoom_bi, 0, sizeof(Source_bi));
  74. Zoom_linebyte = (Zoom_width * Source_bi.biBitCount / 8 + 3) / 4 * 4;
  75. Zoom_bf.bfType = Source_bf.bfType;
  76. Zoom_bf.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+1024+Zoom_linebyte*Zoom_height;
  77. Zoom_bf.bfReserved1 = Source_bf.bfReserved1;
  78. Zoom_bf.bfReserved2 = Source_bf.bfReserved2;
  79. Zoom_bf.bfOffbits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+1024;
  80. Zoom_bi.biSize = 40;
  81. Zoom_bi.biHeight = Zoom_height;
  82. Zoom_bi.biWidth = Zoom_width;
  83. Zoom_bi.biBitCount = Source_bi.biBitCount;;//每一个像素由24 bits表示,即RGB分量每一个分量用8 bits表示
  84. Zoom_bi.biPlanes = 1;
  85. Zoom_bi.biCompression = 0;
  86. Zoom_bi.biCompression = 0;
  87. Zoom_bi.biSizeImage = 1024+Zoom_linebyte*Zoom_bi.biHeight;
  88. Zoom_bi.biXPelsPerMeter = 0;
  89. Zoom_bi.biYPelsPerMter = 0;
  90. Zoom_bi.biClrImportant = 0;
  91. Zoom_bi.biClrUsed = 0;
  92. fwrite(&Zoom_bf,sizeof(BITMAPFILEHEADER),1,InterpolationBMP_fp);
  93. fwrite(&Zoom_bi,sizeof(BITMAPINFOHEADER),1,InterpolationBMP_fp);
  94. fwrite(pColorTable1, sizeof(RGBQUAD), 256, InterpolationBMP_fp);
  95. Zoom_img = (T_U8*)malloc(Zoom_linebyte*Zoom_height);
  96. memset(Zoom_img,0,Zoom_height*Zoom_linebyte);
  97. Zoom_Coff_y = (double)Source_height/Zoom_height;
  98. Zoon_Coff_x = (double)Source_width/Zoom_width;
  99. //Bilinear interpolation
  100. for(i = 0;i < Zoom_height;i++)
  101. {
  102. y0 = floor((double)Zoom_Coff_y*i);
  103. b = Zoom_Coff_y*i - y0;
  104. for(j = 0;j < Zoom_width;j++)
  105. {
  106. x0 = floor((double)Zoon_Coff_x*j);
  107. a = Zoon_Coff_x*j -x0;
  108. UpLeft_Point = Source_dst[y0*Source_linebyte+x0];
  109. UpRight_Point = Source_dst[y0*Source_linebyte+x0+1];
  110. BottomLeft_Point = Source_dst[(y0+1)*Source_linebyte+x0];
  111. BottomRight_Point = Source_dst[(y0+1)*Source_linebyte+(x0+1)];
  112. MidLeft_Point = UpLeft_Point+a*(UpRight_Point-UpLeft_Point);
  113. MidRight_Point = BottomLeft_Point+a*(BottomRight_Point-BottomLeft_Point);
  114. TempValue = MidLeft_Point+b*(MidRight_Point-MidLeft_Point);
  115. //TempValue = (a-1)*(b-1)*UpLeft_Point+ a*(1-b)*UpRight_Point + (1-a)*b*BottomLeft_Point + a*b*BottomRight_Point;
  116. Zoom_img[i*Zoom_linebyte+j] = CLIP255(TempValue);
  117. }
  118. }
  119. fwrite(Zoom_img,Zoom_height*Zoom_linebyte,1,InterpolationBMP_fp);
  120. fclose(InterpolationBMP_fp);
  121. InterpolationBMP_fp = NULL;
  122. free(Zoom_img);
  123. return 0;
  124. }

 

双三次样条插值

     二维三次样条卷积核函数可以用x和y方向的卷积核函数相乘表示:

   由此,计算双三次样条插值可以分别在x,y方向计算

  其中u0=[x0]-1+i,v0=[y0]-1+i,pj表示的是x方向第j行插值的中间值,[x0],[y0]分别表示x0和y0向下取整。双线性插值是基于4*4邻域进行插值。其过程如下:


    三次样条插值关键代码:

  1. /*
  2. input: 8bit gray BMP Source image and zoom width and height
  3. output: 8bit gray BMP Out Image
  4. */
  5. #include"Bilateral_Filter.h"
  6. #include"YUV2BMP.h"
  7. double Wcub_Function(double x)
  8. {
  9. double ReturnValue = 0;
  10. if (fabs(x)>=0 && fabs(x)<1)
  11. {
  12. ReturnValue = pow(fabs(x),3)-2*pow(fabs(x),2)+1;
  13. }
  14. if (fabs(x)>=1 && fabs(x)<2)
  15. {
  16. ReturnValue = -pow(fabs(x),3)+5*pow(fabs(x),2)-8*fabs(x)+4;
  17. }
  18. if (fabs(x)>2)
  19. {
  20. ReturnValue = 0;
  21. }
  22. return ReturnValue;
  23. }
  24. double Wbil_Function(double x)
  25. {
  26. double Return_Value =0;
  27. if (fabs(x)<1)
  28. {
  29. Return_Value = 1-x;
  30. }
  31. if (fabs(x)>=1)
  32. {
  33. Return_Value = 0;
  34. }
  35. return Return_Value;
  36. }
  37. int Image_Interpolation(IMAGE_TYPE *BMP8_img,DWORD Zoom_width, DWORD Zoom_height)
  38. {
  39. DWORD Source_width,Source_height;
  40. WORD Source_biBitCount,Zoom_biBitCount;
  41. T_U32 Source_linebyte,Zoom_linebyte;
  42. T_U8 *Source_dst,*Zoom_dst,*source_img,*Zoom_img;
  43. double p,q,Zoon_Coff_x,Zoom_Coff_y,a,b,TempValue,MidLeft_Point,MidRight_Point;
  44. int InterX0,InterY0,x0,y0,i,j,Row,Col,UpRight_Point,UpLeft_Point,BottomLeft_Point,BottomRight_Point;
  45. BITMAPFILEHEADER Source_bf,Zoom_bf;
  46. BITMAPINFOHEADER Source_bi,Zoom_bi;
  47. FILE *InterpolationBMP_fp = fopen("Interpolation_Image.bmp","wb");
  48. RGBQUAD colortable[256];
  49. RGBQUAD* pColorTable1 = colortable;
  50. if(NULL == InterpolationBMP_fp)
  51. {
  52. printf("Can't open Interpolation_Image.bmp.\n");
  53. return -1;
  54. }
  55. for (i = 0; i<256; ++i)
  56. {
  57. colortable[i].rgbBlue = i;
  58. colortable[i].rgbGreen = i;
  59. colortable[i].rgbRed = i;
  60. colortable[i].rgbReserved = 0;
  61. }
  62. memset(&Source_bf, 0, sizeof(Source_bf));
  63. memset(&Source_bi, 0, sizeof(Source_bi));
  64. source_img = BMP8_img;
  65. memcpy(&Source_bf,source_img,14);
  66. memcpy(&Source_bi,&source_img[14],40);
  67. Source_height = Source_bi.biHeight;
  68. Source_width = Source_bi.biWidth;
  69. Source_biBitCount = Source_bi.biBitCount;//每一个像素由24 bits表示,即RGB分量每一个分量用8 bits表示
  70. Source_linebyte = (Source_width * Source_bi.biBitCount / 8 + 3) / 4 * 4;
  71. Source_dst = source_img+54+1024;
  72. memset(&Zoom_bf, 0, sizeof(Source_bf));
  73. memset(&Zoom_bi, 0, sizeof(Source_bi));
  74. Zoom_linebyte = (Zoom_width * Source_bi.biBitCount / 8 + 3) / 4 * 4;
  75. Zoom_bf.bfType = Source_bf.bfType;
  76. Zoom_bf.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+1024+Zoom_linebyte*Zoom_height;
  77. Zoom_bf.bfReserved1 = Source_bf.bfReserved1;
  78. Zoom_bf.bfReserved2 = Source_bf.bfReserved2;
  79. Zoom_bf.bfOffbits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+1024;
  80. Zoom_bi.biSize = 40;
  81. Zoom_bi.biHeight = Zoom_height;
  82. Zoom_bi.biWidth = Zoom_width;
  83. Zoom_bi.biBitCount = Source_bi.biBitCount;;//每一个像素由24 bits表示,即RGB分量每一个分量用8 bits表示
  84. Zoom_bi.biPlanes = 1;
  85. Zoom_bi.biCompression = 0;
  86. Zoom_bi.biCompression = 0;
  87. Zoom_bi.biSizeImage = 1024+Zoom_linebyte*Zoom_bi.biHeight;
  88. Zoom_bi.biXPelsPerMeter = 0;
  89. Zoom_bi.biYPelsPerMter = 0;
  90. Zoom_bi.biClrImportant = 0;
  91. Zoom_bi.biClrUsed = 0;
  92. fwrite(&Zoom_bf,sizeof(BITMAPFILEHEADER),1,InterpolationBMP_fp);
  93. fwrite(&Zoom_bi,sizeof(BITMAPINFOHEADER),1,InterpolationBMP_fp);
  94. fwrite(pColorTable1, sizeof(RGBQUAD), 256, InterpolationBMP_fp);
  95. Zoom_img = (T_U8*)malloc(Zoom_linebyte*Zoom_height);
  96. memset(Zoom_img,0,Zoom_height*Zoom_linebyte);
  97. Zoom_Coff_y = (double)Source_height/Zoom_height;
  98. Zoon_Coff_x = (double)Source_width/Zoom_width;
  99. //Bicubic interpolation with col
  100. for(Col = 0 ;Col < Zoom_height;Col++)
  101. {
  102. y0 = floor(Zoom_Coff_y*Col);
  103. for(Row = 0;Row < Zoom_width;Row++)
  104. {
  105. x0 = floor(Zoon_Coff_x*Row);
  106. q = 0;
  107. for(i = 0;i < 4;i++)
  108. {
  109. InterY0 = y0+i-1;
  110. p = 0;
  111. for(j = 0;j < 4;j++)
  112. {
  113. InterX0 = x0+j-1;
  114. p += Source_dst[InterY0*Source_linebyte+InterX0]*Wcub_Function(Zoon_Coff_x*Row-InterX0);
  115. }
  116. q += p*Wcub_Function(Zoom_Coff_y*Col-InterY0);
  117. }
  118. Zoom_img[Col*Zoom_linebyte+Row] = CLIP255(q);
  119. }
  120. }
  121. fwrite(Zoom_img,Zoom_height*Zoom_linebyte,1,InterpolationBMP_fp);
  122. fclose(InterpolationBMP_fp);
  123. InterpolationBMP_fp = NULL;
  124. free(Zoom_img);
  125. return 0
  126. }

6.插值结果

                                   
                                   256*256大小 原始图像  

            
                                                                                                                                            512*512大小最近邻插值结果
                
                                                                                                                                     512*512大小 双线性插
        
                                                                                                                                       512*512 大小三次多项式插值

      上述图像分别是256*256大小的原始图像,以及用最近邻插值、双线性插值、三次多项式插值放大两倍后的图像。由图可以看出,使用最近邻插值放大两倍后的图像,有比较明显的方块,图像边缘不平滑。双向性插值核三次多项式插值放大两倍后的图像比最近邻放大的图像边缘较为平滑。且三次多项式插值放大后的图像比双线性插值放大后的图像更加接近原始图像。



























声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/193281
推荐阅读
相关标签
  

闽ICP备14008679号