生活随笔
收集整理的這篇文章主要介紹了
插值 估算近似值
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
插值 估算近似值 1. 插值法 2. 最近鄰插值 3. 雙線性插值 4. 雙三次插值 5. 效果對比
1. 插值法
引用百度的百科對插值的定義:
在離散數據的基礎上補插連續函數,使得這條連續曲線通過全部 給定的離散數據點。 插值是離散函數逼近的重要方法,利用它可通過函數在有限個點處的取值狀況,估算出函數在其他點處的近似值。 插值:用來填充圖像變換時像素之間的空隙。
插值法的第一步都是相同的 計算目標圖(dstImage)的坐標點對應原圖(srcImage)中哪個坐標點來填充,計算公式為: srcsrc s r c X = dstdst d s t X * (srcsrc s r c Width /dstdst d s t Width ) srcsrc s r c Y = dstdst d s t Y * (srcsrc s r c Height /dstdst d s t Height )
對應原圖像的坐標點 等于 目標圖像的某個坐標點 分別乘于 寬和高的放縮比
通過這個公式算出來的 對應原圖像的坐標點srcsrc s r c X , srcsrc s r c Y 有可能是小數 但是原圖像坐標點是不存在小數的,都是整數,得想辦法把它轉換成整數才行
不同插值法的區別就體現在對應原圖像的坐標點是小數時,怎么將其變成整數去取原圖像中的像素值
2. 最近鄰插值
看名字就很簡單,直接四舍五入選取最接近的整數 這樣的做法會導致像素變化不連續,在目標圖像中產生鋸齒邊緣
import cv2
import numpy
as np
def NN_interpolation ( img
, dstH
, dstW
) : scrH
, scrW
, channels
= img
. shaperetimg
= np
. zeros
( ( dstH
, dstW
, channels
) , dtype
= np
. uint8
) for i
in range ( dstH
) : for j
in range ( dstW
) : scrx
= round ( j
* ( scrW
/ dstW
) ) scry
= round ( i
* ( scrH
/ dstH
) ) if scrx
>= scrW
: scrx
= scrW
- 1 if scry
>= scrH
: scry
= scrH
- 1 retimg
[ i
, j
] = img
[ scry
, scrx
] return retimg
3. 雙線性插值
根據于待求點P最近4個點的像素值,計算出P點的像素值 各點的權重看距離 假如想得到未知函數 ff f 在點 P = (x, y) 的值 假設已知函數 ff f 在 Q11 = (x1 , y1 )、Q12 = (x1 , y2 ), Q21 = (x2 , y1 ) 以及 Q22 = (x2 , y2 ) 四個點的值
最常見的情況,ff f 就是一個像素點的像素值 首先在 x 方向進行線性插值,然后再在 y 方向上進行線性插值,最終得到雙線性插值的結果
def BL_interpolation ( img
, dstH
, dstW
) : scrH
, scrW
, channels
= img
. shaperetimg
= np
. zeros
( ( dstH
, dstW
, channels
) , dtype
= np
. uint8
) R1
= np
. zeros
( ( 1 , 1 , channels
) , dtype
= np
. uint8
) R2
= np
. zeros
( ( 1 , 1 , channels
) , dtype
= np
. uint8
) for i
in range ( dstH
) : for j
in range ( dstW
) : x
= j
* ( scrW
/ dstW
) y
= i
* ( scrH
/ dstH
) x1
= int ( x
) y1
= int ( y
) x2
= x1
+ 1 y2
= y1
+ 1 if x2
>= scrW
: x2
= x1x1
-= 1 if y2
>= scrH
: y2
= y1y1
-= 1 R1
= ( x2
- x
) / ( x2
- x1
) * img
[ y1
, x1
] + ( x
- x1
) / ( x2
- x1
) * img
[ y1
, x2
] R2
= ( x2
- x
) / ( x2
- x1
) * img
[ y2
, x1
] + ( x
- x1
) / ( x2
- x1
) * img
[ y2
, x2
] retimg
[ i
, j
] = ( y2
- y
) / ( y2
- y1
) * R1
+ ( y
- y1
) / ( y2
- y1
) * R2
return retimg
4. 雙三次插值
先找出像素(X,Y)在源圖像中對應的像素(x,y) 再根據源圖像距離像素(x,y)最近的16個像素點作為計算目標圖像(X,Y)處像素值的參數
利用BiCubic 基函數求出16個像素點的權重 目標圖像像素(x,y)的值就等于16個像素點的加權疊加
def BiBubic ( x
) : x
= abs ( x
) if x
<= 1 : return 1 - 2 * ( x
** 2 ) + ( x
** 3 ) elif x
< 2 : return 4 - 8 * x
+ 5 * ( x
** 2 ) - ( x
** 3 ) else : return 0 def BC_interpolation ( img
, dstH
, dstW
) : scrH
, scrW
, channels
= img
. shaperetimg
= np
. zeros
( ( dstH
, dstW
, channels
) , dtype
= np
. uint8
) for i
in range ( dstH
) : for j
in range ( dstW
) : x
= j
* ( scrW
/ dstW
) y
= i
* ( scrH
/ dstH
) x_int
= int ( x
) y_int
= int ( y
) u
= x
- x_intv
= y
- y_inttmp
= 0 for ai
in range ( - 1 , 3 ) : for aj
in range ( - 1 , 3 ) : if x
+ ai
< 0 or y
+ aj
< 0 or x
+ ai
>= scrH
or y
+ aj
>= scrW
: tmp
+= img
[ y_int
, x_int
] * BiBubic
( ai
- u
) * BiBubic
( aj
- v
) else : tmp
+= img
[ y_int
+ aj
, x_int
+ ai
] * BiBubic
( ai
- u
) * BiBubic
( aj
- v
) retimg
[ i
, j
] = np
. clip
( tmp
, 0 , 255 ) return retimg
5. 效果對比
img
= cv2
. imread ( "HH.jpg" ) new_img
= NN_interpolation ( img
, 512 , 512 )
cv2
. imshow ( "Nearest Neighbor Interpolation" , new_img
) new_img
= BL_interpolation ( img
, 512 , 512 )
cv2
. imshow ( "Bilinear Interpolation" , new_img
) new_img
= BC_interpolation ( img
, 512 , 512 )
cv2
. imshow ( "BiCubic Interpolation" , new_img
) cv2
. imshow ( "image" , img
)
cv2
. waitKey ( 0 )
可以看到效果依次的好,不過運算耗時也依次增加
謝謝!
總結
以上是生活随笔 為你收集整理的插值 估算近似值 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。