3d numpy 数组输出,旨在模拟图像,无法转换为图像

问题描述 投票:0回答:1

我正在使用函数 make_autostereogram 创建一个自动立体图。它被输出为 3d NumPy 数组(行、列、RGB)。

然后将其输入到 Pillow 函数 fromarray() 中。它具有正在输出的形状的数组。

代码:

import numpy as np
import matplotlib.pyplot as plt
import skimage, skimage.io
from PIL import Image
#%matplotlib inline

plt.rcParams['figure.dpi'] = 150

def blank_image(shape=(600, 800, 4),
               rgba=(255, 255, 255, 0)):
    "Returns a blank image, of size defined by shape and background color rgb."
    return np.ones(shape, dtype=float) * np.array(rgba) / 255

def normalize(depthmap):
    "Normalizes values of depthmap to [0, 1] range."
    if depthmap.max() > depthmap.min():
        return (depthmap - depthmap.min()) / (depthmap.max() - depthmap.min())
    else:
        return depthmap
    
def display(img, colorbar=False):
    "Displays an image."
    
    plt.figure(figsize=(10, 10))
    if len(img.shape) == 2:
        i = skimage.io.imshow(img, cmap='gray')
        #pass
    else:
        #pass
        i = skimage.io.imshow(img)
    i = skimage.io.imshow(img)
    if colorbar:
        plt.colorbar(i, shrink=0.5, label='depth')
    plt.tight_layout()
    print("display called")

def insert_pattern(background_img, pattern, location):
    #Inserts a pattern onto a background, at given location. Returns new image.
    img = background_img.copy()
    r0, c0 = location
    r1, c1 = r0 + pattern.shape[0], c0 + pattern.shape[1]
    if r1 < background_img.shape[0] and c1 < background_img.shape[1]:
        img[r0:r1, c0:c1, :] = skimage.img_as_float(pattern)
    return img



def tile_horizontally(background_img, pattern, start_location, repetitions, shift):
    "Tiles a pattern on a background image, repeatedly with a given shift."
    img = background_img.copy()
    for i in range(repetitions):
        r, c = start_location
        c += i * shift
        img = insert_pattern(img, pattern, location=(r, c))
    return img

def make_pattern(shape=(16, 16), levels=64):
    "Creates a pattern from gray values."
    return np.random.randint(0, levels - 1, shape) / levels


def create_circular_depthmap(shape=(600, 800), center=None, radius=100):
    "Creates a circular depthmap, centered on the image."
    depthmap = np.zeros(shape, dtype=float)
    r = np.arange(depthmap.shape[0])
    c = np.arange(depthmap.shape[1])
    R, C = np.meshgrid(r, c, indexing='ij')
    if center is None:
        center = np.array([r.max() / 2, c.max() / 2])
    d = np.sqrt((R - center[0])**2 + (C - center[1])**2)
    depthmap += (d < radius)
    return depthmap  


def make_autostereogram(depthmap, pattern, shift_amplitude=0.1, invert=False):
    "Creates an autostereogram from depthmap and pattern."
    print("make_autostereogram called")
    depthmap = normalize(depthmap)
    if invert:
        depthmap = 1 - depthmap
    
    #autostereogram = np.zeros_like(depthmap, dtype=pattern.dtype)
    autostereogram = np.zeros((depthmap.shape[0], depthmap.shape[1], 3))

    for r in np.arange(autostereogram.shape[0]):
        for c in np.arange(autostereogram.shape[1]):
            if c < pattern.shape[1]:
                for I in range(autostereogram.shape[2]): 
                     autostereogram[r, c, I] = pattern[r % pattern.shape[0], c, I] 
            else:
                shift = int(depthmap[r, c] * shift_amplitude * pattern.shape[1])
                for I in range(autostereogram.shape[2]):
                    autostereogram[r, c, I] = autostereogram[r, c - pattern.shape[1] + shift, I] 

    return autostereogram
   



img = blank_image()


"""

"""
texture= Image.open('marble.png')
texture.show()

"""

test_img = insert_pattern(img, coin, (10, 20))


pattern = make_pattern(shape=(128, 64))

#print(type(pattern))

patternImg = Image.fromarray(pattern) 

#patternImg.show()

print("pattern: ", type(pattern))
plt.imshow(pattern)
display(pattern)

depthmap = create_circular_depthmap(radius=150)

#print("depthmap: ", depthmap)

depthmapImg = Image.fromarray(normalize(depthmap))

#depthmapImg.show()

display(depthmap, colorbar=True)



#display(autostereogram)


print("depthmap array shape: ", depthmap.shape)

#print("new pattern: ", newPattern)





autostereogram2 = make_autostereogram(depthmap, newPattern)

print(autostereogram2)

#display(autostereogram2)

#print("stereogram shape: ", autostereogram2.shape())

autostereogramImg = patternImg = Image.fromarray(autostereogram2)

autostereogramImg.save('autostereogramOutput.png')

autostereogramImg.show()

错误:

 File "C:\Users\geniu\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\PIL\Image.py", line 3102, in fromarray
    raise TypeError(msg) from e
TypeError: Cannot handle this data type: (1, 1, 3), <f8

我在代码中使用display()函数时出错:

C:\Users\geniu\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\skimage\io\_plugins\matplotlib_plugin.py:158: UserWarning: Float image out of standard range; displaying image with stretched contrast.
  lo, hi, cmap = _get_display_range(image)
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
C:\Users\geniu\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\skimage\io\_plugins\matplotlib_plugin.py:171: UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect.
  ax.get_figure().tight_layout()
C:\Users\geniu\OneDrive\GW\Spring_2024\CSCI_6527\final_project.py:34: UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect.
  plt.tight_layout()

或者,我应该为此源代码使用黑白纹理吗?该源代码是在此处获得的,经过修改

https://flothesof.github.io/making-stereograms-Python.html

我只是想用 RGB 颜色显示或保存正在制作的数组中的图像。

python numpy image multidimensional-array python-imaging-library
1个回答
0
投票

从 PIL 文档,您可以(并且在本例中,您需要)指定Mode。所以,你应该有

Image.fromarray(autostereogram2, mode='RGB')
© www.soinside.com 2019 - 2024. All rights reserved.