精华内容
下载资源
问答
  • 对图像进行最邻近插值,提高图像的分辨率。 对图像进行最邻近插值,提高图像的分辨率。 对图像进行最邻近插值,提高图像的分辨率。 对图像进行最邻近插值,提高图像的分辨率。
  • 使用python对2维图像采用最邻近插值和双线性插值算法实现旋转
  • 图片的旋转方法算法以及双线性插值,最邻近插值法 图片的旋转方法算法以及双线性插值,最邻近插值
  • 基于OpenCV实现的RGB图像通道值分离、最邻近插值法、双线性插值法。
  • 最邻近插值和双线性插值

    千次阅读 2020-04-29 19:51:18
    在所有插值缩放算法中要数最邻近插值最简单最暴力,当然效果也是最不好的。经过该算法进行放大的图片会出现马赛克现象,而进行缩小的图片也会丢失较大的图像信息。但是由于其简单,也是介绍该类算法不可不了解的 1. ...

      插值在图像中的应用一般为处理图像的缩放。所谓缩放就是缩小和放大。在所有插值缩放算法中要数最邻近插值最简单最暴力,当然效果也是最不好的。经过该算法进行放大的图片会出现马赛克现象,而进行缩小的图片也会丢失较大的图像信息。下面介绍两种插值法,最邻近插值和双线性插值。

    1. 最邻近插值法
      最近临插值算法的原理是在原图像中找到最近临的一个点,然后把这个点的像素值插入到目标图像中,最近临插值算法优点是算法简单,易于实现。
    算法公式如下:
           ori_x = dst_x * (ori_width / dst_width)
           ori_y = dst_y * (ori_height / dst_height)
    ori_x、ori_y为原图像的横纵点,dst_x、dst_y为缩放后横纵点,ori_witdh/dst_height为缩放比率。对一个图像放大,实际上是先计算原图像中的虚拟位置,比如4x4的图像要缩放到8x8,即在4x4原图像中横坐标4个点生成8个点,虚拟位置可以通过插值求出,出现小数时我们可以用四舍五入或者向下或向上取整的方法来获得对应的原图坐标。正因为这个机制的引入,才导致最后的生成图效果不佳。

    2. 双线性插值法
    在这里插入图片描述
    双线性插值公式为:
       f(i+u,j+v) = (1-u)(1-v)f(i,j)+u(1-v)f(i+1,j)+(1-u)vf(i,j+1)+ uvf(i+1,j+1)
    原理同上,不过双线性插值算法是用四个点进行估计插值,图像较最邻近插值更显细腻,但计算量较大。

    python实现

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    def resize_nerghbor(src_data, dst_height, dst_width):
          ori_height, ori_width, channel = src_data.shape
          ratio_height = ori_height / dst_height
          ratio_width = ori_width / dst_width
          dst_data = np.zeros((dst_height, dst_width, channel), np.uint8)
          for i in range(channel):
              for y in range(dst_height):
                  for x in range(dst_width):
                      x_ori = int(x * ratio_width)
                      y_ori = int(y * ratio_height)          #取整
                      dst_data[y, x, i] = src_data[y_ori, x_ori, i]
          return dst_data
    
    
    def resize_bilinear(src_data, dst_height, dst_width):
        ori_height, ori_width, channel = src_data.shape
        ratio_height = ori_height / dst_height
        ratio_width = ori_width / dst_width
        dst_data = np.zeros((dst_height, dst_width, channel), np.uint8)
        for i in range(channel):
            for y in range(dst_height):
                for x in range(dst_width):
                    x_ori = x * ratio_width
                    y_ori = y * ratio_height
                    u = x_ori - math.floor(x_ori)
                    v = y_ori - math.floor(y_ori)    # 取小数部分
                    dst_data[y, x, i] = src_data[math.floor(y_ori), math.floor(x_ori),i]*(1 - u) * (1 - v) + \
                                        src_data[math.floor(y_ori), math.ceil(x_ori),i] * (1 - u) * v + \
                                        src_data[math.ceil(y_ori), math.floor(x_ori),i] * u * (1-v) + \
                                        src_data[math.ceil(y_ori), math.ceil(x_ori),i] * u * v         #取整、按公式进行运算
        return dst_data
    
    m = cv2.imread('xian.jpg')
    n = resize_bilinear(m,540,960)
    n = cv2.cvtColor(n, cv2.COLOR_BGR2RGB)
    plt.imshow(n)
    plt.show()
    # cv2.imshow('resize_image', n)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()
    

    在这里插入图片描述

    原图缩小后:
    在这里插给发发描述

    参考: 1.Matlab——图像缩放(插值法)
        2.使用双线性插值法放大图像(matlab实现)
        3.最临近插值和双线性插值

    展开全文
  • 最邻近插值和双线性插值源代码,对图像进行缩放
  • 对灰度图像采用最邻近插值法处理,使图像能够放大
  • 目前比较常用的插值算法有这么几种:最邻近插值,双线性二次插值,三次插值, Lanczos插值等等,今天我们来对比一下这几种插值效果的优劣。 1,最邻近插值  最邻近插值算法也叫做零阶插值算法,

    本文为转载,原博客地址:http://blog.csdn.net/trent1985/article/details/45150677

    [研究内容]

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

    [正文]

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

    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://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是对权重计算构建的映射表:

    [csharp]  view plain  copy
    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
    展开全文
  • 图像处理中最邻近插值和双线性插值 1、最邻近插值 一:数学原理 当一幅二维数字图像从源图像NM被放为(jN) * (k*M)目标图像是,参照数学斜率计算公式 必然有: (X1 – Xmin)/(Xmax - Xmin) = (Y1 - Ymin)/(Ymax-Ymin) ...

    图像处理中最邻近插值和双线性插值

    1、最邻近插值

    一:数学原理

    当一幅二维数字图像从源图像NM被放为(jN) * (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);
    

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

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

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

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

    2、双线性插值

    1,原理

    在图像的仿射变换中,很多地方需要用到插值运算,常见的插值运算包括最邻近插值,双线性插值,双三次插值,兰索思插值等方法,OpenCV提供了很多方法,其中,双线性插值由于折中的插值效果和运算速度,运用比较广泛。
      越是简单的模型越适合用来举例子,我们就举个简单的图像:33 的256级灰度图。假如图像的象素矩阵如下图所示(这个原始图把它叫做源图,Source):
    234 38 22
    67 44 12
    89 65 63
      这 个矩阵中,元素坐标(x,y)是这样确定的,x从左到右,从0开始,y从上到下,也是从零开始,这是图象处理中最常用的坐标系。
      如果想把这副图放大为 4
    4大小的图像,那么该怎么做呢?那么第一步肯定想到的是先把44的矩阵先画出来再说,好了矩阵画出来了,如下所示,当然,矩阵的每个像素都是未知数,等待着我们去填充(这个将要被填充的图的叫做目标图,Destination):
      ? ? ? ?
      ? ? ? ?
      ? ? ? ?
      ? ? ? ?
      然后要往这个空的矩阵里面填值了,要填的值从哪里来来呢?是从源图中来,好,先填写目标图最左上角的象素,坐标为(0,0),那么该坐标对应源图中的坐标可以由如下公式得出srcX=dstX
    (srcWidth/dstWidth) , srcY = dstY * (srcHeight/dstHeight)
      好了,套用公式,就可以找到对应的原图的坐标了(0*(3/4),0*(3/4))=>(00.75,00.75)=>(0,0),找到了源图的对应坐标,就可以把源图中坐标为(0,0)处的234象素值填进去目标图的(0,0)这个位置了。
      接下来,如法炮制,寻找目标图中坐标为(1,0)的象素对应源图中的坐标,套用公式:
    (10.75,00.75)=>(0.75,0) 结果发现,得到的坐标里面竟然有小数,这可怎么办?计算机里的图像可是数字图像,象素就是最小单位了,象素的坐标都是整数,从来没有小数坐标。这时候采用的一种策略就是采用四舍五入的方法(也可以采用直接舍掉小数位的方法),把非整数坐标转换成整数,好,那么按照四舍五入的方法就得到坐标(1,0),完整的运算过程就是这样的:(10.75,00.75)=>(0.75,0)=>(1,0) 那么就可以再填一个象素到目标矩阵中了,同样是把源图中坐标为(1,0)处的像素值38填入目标图中的坐标。
      依次填完每个象素,一幅放大后的图像就诞生了,像素矩阵如下所示:
      234 38 22 22
      67 44 12 12
      89 65 63 63
      89 65 63 63
      这种放大图像的方法叫做最临近插值算法,这是一种最基本、最简单的图像缩放算法,效果也是最不好的,放大后的图像有很严重的马赛克,缩小后的图像有很严重的失真;效果不好的根源就是其简单的最临近插值方法引入了严重的图像失真,比如,当由目标图的坐标反推得到的源图的的坐标是一个浮点数的时候,采用了四舍五入的方法,直接采用了和这个浮点数最接近的象素的值,这种方法是很不科学的,当推得坐标值为 0.75的时候,不应该就简单的取为1,既然是0.75,比1要小0.25 ,比0要大0.75 ,那么目标象素值其实应该根据这个源图中虚拟的点四周的四个真实的点来按照一定的规律计算出来的,这样才能达到更好的缩放效果。
      双线型内插值算法就是一种比较好的图像缩放算法,它充分的利用了源图中虚拟点四周的四个真实存在的像素值来共同决定目标图中的一个像素值,因此缩放效果比简单的最邻近插值要好很多。
    双线性内插值算法描述如下:
      对于一个目的像素,设置坐标通过反向变换得到的浮点坐标为(i+u,j+v) (其中i、j均为浮点坐标的整数部分,u、v为浮点坐标的小数部分,是取值[0,1)区间的浮点数),则这个像素得值 f(i+u,j+v) 可由原图像中坐标为 (i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所对应的周围四个像素的值决定,即:f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)
    其中f(i,j)表示源图像(i,j)处的的像素值,以此类推。
      比如,象刚才的例子,现在假如目标图的象素坐标为(1,1),那么反推得到的对应于源图的坐标是(0.75 , 0.75), 这其实只是一个概念上的虚拟象素,实际在源图中并不存在这样一个象素,那么目标图的象素(1,1)的取值不能够由这个虚拟象素来决定,而只能由源图的这四个象素共同决定:(0,0)(0,1)(1,0)(1,1),而由于(0.75,0.75)离(1,1)要更近一些,那么(1,1)所起的决定作用更大一些,这从公式1中的系数uv=0.75×0.75就可以体现出来,而(0.75,0.75)离(0,0)最远,所以(0,0)所起的决定作用就要小一些,公式中系数为(1-u)(1-v)=0.25×0.25也体现出了这一特点。

    2、计算方法

    在图像处理的时候,我们先根据
      srcX=dstX* (srcWidth/dstWidth),
      srcY = dstY * (srcHeight/dstHeight)
    来计算目标像素在源图像中的位置,这里计算的srcX和srcY一般都是浮点数,比如f(1.2, 3.4)这个像素点是虚拟存在的,先找到与它临近的四个实际存在的像素点
      (1,3) (2,3)
      (1,4) (2,4)
    写成f(i+u,j+v)的形式,则u=0.2,v=0.4, i=1, j=3
    在沿着X方向差插值时,f(R1)=u(f(Q21)-f(Q11))+f(Q11)
    沿着Y方向同理计算。
    或者,直接整理一步计算,
    f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)

    3、简单的手工计算

    dst:目标图像
    src: 源图像

    思想:确定目标图像坐标点D(x,y),根据公式:
    srcX=dstX* (srcWidth/dstWidth),
      srcY = dstY * (srcHeight/dstHeight)
      计算源图像对应的位置,确认原图像这个位置的像素,把这个像素填充到目标图像的这个坐标d(x,y)里.,但是反推原图像的坐标是往往是小数,就需要双线性插值法。
      比如计算出的原图像的位置是S(1.2,3.4),因为原图像中找不到这个点,所以要用双线性插值法来计算这个点的像素。(四个邻近点计算这个像素)
      f(1+0.2,3+0.4)= (1-0.2)(1-0.4)f(1,3)+(1-0.2)0.4f(1,4)+0.2(1-0.4)f(2,3)+0.20.4*f(2,4)
     在原图中找到f(1,3)、f(1,4)、f(2,3)、f(2,4)这四个点的像素即可知道f(1+0.2,3+0.4)这个虚拟点的像素,从而知道目标图像D(x,y)的像素。

    展开全文
  • 最邻近插值 双线性插值 双立方(三次卷积)插值 本文介绍其中的最邻近插值 如果想先看效果和源码,可以拉到底部 何时进行最邻近插值 这个算法的特点是 速度非常快速 误差很大 如果缩放系数较大,肯定会有马赛克...

    前言

    图像处理中有三种常用的插值算法:

    • 最邻近插值
    • 双线性插值
    • 双立方(三次卷积)插值

    本文介绍其中的最邻近插值

    如果想先看效果和源码,可以拉到最底部

    何时进行最邻近插值

    这个算法的特点是

    • 速度非常快速
    • 误差很大
    • 如果缩放系数较大,肯定会有马赛克效果

    适合在一些需要实时预览缩放后效果,但是精度要求又不是很高的场景

    数学理论

    最简单的理论-1对1映射,如图

    image

    简单分析如下:

    • 目标插值图中的某像素点(distI, distJ)在原图中的映射为(i + v, j + u)
    • 最终这个点的取值就是(i, j)处的值
    • v,u都小于1(就是进行一次取整)

    插值公式

    F(i + v, j + u) = f(i, j)

    直接映射+取整即可完成取值

    代码实现

    过于简单,不再赘述,核心就是

    运行效果

    可参考同系列中的双立方插值中的效果图

    三种插值算法的简单比较

    纬度最邻近双线性双立方
    速度较慢
    质量
    质量相比于canvas 远低于低于高于
    代码实现难度极易偏难
    适用场景实时计算作为默认实现效果高质量的效果

    开源项目

    这个项目里用JS实现了几种插值算法,包括(最邻近值,双线性,三次卷积-包括两种不同实现等)

    https://github.com/dailc/image-process

    附录

    博客

    初次发布2016.11.02于我个人博客上面

    http://www.dailichun.com/2017/11/01/imageprocess_nearestinterpolation.html

    展开全文
  • 里面包含邻近插值和双线性插值的文档说明以及程序比较,很适合初学者的学习使用,可以很好的理解其中的原理!
  • 最邻近插值法原理分析及c++实现 最邻近插值法 : 其核心思想是选取离目标点最近的点作为待插入的新值点 公式推导过程 上述图片中像素点的说明: Q11,Q21,Q12,Q22 分别为四个真实存在的像素点 P 为最邻近插值法...
  • opencv 图像截取 图像显示 图像变换 双线性 最邻近插值 图像缩放 opencv 图像截取 图像显示 图像变换 双线性 最邻近插值 图像缩放 opencv 图像截取 图像显示 图像变换 双线性 最邻近插值 图像缩放
  • 最邻近插值、双线性插值、三线性插值 零、图像的放大和缩小的基本原理–映射 图像的放大和缩小的基本原理就是一种映射,即缩小后或者放大后的图像像素位置向原图的一个映射。简单理解就是,将放大或者缩小后的图像...
  • 最邻近插值 双线性插值 双立方(三次卷积)插值 其中效果最好的是双立方(三次卷积)插值,本文介绍它的原理以及使用 如果想先看效果和源码,可以拉到底部 本文的契机是某次基于canvas做图像处理时...
  • 最邻近插值法(图像缩放算法) 例如:图像src为3*3的256级灰度图像(源图像) 234 38 22 67 44 12 89 65 63
  • python实现图像的最邻近插值,双线性内插和双三次卷积插值代码演示 from PIL import Image import matplotlib.pyplot as plt import numpy as np import math def NN_interpolation(img, dstH, dstW): #定义最邻近...
  • 1.最邻近插值算法 首先假设原图是一个像素大小为W*H的图片,缩放后的图片是一个像素大小为w*h的图片,这时候我们是已知原图中每个像素点上的像素值(即灰度值等)的(⚠️像素点对应像素值的坐标都是整数)。这个...
  • [MATLAB]最邻近插值法进行图像放大

    千次阅读 2020-11-24 20:12:29
    [MATLAB代码]关于运用最邻近插值法进行图像放大 %导入图片并显示原图 img=imread('pepper.bmp'); figure; imshow(img); title('原图'); %计算原图长、宽、通道数 [row col ch]=size(img); %画布放大两倍 rr=ceil...
  • ##[MATLAB代码]关于运用最邻近插值法进行图像旋转 %导入图片并显示原图 img=imread('pepper.bmp'); figure; imshow(img); title('原图'); %计算原图长、宽、通道数 [row col ch]=size(img); d=[row col]/2; %求出...
  • 最邻近插值&&双线性内插值! 普通科学 发布时间:18-12-1723:37 写在前:用简单的方式,讲述深刻的知识。 %%%%%%% %%%%%%% %%%%%%% %%%%%%% %%%%%%% %%%%%%% 图像的缩放,对于大家来说一定是个...
  • 最邻近插值(Nearest neighbor interpolation) 这里只用基本的灰度图来介绍。 DDD是目标图像的灰度,S是原本图像的灰度 D(x,y)=S([x+0.5],[y+0.5])D(x,y) = S([x + 0.5],[y + 0.5])D(x,y)=S([x+0.5],[y+0.5]) [×][\...
  • 1、最邻近插值法(Nearest Interpolation) 这是简单的一种插值方法,不需要计算。在待求像素的四邻像素中,将距离待求像素最近的邻接像素灰度值赋予待求像素。设i+u, j+v(i, j为正整数, u, v为大于零

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,637
精华内容 2,254
关键字:

最邻近插值