首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

几种插值算法对比研究

  • 23-09-22 20:42
  • 2864
  • 5041
blog.csdn.net

[研究内容]

目前比较常用的几种插值算法

[正文]

目前比较常用的插值算法有这么几种:最邻近插值,双线性二次插值,三次插值,

Lanczos插值等等,今天我们来对比一下这几种插值效果的优劣。

1,最邻近插值

    最邻近插值算法也叫做零阶插值算法,主要原理是让输出像素的像素值等于邻域内

离它距离最近的像素值。例如下图中所示,P1距离0灰度值像素的距离小于100灰度值的

距离,因此,P1位置的插值像素为0。这个算法的优点是计算简单方便,缺点是图像容

易出现锯齿。

2,双线性二次插值

    在介绍双线性插值前,我们先介绍一下拉格朗日插值多项式。本文参考引用均来自

张铁的《数值分析》一书。

 

  我们的方法是这样的,根据水平方向上的双线性二次插值,由f(I,j)和f(i+1,j)求取f(x,j),由

f(I,j+1)和f(i+1,j+1)求取f(x,j+1),然后再根据这两点的二次插值求取f(x,y)。

  根据前面的例题,我们可以很容易的求取各点插值如下:

                        f(x,j)=(i+1-x)f(I,j)+(x-i)f(i+1,j)               公式1-(4)

                      f(x,j+1)=(i+1-x)f(I,j+1)+(x-i)f(i+1,j+1)           公式1-(5)

                       f(x,y)=(i+1-y)f(x,j)+(y-j)f(x,j+1)               公式1-(6)

  以上三式综合可以得到:

  f(x,y)=(j+1-y)(i+1-x)f(I,j)+(j+1-y)(x-i)f(i+1,j)+(y-j)(i+1-x)f(I,j+1)+(y-j)(x-i)f(i+1,j+1)     公式1-(7)

  我们令x=i+p,y=j+q得:

  f(i+p,j+q)=(1-q)(1-p)f(I,j)+p(1-q)f(i+1,j)+q(1-p)f(I,j+1)+pqf(i+1,j+1)                公式1-(8)

  上式即为数字图像处理中的双线性二次插值公式。


3,双线性三次插值


4,Lanczos插值算法

该算法的主要原理介绍地址:http://iyenn.com/index/link?url=http://en.wikipedia.org/wiki/Lanczos_resampling

这里我大概介绍一下算法的流程:

这个算法也是一个模板算法,主要内容是计算模板中的权重信息。

对于一维信息,假如我们输入点集为X,那么,Lanczos对应有个窗口模板Window,这个窗口中每个位置的权重计算如下:

                         1-(12)


                 Fig.6 Lanczos

通常,这个a取2或者3,a=2时,该算法适用于图像缩小插值;a=3时,该算法适用于放大插值;对应不同a值得Lanczos插值曲线如上图6所示;上述的公式分别为连续和离散的公式。我们根据输入点X的位置,确定对应window中不同位置的权重L(x),然后对模板中的点值取加权平均,公式如下:

                                                    1-(13)

这个S(x)即为X处的插值结果。

根据上述一维插值,推广得到多维插值公式如下(这里以二维为例):

 1-(14)


上述内容是对不同插值算法简单的进行了介绍,如果不明白可以查找相关知识。

现在我们来看下相应的效果图:


上面的一组效果图均是先将原图缩小50%,然后使用不同算法放大到原图大小得到的。由上面这组图我们可以发现,效果最差的是最邻近插值算法,效果最好的是双线性三次插值,Lanczos算法跟三次插值大致一致;

由于编程语言不同,可能会造成耗时的差距,但是,对于同一种语言,统计得出:最邻近插值速度最快,三次插值速度最慢,而Lanczos算法与二次插值相仿。

综上,Lanczos插值具有速度快,效果好,性价比最高的优点,这也是目前此算法比较流行的原因。

