Python: Noise RGB 2d массив производит столбцы цвета - PullRequest
0 голосов
/ 12 октября 2019

Я следую этому уроку и должен был обновить его, чтобы использовать PIL Image.fromarray вместо scipy's toimage. Когда я запускаю этот код (маленький 64 ^ 2, а не целые 1024 ^ 2), на выходе появляются столбцы непрерывного цвета. Даже в первом наборе кодов, где я должен получить хороший черный и белый шарик, он выглядит как столбцы повторяющихся статических кубов. Почему это?

import noise
import numpy as np
from PIL import Image

shape       = (64,64)
scale       = 100.0
octaves     = 6
persistence = 0.5
lacunarity  = 2.0

world = np.zeros(shape)
for i in range(shape[0]):
    for j in range(shape[1]):
        world[i][j] = noise.pnoise2(j/scale, 
                                    i/scale, 
                                    octaves     = octaves, 
                                    persistence = persistence, 
                                    lacunarity  = lacunarity, 
                                    repeatx     = 1024, 
                                    repeaty     = 1024, 
                                    base        = 0)


blue = [65,105,225]
green = [34,139,34]
beach = [238, 214, 175]

def add_color(arr):
    color_world = np.zeros(arr.shape+(3,))
    for i in range(shape[0]):
        for j in range(shape[1]):
            if arr[i][j] < -0.05:
                color_world[i][j] = blue
            elif arr[i][j] < 0:
                color_world[i][j] = beach
            elif arr[i][j] < 1.0:
                color_world[i][j] = green

    return color_world

color_world = add_color(world)

im = Image.fromarray(color_world, "RGB")
im.show()

RGB 2D Perlin Noise Array

1 Ответ

0 голосов
/ 14 октября 2019

Проблема в том, что PIL.Image.fromarray ожидает, что его аргумент будет массивом целочисленных значений, но Numpy по умолчанию создает массивы значений с плавающей запятой. Таким образом, ваш массив color_world содержит значения с плавающей точкой, и поэтому ваше изображение искажено. Вертикальная полоса возникает из-за сходства в двоичном представлении этих значений с плавающей запятой.

Чтобы исправить, используйте метод astype массива Numpy, чтобы аргумент Image.fromarray был массивом uint8потому что это подходящий размер для ваших компонентов R, G и B. Вместо:

im = Image.fromarray(color_world, "RGB")

do:

im = Image.fromarray(color_world.astype("uint8"), "RGB")

В качестве альтернативы, создайте color_world как массив uint8 с самого начала. Для этого измените:

    color_world = np.zeros(arr.shape+(3,))

на:

    color_world = np.zeros(arr.shape+(3,), dtype="uint8")

Это может быть немного более эффективно.

...