大家好!
我正在编写一个函数,它获取两个 Pytorch-Tensors 作为输入并将两个张量的部分合并到一个新数组,该数组将转换为 Lab-image之后。
net_input
是具有 3 个 channel (L、a、b)的张量,output
是具有 2 个 channel (a、b)的张量。
现在,我想从 net_input
获取 L channel ,从 output
获取 a channel 和 b channel 。
第一个张量 net_input
的值介于 -1 到 1 之间。第二个张量 output
的值介于 0 - 1 之间。
因此,它们都必须映射到从 -128 到 127 的值。我这样做是使用 interp1d
显然保存的图像有一些不需要的图案并且不正确。
from PIL import Image as pil
import numpy as np
from PIL import Image
from scipy.interpolate import interp1d
from datetime import datetime
def output_to_image(net_input, output, index):
# net_input.size() --> torch.Size([1, 3, 225, 225]) # l, a, b channel
# output.size() --> torch.Size([1, 2, 225, 225]) # a, b channel
# A - B - Channel
map_a_b = interp1d([0.0, 1.0], [-128, 127])
# L-Channel
map_l = interp1d([-1.0, 1.0], [-128, 127])
height = output.size()[2]
width = output.size()[3]
l = net_input.detach().numpy()[0][0] # l channel
a = output.detach().numpy()[0][0] # a channel
b = output.detach().numpy()[0][1] # b channel
# pdb.set_trace()
img_arr = np.empty([height, width, 3]) # lab img array
l_arr = np.empty([height, width]) # grayscale img array
for h in range(0, height-1):
for w in range(0, width-1):
img_arr[h][w] = [map_l(l[h][w]), map_a_b(a[h][w]), map_a_b(b[h][w])]
l_arr[h][w] = map_l(l[h][w])
now = datetime.now()
img = Image.fromarray(img_arr, "LAB")
img.save(f"../images/output/{now.strftime('%d-%m-%Y %H:%M:%S')}-lab-img{index}.tiff")
gray = Image.fromarray(l_arr, "L")
gray.save(f"../images/output/{now.strftime('%d-%m-%Y %H:%M:%S')}-gray-img{index}.jpg")
这是 L、a 和 b 的样子:
(Pdb) >? print(l)
[[-1. -1. -1. ... -1. -1. -1.]
[-1. -1. -1. ... -1. -1. -1.]
[-1. -1. -1. ... -1. -1. -1.]
...
[-1. -1. -1. ... -1. -1. -1.]
[-1. -1. -1. ... -1. -1. -1.]
[-1. -1. -1. ... -1. -1. -1.]]
(Pdb) >? print(a)
[[0.51877767 0.5208904 0.5310791 ... 0.5340722 0.51334995 0.522657 ]
[0.5142181 0.50250506 0.5197009 ... 0.51169556 0.5332947 0.5155644 ]
[0.53288984 0.51795006 0.5224927 ... 0.51704454 0.53655064 0.50311136]
...
[0.5270468 0.5071506 0.52318716 ... 0.5217321 0.53424454 0.5011423 ]
[0.5216123 0.53247094 0.5254119 ... 0.53089285 0.5259453 0.532716 ]
[0.53135234 0.5184961 0.51334924 ... 0.5131047 0.51930845 0.51474 ]]
(Pdb) >? print(b)
[[0.4812223 0.47910962 0.46892092 ... 0.46592775 0.48665005 0.47734302]
[0.48578197 0.49749494 0.4802992 ... 0.4883045 0.46670532 0.48443565]
[0.46711013 0.48204994 0.47750723 ... 0.4829555 0.46344927 0.4968886 ]
...
[0.47295317 0.49284932 0.47681284 ... 0.47826794 0.46575552 0.49885774]
[0.47838774 0.46752912 0.47458804 ... 0.46910718 0.47405463 0.46728405]
[0.46864766 0.48150396 0.48665074 ... 0.48689532 0.48069155 0.48526 ]]
(Pdb)
编辑:
按照 Mark 的建议,将插值范围调整为 0..255 后,输出看起来有点不同:
import numpy as np
from PIL import Image
from datetime import datetime
def output_to_image(net_input, output, index):
# net_input.size() --> torch.Size([1, 3, 225, 225])
# output.size() --> torch.Size([1, 3, 225, 225])
height = output.size()[2]
width = output.size()[3]
l = net_input.detach().numpy()[0][0] # l channel
a = output.detach().numpy()[0][0] # a channel
b = output.detach().numpy()[0][1] # b channel
#pdb.set_trace()
img_arr = np.empty([height, width, 3]) # lab img array
l_arr = np.empty([height, width]) # grayscale img array
for h in range(0, height-1):
for w in range(0, width-1):
img_arr[h][w] = [map_l(l[h][w]), map_a_b(a[h][w]), map_a_b(b[h][w])]
l_arr[h][w] = map_l(l[h][w])
now = datetime.now()
img = Image.fromarray(img_arr, "LAB")
img.save(f"../images/output/{now.strftime('%d-%m-%Y %H:%M:%S')}-lab-img{index}.tiff")
gray = Image.fromarray(l_arr, "L")
gray.save(f"../images/output/{now.strftime('%d-%m-%Y %H:%M:%S')}-gray-img{index}.jpg")
def map_l(x):
return (x+1)*127
def map_a_b(x):
return x*127
最佳答案
如果您使用 PIL 执行此操作:
im = Image.new('LAB',(80,80),color=(255,0,0)).save('a.tif')
您将获得与使用 this colour converter 相同的青色并放入
L/a/b = 100/-128/-128
如果你这样做:
im = Image.new('LAB',(80,80),color=(255,255,0)).save('a.tif')
你会发现对应
L/a/b=100/128/-128
在在线转换器上。
如果你这样做:
im = Image.new('LAB',(80,80),color=(255,255,255)).save('a.tif')
你会发现对应
L/a/b=100/128/128
在在线转换器上。
因此,我认为如果使用 PIL,您的目标限制是错误的。 L
、a
和 b
的范围都应为 0..255。
关于缩放,我根本不会使用 interp1d()
。如果我需要将范围 -1..1 缩放到范围 0..255,我会加 1 到范围 0..2,然后乘以 255/2。
关于python - 通过 PIL 将 Numpy 数组保存为实验室图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58892179/