画像補間 - 線形差分

理論的根拠

線形補間: 2 つの点によって直線が決定され、直線上の未知の点の値は直線の方程式によって決定できます。
線形補間
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 ob ) 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()

結果を示す

  1. 双一次補間を使用して画像を拡大した後、カラー ブロックは削減されますが、鮮明さの効果は依然として非常に限定的です。
    双一次補間

その他の重み

双一次補間公式は、点 P の近くの 4 点の重みを設計します。
他の形式の重み付けを使用することもできます。のように:

  1. ガウス分布
    距離が r の場合、ガウス公式を使用してその重みを計算します。
    ω ( r ) = e − ( ε r ) 2 \bf \omega(r) = e^{-(\varepsilon r)^2}ω ( r )=e( ε r )2
    注: 重みを正規化する必要があるため、省略される係数はここで直接破棄されます。
    1次元ガウス分布
    以下の二次元空間内。
    距離の重み
    点 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 ]

ブロガーが生み出す効果は平均的です。
ガウス分布の重み

おすすめ

転載: blog.csdn.net/2201_75691823/article/details/129636579