最后,给出一个本人使用C#写的Lanczos代码,代码未经优化,仅供测试,这里的NP是对权重计算构建的映射表:

  1. private Bitmap ZoomLanczos2Apply(Bitmap srcBitmap, double k)
  2. {
  3. Bitmap src = new Bitmap(srcBitmap);
  4. int width = src.Width;
  5. int height = src.Height;
  6. BitmapData srcData = src.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
  7. byte* pS = (byte*)srcData.Scan0;
  8. int w = (int)((double)width * k);
  9. int h = (int)((double)height * k);
  10. Bitmap dst = new Bitmap(w, h, PixelFormat.Format32bppArgb);
  11. BitmapData dstData = dst.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
  12. byte* d = (byte*)dstData.Scan0;
  13. int offset = dstData.Stride - w * 4;
  14. int x = 0, y = 0;
  15. double p = 0, q = 0;
  16. double n1 = 0, n2 = 0, n3 = 0, n4 = 0, nSum = 0;
  17. int p0 = 0, p1 = 0, p2 = 0, p3 = 0, p4 = 0, gray = 0;
  18. byte* temp = null;
  19. double[] NP1 = new double[] { -0.00623896218505032, -0.0122238956025722, -0.0179556611741633, -0.0234353793884155, -0.028664425422539, -0.0336444239814841, -0.0383772438642046, -0.0428649922670393, -0.0471100088344975, -0.0511148594680326, -0.0548823299036605, -0.0584154190695433, -0.0617173322348938, -0.0647914739617815, -0.0676414408716196, -0.0702710142382982, -0.0726841524200902, -0.0748849831426012, -0.0768777956451566, -0.0786670327031274, -0.0802572825387739, -0.0816532706332581, -0.0828598514525135, -0.0838820000996894, -0.0847248039068906, -0.0853934539789171, -0.0858932367016755, -0.0862295252278804, -0.0864077709525887, -0.0864334949910196, -0.086312279671003, -0.0860497600522689, -0.0856516154846428, -0.0851235612170509, -0.0844713400690516, -0.0837007141764163, -0.0828174568220629, -0.0818273443634177, -0.0807361482670294, -0.0795496272610035, -0.0782735196155422, -0.0769135355615895, -0.0754753498572731, -0.0739645945115212, -0.0723868516738999, -0.0707476466993797, -0.0690524413963838, -0.0673066274661114, -0.0655155201407567, -0.0636843520278618, -0.0618182671676555, -0.0599223153098279, -0.0580014464157926, -0.0560605053920726, -0.0541042270600343, -0.0521372313667693, -0.0501640188415028, -0.048188966301476, -0.0462163228108206, -0.0442502058955092, -0.0422945980170336, -0.0403533433070252, -0.0384301445645995, -0.0365285605177724, -0.0346520033498648, -0.0328037364913793, -0.0309868726774121, -0.0292043722702325, -0.0274590418462525, -0.0257535330461864, -0.0240903416868009, -0.0224718071322479, -0.0209001119225812, -0.0193772816566703, -0.0179051851263444, -0.0164855346982315, -0.015119886939392, -0.013809643482501, -0.0125560521259855, -0.0113602081641975, -0.0102230559423803, -0.00914539063088284, -0.00812786021277406, -0.00717096767873418, -0.00627507342282205, -0.00544039783246632, -0.00466702406578012, -0.00395490100907222, -0.00330384640720963, -0.00271355015928674, -0.00218357777186753, -0.00171337396189679, -0.00130226640121749, -0.000949469594490465, -0.00065408888218426, -0.000415124560192089, -0.000231476107535702, -0.000101946513534946, -0 };
  20. double[] NP2 = new double[] { 0.999794398630316, 0.999177779156011, 0.998150695261436, 0.996714069021198, 0.994869189802256, 0.992617712728975, 0.989961656713271, 0.986903402052547, 0.983445687598761, 0.979591607502511, 0.975344607536654, 0.9707084810045, 0.965687364238256, 0.960285731693901, 0.954508390649264, 0.948360475512591, 0.941847441749449, 0.934975059436304, 0.927749406449645, 0.920176861299994, 0.912264095620641, 0.904018066321406, 0.895446007418168, 0.886555421549337, 0.877354071190877, 0.867849969581877, 0.858051371373022, 0.847966763010743, 0.83760485287009, 0.826974561149762, 0.816085009542993, 0.804945510698284, 0.793565557484247, 0.781954812073053, 0.770123094857198, 0.758080373214511, 0.745836750136481, 0.733402452735159, 0.720787820644003, 0.708003294328147, 0.695059403319663, 0.68196675439345, 0.668736019699406, 0.655377924866579, 0.641903237094975, 0.628322753250659, 0.614647287979759, 0.600887661856885, 0.587054689583387, 0.573159168250756, 0.559211865684328, 0.545223508882287, 0.531204772564777, 0.517166267847729, 0.503118531055783, 0.489072012688425, 0.47503706655321, 0.461023939079635, 0.447042758826945, 0.433103526198797, 0.419216103377392, 0.405390204489315, 0.391635386014941, 0.37796103745288, 0.364376372250524, 0.350890419011333, 0.33751201298905, 0.324249787878619, 0.311112167913061, 0.298107360275149, 0.285243347832182, 0.272527882201696, 0.259968477155437, 0.247572402368387, 0.235346677519141, 0.223298066747373, 0.211433073473617, 0.199757935586031, 0.188278620998268, 0.177000823582037, 0.165929959477376, 0.155071163783102, 0.144429287629353, 0.13400889563358, 0.123814263740785, 0.113849377448258, 0.104117930414501, 0.0946233234514916, 0.0853686638988765, 0.0763567653781721, 0.0675901479244855, 0.059071038492763, 0.050801371835042, 0.0427827917446759, 0.0350166526629909, 0.0275040216433488, 0.0202456806670952, 0.0132421293054104, 0.00649358772061002 };
  21. double[] NP3 = new double[] { 0.00649358772061002, 0.0132421293054104, 0.0202456806670952, 0.0275040216433488, 0.0350166526629909, 0.0427827917446759, 0.0508013718350421, 0.059071038492763, 0.0675901479244855, 0.0763567653781721, 0.0853686638988765, 0.0946233234514916, 0.104117930414501, 0.113849377448258, 0.123814263740785, 0.13400889563358, 0.144429287629353, 0.155071163783102, 0.165929959477376, 0.177000823582037, 0.188278620998268, 0.199757935586031, 0.211433073473617, 0.223298066747373, 0.235346677519141, 0.247572402368387, 0.259968477155437, 0.272527882201696, 0.285243347832182, 0.298107360275149, 0.311112167913061, 0.324249787878619, 0.33751201298905, 0.350890419011333, 0.364376372250524, 0.37796103745288, 0.391635386014941, 0.405390204489315, 0.419216103377392, 0.433103526198797, 0.447042758826944, 0.461023939079634, 0.475037066553209, 0.489072012688425, 0.503118531055783, 0.517166267847729, 0.531204772564777, 0.545223508882287, 0.559211865684328, 0.573159168250756, 0.587054689583387, 0.600887661856885, 0.614647287979759, 0.628322753250659, 0.641903237094975, 0.655377924866579, 0.668736019699406, 0.68196675439345, 0.695059403319663, 0.708003294328147, 0.720787820644003, 0.733402452735159, 0.745836750136481, 0.758080373214511, 0.770123094857198, 0.781954812073053, 0.793565557484247, 0.804945510698284, 0.816085009542993, 0.826974561149762, 0.837604852870089, 0.847966763010743, 0.858051371373022, 0.867849969581877, 0.877354071190877, 0.886555421549337, 0.895446007418168, 0.904018066321406, 0.912264095620641, 0.920176861299994, 0.927749406449646, 0.934975059436304, 0.941847441749449, 0.948360475512591, 0.954508390649264, 0.960285731693901, 0.965687364238256, 0.9707084810045, 0.975344607536654, 0.979591607502512, 0.983445687598761, 0.986903402052547, 0.989961656713271, 0.992617712728975, 0.994869189802256, 0.996714069021198, 0.998150695261436, 0.999177779156011, 0.999794398630316 };
  22. double[] NP4 = new double[] { -0, -0.000101946513534946, -0.000231476107535702, -0.000415124560192089, -0.00065408888218426, -0.000949469594490465, -0.0013022664012175, -0.00171337396189679, -0.00218357777186754, -0.00271355015928674, -0.00330384640720965, -0.00395490100907222, -0.00466702406578012, -0.00544039783246632, -0.00627507342282205, -0.00717096767873415, -0.00812786021277406, -0.00914539063088281, -0.0102230559423803, -0.0113602081641975, -0.0125560521259855, -0.013809643482501, -0.015119886939392, -0.0164855346982315, -0.0179051851263444, -0.0193772816566703, -0.0209001119225812, -0.0224718071322479, -0.0240903416868009, -0.0257535330461864, -0.0274590418462525, -0.0292043722702326, -0.0309868726774121, -0.0328037364913794, -0.0346520033498648, -0.0365285605177724, -0.0384301445645995, -0.0403533433070252, -0.0422945980170336, -0.0442502058955092, -0.0462163228108205, -0.048188966301476, -0.0501640188415028, -0.0521372313667693, -0.0541042270600343, -0.0560605053920726, -0.0580014464157926, -0.0599223153098279, -0.0618182671676555, -0.0636843520278618, -0.0655155201407567, -0.0673066274661114, -0.0690524413963838, -0.0707476466993797, -0.0723868516738999, -0.0739645945115212, -0.0754753498572731, -0.0769135355615895, -0.0782735196155421, -0.0795496272610035, -0.0807361482670294, -0.0818273443634177, -0.0828174568220629, -0.0837007141764163, -0.0844713400690516, -0.0851235612170509, -0.0856516154846428, -0.0860497600522689, -0.086312279671003, -0.0864334949910196, -0.0864077709525887, -0.0862295252278804, -0.0858932367016755, -0.0853934539789171, -0.0847248039068906, -0.0838820000996894, -0.0828598514525135, -0.0816532706332581, -0.0802572825387739, -0.0786670327031274, -0.0768777956451566, -0.0748849831426012, -0.0726841524200902, -0.0702710142382982, -0.0676414408716196, -0.0647914739617815, -0.0617173322348938, -0.0584154190695433, -0.0548823299036604, -0.0511148594680326, -0.0471100088344975, -0.0428649922670393, -0.0383772438642045, -0.0336444239814841, -0.028664425422539, -0.0234353793884155, -0.0179556611741633, -0.0122238956025722, -0.00623896218505032 };
  23. for (int j = 0; j < h; j++)
  24. {
  25. q = (double)j / (double)k;
  26. y = (int)q;
  27. q = Math.Abs(q - (double)y);
  28. p0 = y * srcData.Stride;
  29. y = y >= height ? height - 1 : y;
  30. for (int i = 0; i < w; i++)
  31. {
  32. p = (double)i / (double)k;
  33. x = (int)p;
  34. p = Math.Abs(p - (double)x);
  35. temp = d + i * 4 + j * dstData.Stride;
  36. if (p != 0)
  37. {
  38. x = (x >= width - 3 ? width - 3 : x);
  39. x = x < 1 ? 1 : x;
  40. gray = (int)(p * 100.0) - 1;
  41. gray = Math.Max(0, gray);
  42. n1 = NP1[gray];
  43. n2 = NP2[gray];
  44. n3 = NP3[gray];
  45. n4 = 1.0 - n1 - n2 - n3;// NP4[gray];
  46. p2 = x * 4 + p0;
  47. p1 = p2 - 4;
  48. p3 = p2 + 4;
  49. p4 = p2 + 8;
  50. nSum = n1 + n2 + n3 + n4;
  51. gray = (int)((n1 * (double)((pS + p1)[0]) + n2 * (double)((pS + p2)[0]) + n3 * (double)((pS + p3)[0]) + n4 * (double)((pS + p4)[0])));
  52. gray = Math.Max(0, Math.Min(255, gray));
  53. temp[0] = (byte)gray;
  54. gray = (int)((n1 * (double)((pS + p1)[1]) + n2 * (double)((pS + p2)[1]) + n3 * (double)((pS + p3)[1]) + n4 * (double)((pS + p4)[1])));
  55. gray = Math.Max(0, Math.Min(255, gray));
  56. temp[1] = (byte)gray;
  57. gray = (int)((n1 * (double)((pS + p1)[2]) + n2 * (double)((pS + p2)[2]) + n3 * (double)((pS + p3)[2]) + n4 * (double)((pS + p4)[2])));
  58. gray = Math.Max(0, Math.Min(255, gray));
  59. temp[2] = (byte)gray;
  60. }
  61. else
  62. {
  63. x = x >= width ? width - 1 : x;
  64. gray = x * 4 + y * srcData.Stride;
  65. temp[0] = (byte)(pS + gray)[0];
  66. temp[1] = (byte)(pS + gray)[1];
  67. temp[2] = (byte)(pS + gray)[2];
  68. }
  69. temp[3] = (byte)255;
  70. }
  71. }
  72. for (int i = 0; i < w; i++)
  73. {
  74. p = (double)i / (double)k;
  75. x = (int)p;
  76. p = Math.Abs(p - (double)x);
  77. x = x >= width ? width - 1 : x;
  78. for (int j = 0; j < h; j++)
  79. {
  80. q = (double)j / (double)k;
  81. y = (int)q;
  82. q = Math.Abs(q - (double)y);
  83. p0 = y * srcData.Stride;
  84. temp = d + i * 4 + j * dstData.Stride;
  85. if (q != 0)
  86. {
  87. y = y >= height - 3 ? height - 3 : y;
  88. y = y < 1 ? 1 : y;
  89. gray = (int)(q * 100.0) - 1;
  90. gray = Math.Max(0, gray);
  91. n1 = NP1[gray];
  92. n2 = NP2[gray];
  93. n3 = NP3[gray];
  94. n4 = 1.0 - n1 - n2 - n3;// NP4[gray];
  95. nSum = n1 + n2 + n3 + n4;
  96. p2 = x * 4 + y * srcData.Stride;
  97. p1 = p2 - srcData.Stride;
  98. p3 = p2 + srcData.Stride;
  99. p4 = p3 + srcData.Stride;
  100. gray = (int)((n1 * (double)((pS + p1)[0]) + n2 * (double)((pS + p2)[0]) + n3 * (double)((pS + p3)[0]) + n4 * (double)((pS + p4)[0])));
  101. gray = Math.Max(0, Math.Min(255, gray));
  102. temp[0] = (byte)gray;
  103. gray = (int)((n1 * (double)((pS + p1)[1]) + n2 * (double)((pS + p2)[1]) + n3 * (double)((pS + p3)[1]) + n4 * (double)((pS + p4)[1])));
  104. gray = Math.Max(0, Math.Min(255, gray));
  105. temp[1] = (byte)gray;
  106. gray = (int)((n1 * (double)((pS + p1)[2]) + n2 * (double)((pS + p2)[2]) + n3 * (double)((pS + p3)[2]) + n4 * (double)((pS + p4)[2])));
  107. gray = Math.Max(0, Math.Min(255, gray));
  108. temp[2] = (byte)gray;
  109. }
  110. else
  111. {
  112. y = y >= height ? height - 1 : y;
  113. gray = x * 4 + y * srcData.Stride;
  114. temp[0] = (byte)(pS + gray)[0];
  115. temp[1] = (byte)(pS + gray)[1];
  116. temp[2] = (byte)(pS + gray)[2];
  117. }
  118. temp[3] = (byte)255;
  119. }
  120. }
  121. src.UnlockBits(srcData);
  122. dst.UnlockBits(dstData);
  123. return dst;
  124. }

 最后,分享一个专业的图像处理网站(微像素),里面有很多源代码下载:
http://www.zealpixel.com/portal.php 点击打开链接
文章知识点与官方知识档案匹配,可进一步学习相关知识
算法技能树首页概览51048 人正在系统学习中
注:本文转载自blog.csdn.net的Trent1985的文章"http://blog.csdn.net/trent1985/article/details/45150677#"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top