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

    圖像縮放

    概要

    本節介紹了使用resize 函數與wrapAffine 兩種方式實現圖像縮放.

    keywords 圖像縮放 resize wrapAffine

    利用resize函數實現縮放

    opencv其實有專門進行圖像縮放的函數resize。

    resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) -> dst
    

    參數解析

    • src 輸入圖片

    • dsize 輸出圖片的尺寸

    • dst 輸出圖片

    • fx x軸的縮放因子

    • fy y軸的縮放因子

    • interpolation 插值方式

    • INTER_NEAREST - 最近鄰插值

    • INTER_LINEAR - 線性插值(默認

    • INTER_AREA - 區域插值

    • INTER_CUBIC - 三次樣條插值

    • INTER_LANCZOS4 - Lanczos插值

    在使用的時候, 我們可以傳入指定的圖片的尺寸dsize

    src/resize_cat.py

    '''
    使用resize函數對圖像進行縮放
    '''
    import cv2
    import numpy as np
    
    img = cv2.imread('cat.jpg')
    height,width,channel = img.shape
    
    # 聲明新的維度
    new_dimension = (400, 400)
    # 指定新圖片的維度與插值算法(interpolation)
    resized = cv2.resize(img, new_dimension)
    
    cv2.imwrite('cat_resize_400_400.png', resized)
    

    cat_resize_400_400

    或者指定縮放因子

    f_x, f_y

    dsize 設置為 None 然后指定fx fy

    import cv2
    import numpy as np
    
    img = cv2.imread('cat.png')
    height,width,channel = img.shape
    
    # 指定新圖片的維度與插值算法(interpolation)
    resized = cv2.resize(img, None, fx=1.5, fy=2)
    
    cv2.imwrite('cat_resize_fx_fy.png', resized)
    

    cat_resize_fx_fy

    或者指定輸出圖片,并傳入輸出圖片的size。

    src/resize_cat_v2.py

    '''
    根據fx跟fy進行圖像縮放
    '''
    import cv2
    import numpy as np
    
    img = cv2.imread('cat.jpg')
    height,width,channel = img.shape
    
    # 指定輸出圖片
    dst = np.zeros((100, 100, 3), dtype='uint8')
    
    # 指定新圖片的維度與插值算法(interpolation)
    cv2.resize(img, dst=dst, dsize=(dst.shape[1], dst.shape[0]), fx=1.5, fy=2)
    
    cv2.imwrite('cat_resize_from_dst.png', dst)
    

    cat_resize_from_dst

    更詳細的使用說明見opencv-resize 文檔

    為了方便使用, 我們也可以將其封裝成函數

    def resize(image, width = None, height = None, inter = cv2.INTER_AREA):
        dim = None
        (h, w) = image.shape[:2]
    
        if width is None and height is None:
            return image
    
        if width is None:
            r = height / float(h)
            dim = (int(w * r), height)
    
        if height is None:
            r = width / float(w)
            dim = (width, int(h * r))
    
        if width and height:
            dim = (width, height)
    
        resized = cv2.resize(image, dim, interpolation = inter)
        return resized
    

    分辨率 從5*5 放大到1000*1000, 選擇不同的插值算法,對應的演示效果。

    Screenshot_20180218_214012.png

    Screenshot_20180218_214406.png

    src/resize_interpolation.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()
    


    !!學霸分割線!!
    如果你對圖像縮放的數學原理不感興趣的話,就不需要往下看了.


    利用wrapAffine實現縮放

    對圖像的伸縮變換的變換矩陣M為

    \begin{equation} { \left[ \begin{array}{c} x'\\ y'\\ \end{array} \right ]}= { \left[ \begin{array}{cc} f_x & 0\\ 0 & f_y\\ \end{array} \right ]}\times { \left[\begin{array}{c} x\\ y\\ \end{array} \right] }+ { \left[\begin{array}{c} 0\\ 0\\ \end{array} \right] } \end{equation}

    其中,

    f_x

    代表x軸的焦距(縮放因子),

    f_y

    代表y軸的焦距(縮放因子)。

    x' = f_x * x
    y' = f_y*y
    '''
    使用仿射矩陣實現
    '''
    import numpy as np
    import cv2
    
    img = cv2.imread('cat.jpg')
    
    height,width,channel = img.shape
    
    # x軸焦距 1.5倍
    fx = 1.5
    # y軸焦距 2倍
    fy = 2
    
    # 聲明變換矩陣 向右平移10個像素, 向下平移30個像素
    M = np.float32([[fx, 0, 0], [0, fy, 0]])
    
    # 進行2D 仿射變換
    resized = cv2.warpAffine(img, M, (int(width*fx), int(height*fy)))
    cv2.imwrite('resize_raw.png', resized)
    

    演示效果

    Screenshot_20180218_180904

    我們利用random 模塊生成一個5×5的隨機矩陣。

    # 生成一個隨機噪點
    img = np.uint8(np.random.randint(0,255,size=(5,5)))
    

    原圖

    [[227  66   2 153  30]                                                            
     [  8  23  68  45  91]                                                            
     [194 216 229 128 109]                                                            
     [ 73 111 189 200 111]                                                            
     [ 99  82 217  80  52]] 
    

    縮放后

    [[227 121  44   2 101 111  30]                                                    
     [118  70  41  35  77  86  61]                                                    
     [  8  18  38  68  53  61  91]                                                    
     [101 113 129 149 108  91 100]                                                    
     [194 208 220 229 163 121 109]                                                    
     [134 153 179 209 179 145 110]                                                    
     [ 73  98 138 189 196 169 111]                                                    
     [ 86  93 133 203 162 120  82]                                                    
     [ 99  88 128 217 127  70  52]
     [ 50  44  64 109  64  35  26]]
    

    為了更加直觀的感受, 我們可以進行數據可視化。

    我們使用matplotlib進行繪制 resize前與resize之后的圖片。

    2018021812312

    源代碼

    src/resize_cat_v4.py

    '''
    仿射矩陣實現縮放 fx,fy
    '''
    import numpy as np
    import cv2
    from matplotlib import pyplot as plt
    # 生成一個隨機噪點
    img = np.uint8(np.random.randint(0,255,size=(5,5)))
    
    height,width = img.shape
    
    # x軸焦距 1.5倍
    fx = 1.5
    # y軸焦距 2倍
    fy = 2
    
    # 聲明變換矩陣 向右平移10個像素, 向下平移30個像素
    M = np.float32([[fx, 0, 0], [0, fy, 0]])
    
    # 進行2D 仿射變換
    resized = cv2.warpAffine(img, M, (int(width*fx), int(height*fy)))
    
    print(img)
    print(resized)
    
    # 數據可視化
    plt.subplot(121)
    plt.imshow(img, cmap="gray")
    plt.subplot(122)
    plt.imshow(resized,cmap="gray")
    plt.show()
    


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