官术网_书友最值得收藏!

2.1 縮放

縮放是最簡單的仿射變換,顧名思義,應用它可將圖像放大或縮小。圖2-2所示是一幅原始圖像,圖2-3(a)所示是縮小后的圖像,圖2-3(b)所示是放大后的圖像。

圖2-2 原始圖像

(a)

(b)

圖2-3 圖2-2縮放后的圖像

將圖像放大或縮小后會得到新圖像,比如將100×100的圖像放大為200×200,如果原始圖像有1萬個像素點,那么新圖像中有4萬個像素點,這4萬個像素點的值應該怎么根據原始圖像的像素值來計算呢?這就需要用到一個重要的技術——插值。

我們先來看一個例子。如圖2-4所示,有一幅大小為3×3的圖像,將其按長寬等比例放大4/3倍后得到一幅4×4的新圖像,新圖像中(2, 1)位置的像素對應于原始圖像(1.5, 0.75)位置。但是原始圖像的像素都位于整數坐標位置,于是新圖像在原始圖像中的對應點(1.5, 0.75)位置的像素值就需要根據其周圍在整數位置的像素值來計算得出,比如可以用圖2-4(a)中深色區域的4個像素來計算,這就是插值。

最簡單的插值方法就是直接取距離(1.5, 0.75)最近的整數位置像素的值,這種方法叫作最近鄰插值。

雙線性插值是一種常用的插值方法,它是線性插值的擴展。在數學上,線性插值是一種曲線擬合的方法,它通過線性多項式來計算已知相鄰數據點之間的點。如圖2-5所示,假設已知兩點,用線性插值可以計算出這兩點間連線上的點,也就是說給出x0x1間的一個值x,對應的y值可用下面的式(2-1)計算得出:

式(2-1)

(a)                                    ?。╞)  

圖2-4 插值

圖2-5 線性插值

對線性插值進行擴展,在兩個方向上分別進行一次線性插值,即對xy都進行插值,這樣的方法就稱為雙線性插值。如圖2-6所示,我們需要得到點的值,假設已知、這4個點的值。

圖2-6 雙線性插值

先在x軸方向進行線性插值,得到點的值:

式(2-2)

然后在y軸方向根據點進行線性插值,便得到點P的值:

式(2-3)

雙線性插值的結果與插值順序無關,先進行x軸方向插值和先進行y軸方向插值的最終結果是一樣的。需要注意的是,雙線性插值并不是線性的,而是非線性的。對于其他的插值方法,感興趣的讀者可以查閱相關資料進行了解。

OpenCV提供了對圖像進行縮放的函數cv.resize(),該函數支持多種插值方法。

dst = cv.resize(src, dsize[, fx[, fy[, interpolation]]])

其中的主要參數介紹如下。

dst:輸出圖像,大小為dsize,或由src的大小、fx和fy計算得到。

src:輸入圖像。

dsize:輸出圖像的大小。如果其為None,則

fx:圖像寬的縮放比例。如果該值為0,則按計算得出。

fy:圖像高的縮放比例。如果該值為0,則按計算得出。

interpolation:插值方法。插值方法和說明如表2-1所示。默認的插值方法是雙線性插值INTER_LINEAR。

表2-1 插值方法和說明

不同的插值方法會產生不同質量的圖像,同時它們的計算速度也不一樣。圖2-7中的4幅圖為采用不同的插值方法將圖2-2放大2倍后的圖像,圖2-7(a)~圖2-7(d)依次為使用最近鄰插值、雙線性插值、雙三次插值和LANCZOS插值得到的新圖像。對比結果可以看出,最近鄰插值會讓圖像產生鋸齒效果,雙線性插值會讓圖像邊緣變模糊,而雙三次插值和LANCZOS插值的效果均較好。從速度上看,這4種插值方法中,最近鄰插值速度最快,雙線性插值的速度較快,雙三次插值的速度一般,而LANCZOS插值的速度最慢。

(a)

(b)

(c)

(d)

圖2-7 使用不同的插值方法將圖2-2放大2倍后的圖像

實現代碼如下:

import cv2 as cv
import numpy as np
 
 
def main():
 
    # 讀入圖像
    im = cv.imread('lena.jpg')
    cv.imshow('lena.jpg', im)
 
    # 縮放圖像
    dim = (int(im.shape[1]*2), int(im.shape[0]*2))
    im_rs_nr = cv.resize(im, dim, interpolation=cv.INTER_NEAREST)
    im_rs_ln = cv.resize(im, dim, interpolation=cv.INTER_LINEAR)
    im_rs_cb = cv.resize(im, dim, interpolation=cv.INTER_CUBIC)
    im_rs_lz = cv.resize(im, dim, interpolation=cv.INTER_LANCZOS4)
    cv.imshow('lena_rs_nr.jpg', im_rs_nr)
    cv.imshow('lena_rs_ln.jpg', im_rs_ln)
    cv.imshow('lena_rs_cb.jpg', im_rs_cb)
    cv.imshow('lena_rs_lz.jpg', im_rs_lz)
 
    cv.waitKey()
    cv.destroyAllWindows()
 
 
if __name__ == '__main__':
main()
主站蜘蛛池模板: 泊头市| 柳州市| 肥乡县| 延长县| 西峡县| 汝州市| 万盛区| 桐梓县| 玛纳斯县| 桐乡市| 佛山市| 雅安市| 淮南市| 民县| 绍兴市| 民勤县| 和田县| 都兰县| 田东县| 姜堰市| 无为县| 绵阳市| 方正县| 阿鲁科尔沁旗| 丰原市| 临沭县| 腾冲县| 栾川县| 江永县| 张家港市| 南江县| 中卫市| 屯留县| 普宁市| 晋州市| 永安市| 方城县| 都安| 赣州市| 和田市| 伊金霍洛旗|