記事ディレクトリ
理論的根拠
線形補間: 2 つの点によって直線が決定され、直線上の未知の点の値は直線の方程式によって決定できます。
2 次元空間では、線形差分を双線形補間に拡張する必要があります。
A、B、C、Dの画素値をそれぞれA、B、C、Dとする。
P1 のピクセル値はP1 = 1 / 行 × ( ( row − a ) A + a B ) P1 = 1/row \times ((row-a)A + aB)P1_ _=1 /行×( (行−a ) A+a B )
P2 のピクセル値はP 2 = 1 / 行 × ( ( row − a ) C + a D ) P2 = 1/row \times ((row-a)C + aD)P2_ _=1 /行×( (行−ア)C+a D )
P のピクセル値はP = 1 /col × ( (col − b ) P 1 + b P 2 ) P = 1/col \times ((col-b)P1 + bP2)P=1 /コル×( ( _−b ) P1 _+b P 2 )
して P1、P2 を代入して
P = 1col × row × [ ( row − a ) ( clo − b ) A + a (col − b ) B ) + a ( row − a ) C + ab D ] P = \frac{1}{col \times row} \times \left[ (row-a)(clo-b)A + a(col-b)B) + a(row-a)C + abD\right 】P=コル_×ロウ_1×[ (行_−a ) ( c l o−b ) A+a (コル_−b ) B )+あ(行_−ア)C+ab D ]
注: 点 P が補間のために元の画像に投影される場合、行と列の値は 1 と 1 になります。
コーディング実装(Python)
# coding=utf-8
import cv2
import numpy as np
def Bilinear(img, up_height, up_width, channels):
bilinear_img = np.zeros(shape=(up_height, up_width, channels), dtype=np.uint8)
img_height, img_width, img_channels = img.shape
for i in range(up_height):
for j in range(up_width):
row_up = int(i * img_height/up_height) # 原图像左像素点
col_left = int(j * img_width/up_width) # 原图像上像素点
row_bottom = row_up + 1
col_right = col_left + 1
if row_bottom == img_height:
row_bottom -= 1
if col_right == img_width:
col_right -= 1
a = j * img_width / up_width - col_left
b = i * img_height / up_height - row_up
# 这里定义bilinear_img已经强制了数据类型\
bilinear_img[i][j] = ( \
(1 - a) * (1 - b) * img[row_up][col_left] + \
a * (1 - b) * img[row_up][col_right] + \
(1 - a) * b * img[row_bottom][col_left] + \
a * b * img[row_bottom][col_right] \
)
return bilinear_img
if __name__ == "__main__":
# 无法处理透明度通道(压根就没读进来)
img_source = cv2.imread(r"Image_restoration\source\1.png")
img_height, img_width, img_channels = img_source.shape
print("height {}, width {}, channels {}".format( img_height, img_width, img_channels))
times = 3 # 放大3倍
up_height = int(img_height * times)
up_width = int(img_width * times)
print("up_height {}, up_width {}".format(up_height, up_width))
bilinear_img = Bilinear(img_source, up_height, up_width, img_channels)
cv2.imshow("img_source", img_source)
cv2.imshow("bilinear_img", bilinear_img)
cv2.imwrite(r"Image_restoration\result\1_bilinear.png", bilinear_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
結果を示す
- 双一次補間を使用して画像を拡大した後、カラー ブロックは削減されますが、鮮明さの効果は依然として非常に限定的です。
その他の重み
双一次補間公式は、点 P の近くの 4 点の重みを設計します。
他の形式の重み付けを使用することもできます。のように:
- ガウス分布
距離が r の場合、ガウス公式を使用してその重みを計算します。
ω ( r ) = e − ( ε r ) 2 \bf \omega(r) = e^{-(\varepsilon r)^2}ω ( r )=e− ( ε r )2
注: 重みを正規化する必要があるため、省略される係数はここで直接破棄されます。
以下の二次元空間内。
点 P のピクセル値は
P = 1 ω ( a ) + ω ( b ) + ω ( c ) + ω ( d ) [ ω ( a ) × A + ω ( b ) × B + ω ( c ) × C + ω ( d ) × D ] P = \frac{1}{\omega(a)+\omega(b)+\omega(c)+\omega(d)}[\omega(a)\times A+\オメガ( b)\times B+\omega(c)\times C+\omega(d)\times D]P=お(あ)+o ( b )+o ( c )+o ( d )1[ o ( a )×あ+o ( b )×B+o ( c )×C+o ( d )×D ]
ブロガーが生み出す効果は平均的です。