程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

二次線性插值原理+代碼詳解【python】

編輯:Python

一、原理

參考博客,我也是看這篇文章入門的。

1、單次線性插值


單線性插值就好像初高中的兩點法求函數的表達式,利用y0和y1的加權表示y

2、雙線性插值


從兩個方向分別插值:


合並上式:

3、進階版本

雙線型內插值算法就是一種比較好的圖像縮放算法,它充分的利用了源圖中虛擬點四周的四個真實存在的像素值來共同決定目標圖中的一個像素值,因此縮放效果比簡單的最鄰近插值要好很多。由於圖像雙線性插值只會用相鄰的4個點,因此以下公式的分母都是1。算法描述:對於一個目的像素,設置坐標通過反向變換得到的浮點坐標為(i+u,j+v) (其中i、j均為浮點坐標的整數部分,u、v為浮點坐標的小數部分,是取值[0,1)區間的浮點數),則這個像素得值 f(i+u,j+v) 可由原圖像中坐標為 (i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所對應的周圍四個像素的值決定,即:

f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)

其中f(i,j)表示源圖像(i,j)處的的像素值,以此類推。單線性插值:已知數據 (x0, y0) 與 (x1, y1),要計算 [x0, x1] 區間內某一位置 x 在直線上的y值。雙線性插值:已知函數 f 在 Q11 = (x1, y1)、Q12 = (x1, y2), Q21 = (x2, y1) 以及 Q22 = (x2, y2) 四個點的值。求未知函數 f 在點 P = (x, y) 的值。

二、代碼

1、導入相關庫函數

from PIL import Image
from datetime import datetime
import matplotlib.pyplot as plt
import numpy as np
import math
import os

2、基本初始設置

img_path = r'D:\jupyter_py\in50.jpg' #源圖的地址
target_size = (600,800, 3) #目標圖像的尺寸
img_arr = np.array(Image.open(img_path), np.uint8)
source_img = Image.fromarray(img_arr.astype(np.uint8)) #源圖編碼
plt.imshow(source_img)
plt.show()
source_size = img_arr.shape #源圖尺寸
print(source_size)
ratio_x, ratio_y = source_size[0]/target_size[0], source_size[1]/target_size[1] #源圖和目標圖像長寬之比

3、定義求值函數

def cal(x, y, c): #傳入的是從目標圖像轉化為原圖像中的坐標值,但是並不是整數
x, y = math.modf(x), math.modf(y) #得到輸入值得整數部分和小數部分
mod_x, int_x, mod_y, int_y = round(x[0],4),int(x[1]),round(y[0],4),int(y[1]) #小數部分保留4位,索引必須為整數
#print(int_x, int_y)
if int_x<source_size[0]-1 and int_y<source_size[1]-1: #如果不加該條件,索引值會溢出
p1 = (1-mod_x)*(1-mod_y)*img_arr[int_x, int_y, c] + mod_x*(1-mod_y)*img_arr[int_x+1, int_y, c]
p2 = (1-mod_x)*mod_y*img_arr[int_x, int_y+1, c] + mod_x*mod_y*img_arr[int_x+1, int_y+1, c]
else:
p1 = (1-mod_x)*(1-mod_y)*img_arr[int_x, int_y, c] + mod_x*(1-mod_y)*img_arr[int_x, int_y, c]
p2 = (1-mod_x)*mod_y*img_arr[int_x, int_y, c] + mod_x*mod_y*img_arr[int_x, int_y, c]
p = p1 + p2 #原理公式
return p #上述處理比較草率,x,y分別溢出嚴格應進行三次條件判斷

4、mian函數

if __name__ == '__main__':
start = datetime.now() #計算運算時間
resized_img = [cal(i*ratio_x, j*ratio_y, c) for i in range(target_size[0]) for j in range(target_size[1]) for c in range(target_size[2])] #從三個維度依次計算
resized_img = np.array(resized_img).reshape((target_size[0], target_size[1], target_size[2]))
end = datetime.now()
seconds = (end-start).seconds
print('process cost {}s'.format(seconds)) #輸出計算時間
resized_show = Image.fromarray(resized_img.astype(np.uint8))
resized_show.save(r"./1.jpg") #保存目標圖像
plt.imshow(resized_show) #顯示目標圖像
plt.show()

5、效果展示



  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved