<button id="ssm6u"><optgroup id="ssm6u"></optgroup></button>
  • 跳轉至

    圖像插值算法

    概述

    圖像2D仿射變換一章里, 我們介紹了resize中有若干個插值算法,本節, 阿凱將講解各種插值算法的實現過程。

    keywords 2D仿射變換 插值算法

    何為插值?

    一個圖片從4×4 放大到8*8的時候, 就會產生一些新的像素點( 如下圖紅點所示),

    如何給這些值賦值, 就是interpolation 插值所要解決的問題。

    Screenshot_20180218_221953.png

    插值方法一覽

    全部的插值方式 請見文檔 InterpolationFlags

    這里我們只講解五個插值方式。 我們隨機生成一個5×5的矩陣, 然后用下面五種方式進行插值, 效果如圖所示:

    201802182105

    interpolation_algorithm_v1.py

    import cv2
    import numpy as np
    from matplotlib import pyplot as plt
    
    
    img = np.uint8(np.random.randint(0,255,size=(5,5)))
    height,width= img.shape
    
    
    # 聲明新的維度
    new_dimension = (25, 25)
    
    plt.subplot(231)
    plt.title("SRC Image")
    plt.imshow(img,cmap='gray')
    
    plt.subplot(232)
    resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_NEAREST)
    plt.title("INTER_NEAREST")
    plt.imshow(resized,cmap='gray')
    
    
    plt.subplot(233)
    resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_LINEAR)
    plt.title("INTER_LINEAR")
    plt.imshow(resized,cmap='gray')
    
    
    plt.subplot(234)
    resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_AREA)
    plt.title("INTER_AREA")
    plt.imshow(resized,cmap='gray')
    
    
    plt.subplot(235)
    resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_CUBIC)
    plt.title("INTER_CUBIC")
    plt.imshow(resized,cmap='gray')
    
    
    plt.subplot(236)
    resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_LANCZOS4)
    plt.title("INTER_LANCZOS4")
    plt.imshow(resized,cmap='gray')
    
    plt.show()
    

    為了更加直觀的觀察,我們將cmap 換為seismic 分辨率 從5*5 放大到1000*1000

    Screenshot_20180218_214012.png

    Screenshot_20180218_214406.png

    interpolation_algorithm_v2.py

    import cv2
    import numpy as np
    from matplotlib import pyplot as plt
    
    
    img = np.uint8(np.random.randint(0,255,size=(5,5)))
    height,width= img.shape
    
    
    # 聲明新的維度
    new_dimension = (1000, 1000)
    
    plt.subplot(231)
    plt.title("SRC Image")
    plt.imshow(img,cmap='seismic')
    
    plt.subplot(232)
    resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_NEAREST)
    plt.title("INTER_NEAREST")
    plt.imshow(resized,cmap='seismic')
    
    
    plt.subplot(233)
    resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_LINEAR)
    plt.title("INTER_LINEAR")
    plt.imshow(resized,cmap='seismic')
    
    
    plt.subplot(234)
    resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_AREA)
    plt.title("INTER_AREA")
    plt.imshow(resized,cmap='seismic')
    
    
    plt.subplot(235)
    resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_CUBIC)
    plt.title("INTER_CUBIC")
    plt.imshow(resized,cmap='seismic')
    
    
    plt.subplot(236)
    resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_LANCZOS4)
    plt.title("INTER_LANCZOS4")
    plt.imshow(resized,cmap='seismic')
    
    plt.show()
    

    關于插值方式的不同與縮放因子的不同對應的時間消耗, 可以查閱下表:

    interpolation_speed_test.png

    最近鄰插值 INTER_NEAREST

    最近鄰插值法, 找到與之距離最相近的鄰居(原來就存在的像素點, 黑點), 賦值與其相同。

    fig5_23.gif

    問題 如果距離四個點都相等(中心處)要如何處理?

    Screenshot_20180218_222515.png

    效果展示

    interpolation_INTER_NEAREST

    線性插值(默認)INTER_LINEAR

    這里的線形插值INTER_LINEAR 其實是Bi-Linear Interpolation

    我們先來看一個簡單的一維線形插值的例子。

    已知兩點(紅色) ,在給出一個藍點的x坐標, 求y。

    所以需要根據兩個紅點確定一條直線,求出直線的表達式, 然后再將x坐標帶進去。

    Screenshot_20180218_225345.png

    接下來我們來看Bi-Linear Interpolation 的例子。

    Screenshot_20180218_225832.png

    下圖中 P(x,y)周圍有

    Q{11} = (x_1, y_1), Q{12} = (x_1, y_2), Q{21} = (x_2,y_1), Q{22} = (x_2, y_2)

    四個點.

    又假定我們已知函數

    f(x_n, y_n)

    在四個點的取值, 現在需要我們求

    f(P) = f(x,y)

    思路是我們可以將求解過程分解為兩次插值過程。

    首先在x軸方向上進行插值,根據點

    Q_{11},1 Q_{21}

    的取值求得

    f(R_1)

    , 根據點

    Q_{12}, Q_{22}

    的取值求得

    f(R_2)

    .

    然后在y軸方向上進行插值, 根據點

    R_1, R_2

    的取值求得f(P).

    R_1 = (x, y_1)
    f(R1) = (x-x_1)/ (x_2-x_1)* f(Q{11}) + (x_2-x)/(x_2-x_1)*f(Q{21})
    R_2 = (x, y_2)
    f(R2) = (x-x_1)/ (x_2-x_1)* f(Q{12}) + (x_2-x)/(x_2-x_1)*f(Q{22})

    **這本質上就是加權平均。以x點到

    x_1, x_2

    的距離作為權值,來表示該點受周邊兩點的影響。**

    P = (x, y)
    f(P) = (y - y1)/(y2 - y1) * f(R_1) + (y2- y)/(y2-y1) *f(R_2)

    展開后得到

    15150029-ef41a1ca5a354f2baeb84b75d28d8414.png

    15150155-b11a2b3839334f1aa565cdbf9a6b8526.png

    不知道你有沒有發現, 實際上P點的值, 等于周邊四點值根據與P點形成的對角矩形面積的加權平均。

    Screenshot_20180218_230434.png

    Screenshot_20180218_230602.png

    效果展示

    interpolation_INTER_LINEAR

    區域插值 INTER_AREA

    interpolation_INTER_AREA

    三次樣條插值 INTER_CUBIC

    interpolation_INTER_CUBIC

    由相鄰的4*4像素計算得出,公式類似于雙線性.

    Lanczos插值 INTER_LANCZOS4

    interpolation_INTER_LANCZOS4

    蘭索斯插值:由相鄰的8*8像素計算得出,公式類似于雙線性

    Reference

    02 sampling quantization interpolation

    插值部分講解的原理圖片,主要來自與此課件

    Neighborhood Operations - ENDS489 Course Notes - Fall 2000 Section 1-8

    雙線性插值(Bilinear Interpolation)

    三次樣條插值(Cubic Spline Interpolation)及代碼實現(C語言)

    Comparison of OpenCV Interpolation Algorithms

    插值算法性能對比來自于此文章

    小強學Python+OpenCV之-1.4.1平移、旋轉、縮放、翻轉-之實踐

    博客里提到了各種插值算法的運算速度與選擇。

    ?


    韩国精品无码一区二区三区,精品无码一区二区三区AV,欧洲丰满美熟女乱又伦AV,亚洲午夜久久久影院伊人