0、pytorch函數(shù)實現(xiàn)方法:
import torch.nn.functional as F
image_arr=(np.random.rand(3,2,2)).astype(np.float32)
# print(image_arr)
image_tensor=torch.tensor(image_arr.copy(),dtype=torch.float32).unsqueeze(0)
# print(image_tensor)
# 使用pytorch的函數(shù)方法實現(xiàn)
result=F.interpolate(image_tensor,size=(3,3),mode="bilinear",align_corners=False)
1、最近鄰插值法
最鄰近插值:將每個目標像素找到距離它最近的原圖像素點,然后將該像素的值直接賦值給目標像素
- 優(yōu)點:實現(xiàn)簡單,計算速度快
-
缺點:插值結(jié)果缺乏連續(xù)性,可能會產(chǎn)生鋸齒狀的邊緣,對于圖像質(zhì)量影響較大,因此當(dāng)處理精度要求較高的圖像時,通常會采用更加精細的插值算法,例如:雙線性插值、三次插值。
-
代碼示例:
import numpy as np
from PIL import Image
def nearest_neighbor_interpolation(image,scale_factor):
"""
image:輸入圖像數(shù)組
scale_factor:圖像縮放因子
"""
# 得到輸入圖像的高與寬
height,width=image.shape[:2]
# 計算輸出圖像的高與寬
out_height=int(height * scale_factor)
out_width=int(width * scale_factor)
# 創(chuàng)建愛你輸出圖像
output_imaage=np.zeros((out_height,out_width,3),dtype=np.uint8)
print(output_imaage.shape)
# 遍歷輸出的每個像素,分別計算其在圖像中最近鄰的像素坐標,并將其像素值賦給當(dāng)前像素
for out_y in range(out_height):
for out_x in range(out_width):
# 計算當(dāng)前像素在輸入圖像中的坐標
input_x=int(round(out_x / scale_factor))
input_y=int(round(out_y / scale_factor))
# 判斷計算出來的輸入像素坐標是否越界,如果越界則賦值為邊界像素
input_x=min(input_x,width - 1)
input_y=min(input_y,height - 1)
# 將輸入圖像的像素值賦值給輸出圖像的對應(yīng)位置上的像素值
output_imaage[out_y,out_x]=image[input_y,input_x]
return output_imaage
# 讀取原始圖像
input_image=Image.open("./test_image.PNG").convert("RGB")
print(input_image)
image_array=np.array(input_image)
print(image_array.shape)
output_imaage=nearest_neighbor_interpolation(image_array,5.0)
out_image_pil=Image.fromarray(output_imaage.astype("uint8"))
print(out_image_pil)
out_image_pil.save("./result.jpg") # 保存數(shù)據(jù)圖像
結(jié)果:
-
使用場景:
雖然最近鄰插值算法會導(dǎo)致處理后的圖像出現(xiàn)鋸齒失真,但最進行圖像分割模型訓(xùn)練時,為了避免引入其他像素值的干擾,必須采用最近鄰插值算法。
2、雙線性插值
每個像素是一個正方形,紅點是像素的中心
每個像素的高和寬都是1, 面積為1
雙線性插值算法,包含兩種模式:角對齊模式與邊對齊模式
計算過程:
代碼實現(xiàn):
import torch
import numpy as np
import torch.nn.functional as F
def bilinear_interpolation(image,out_height,out_width,corner_align=False):
# 獲取輸入圖像的高與寬
height,width=image.shape[:2]
# 創(chuàng)建輸出圖像
output_image=np.zeros((out_height,out_width,image.shape[-1]),dtype=np.float32)
# print(output_image)
# 計算x,y軸的縮放因子
scale_x_corner=float(width - 1) / (out_width - 1) # (3-1) / (5-1) = 0.5
scale_y_corner=float(height - 1) / (out_height - 1) # (3-1) / (5-1) = 0.5
scale_x=float(width) / out_width # 3 / 5 = 0.6
scale_y=float(height) / out_height
# 遍歷輸出圖像的每個像素,分別計算其在輸入圖像中最近的四個像素的坐標,然后按照加權(quán)計算當(dāng)前像素的像素值
for out_y in range(out_height):
for out_x in range(out_width):
if corner_align == True:
# 計算當(dāng)前像素在輸入像素中的位置
x = out_x * scale_x_corner # 1 * 0.5 = 0.5
y = out_y * scale_y_corner # 1 * 0.5 = 0.5
else:
x=(out_x + 0.5) * scale_x - 0.5
y=(out_y + 0.5) * scale_y - 0.5
x=np.clip(x,0,width - 1)
y=np.clip(y,0,height-1)
# 計算當(dāng)前像素在輸入圖像中最近鄰的四個像素的坐標
x0,y0=int(x),int(y)
x1,y1=x0 + 1,y0 + 1
# 對原圖像邊緣進行特殊處理
if x0 == width - 1:
x0 = width - 2
x1 = width - 1
if y0 == height - 1:
y0 = height - 2
y1 = height - 1
xd = x - x0
yd = y - y0
p00=image[y0,x0]
p01=image[y0,x1]
p10=image[y1,x0]
p11=image[y1,x1]
x0y=p01 * xd + (1 - xd) * p00
x1y=p11 * xd + (1 - xd) * p10
output_image[out_y,out_x] = x1y * yd + (1 - yd) * x0y
return output_image
image_arr=(np.random.rand(2,3,3)).astype(np.float32)
# print(image_arr)
image_tensor=torch.tensor(image_arr.copy(),dtype=torch.float32).unsqueeze(0)
# print(image_tensor)
# 使用pytorch的函數(shù)方法實現(xiàn)
result=F.interpolate(image_tensor,size=(4,4),mode="bilinear",align_corners=False) # align_corners:True:角點對齊;False:為邊對齊
print(result.shape)
image_pytorch_result=result.squeeze(0)
print(image_pytorch_result.shape)
imge_torch2numpy=image_pytorch_result.numpy().transpose(1,2,0)
print(imge_torch2numpy.shape)
print(imge_torch2numpy)
print("\n","*"*40,"\n")
image_arr_=image_arr.transpose(1,2,0) # 轉(zhuǎn)成 H,W,C
# 自己代碼實現(xiàn)的版本
image_result=bilinear_interpolation(image_arr_,4,4,corner_align=False) # align_corners:True:角點對齊;False:為邊對齊
print(image_result)
print(image_result.shape)
輸出結(jié)果:文章來源:http://www.zghlxwxcb.cn/news/detail-768365.html
torch.Size([1, 2, 4, 4])
torch.Size([2, 4, 4])
(4, 4, 2)
[[[0.01729881 0.46345708]
[0.6254483 0.23894069]
[0.9647001 0.25322512]
[0.92197037 0.5015489 ]]
[[0.23900598 0.34148777]
[0.39870048 0.45681208]
[0.47503293 0.50936383]
[0.44255918 0.48162583]]
[[0.42145333 0.25761825]
[0.26364937 0.51880765]
[0.14657585 0.64366746]
[0.10925723 0.59057784]]
[[0.50382507 0.23980509]
[0.265312 0.40426224]
[0.08881453 0.6113682 ]
[0.03316517 0.7920877 ]]]
****************************************
[[[0.01729881 0.46345708]
[0.6254483 0.23894069]
[0.9647001 0.25322512]
[0.92197037 0.5015489 ]]
[[0.23900598 0.34148777]
[0.39870048 0.45681208]
[0.47503293 0.50936383]
[0.44255918 0.4816258 ]]
[[0.42145333 0.25761825]
[0.26364937 0.51880765]
[0.14657584 0.64366746]
[0.10925723 0.59057784]]
[[0.50382507 0.23980509]
[0.265312 0.40426219]
[0.08881453 0.6113682 ]
[0.03316517 0.7920877 ]]]
(4, 4, 2)
4、雙三次插值算法
文章來源地址http://www.zghlxwxcb.cn/news/detail-768365.html
到了這里,關(guān)于深度學(xué)習(xí)基礎(chǔ)知識 最近鄰插值法、雙線性插值法、雙三次插值算法的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!