Построение непосредственно в фильме с помощью numpy и mencoder

Итак, это должен быть комментарий к этой теме, но он, видимо, закрыт, так что вот оно. Я довольно успешно играл с matplotlib, numpy и mencoder, как было предложено здесь. С тех пор я использовал буфер Voki Codder для стандартного решения, которое значительно ускоряет весь процесс. Дело в том, что я не смог найти никакой документации по части команды -format="bgra". Это означает, что байты идут справа налево синий зеленый красный альфа, правый. Должны ли они быть uint32 или что-то еще. Проблема в том, что я строю карты цветов с плавающей запятой, поэтому я пытаюсь преобразовать их в оттенки серого, но получаю множество странных узоров, которые заставляют меня твердо верить, что я делаю что-то не так. Я написал эту функцию для преобразования из float в uint32 в пределах диапазона. Но результат не то, чего я ожидал, я делаю что-то ужасно глупое?

def grayscale(x, min, max):
  return np.uint32((x-min)/(max-min)*0xffffff)

person Alex S    schedule 12.08.2011    source источник


Ответы (1)


Я думаю, вы запутались в том, что представляет собой uint32. Это 4 полосы uint8 целых чисел.

Если у вас есть данные с плавающей запятой и вы хотите представить их в оттенках серого, вы не хотите масштабировать их до полного 32-битного диапазона, вы хотите масштабировать их до 8-битного диапазона и повторить это для красного, зеленого , и синие полосы (а затем предположительно помещаются в постоянную альфа-полосу).

Вы также можете просто использовать другой порядок байтов. Y8 — это всего лишь одна 8-битная полоса в градациях серого, а Y16 — 16-битная полоса в градациях серого. (Посмотрите на вывод mencoder -rawvideo format=help для полного (хотя и несколько запутанного) листинга.)

Просто чтобы проиллюстрировать использование numpy для просмотра 32-битного целого числа в виде четырех полос 8-битных целых чисел:

import numpy as np
height, width = 20,20

# Make an array with 4 bands of uint8 integers
image = np.zeros((height, width, 4), dtype=np.uint8)

# Filling a single band (red) 
b,g,r,a = image.T
r.fill(255) 

# Fill the image with yellow and leave alpha alone
image[...,:3] = (255, 255, 0) 

# Then when we want to view it as a single, 32-bit band:
image32bit = image.reshape(-1).view(np.uint32).reshape(height, width)
# (Note that this is a view. In other words,  we could change "b" above 
#  and it would change "image32bit")

Однако в вашем случае вы, вероятно, захотите сделать что-то вроде этого:

import numpy as np
from videosink import VideoSink

height, width = 20,20
numframes = 1000
data = np.random.random((height, width, numframes))

# Rescale your data into 0-255, 8-bit integers 
# (This could be done in-place if you need to conserve memory)
d    ata_rescaled = 255.0 / (data.max() - data.min()) * (data - data.min())
data_rescaled = data_rescaled.astype(np.uint8)

# The key here is the "Y8" format. It's 8-bit grayscale.
video = VideoSink((height,width), "test", rate=20, byteorder="Y8")

# Iterate over last axis
for frame in data.T:
    video.run(frame.T)
video.close()
person Joe Kington    schedule 12.08.2011
comment
Круто, поэтому лучше всего было бы сделать что-то вроде определения оттенков серого (x, min, max): t = int_max*(x-min)/(max-min) return np.uint8(t)*0x1 + np.uint8( t)*0x100 + np.uint8(x)*0x10000 + 0x0f000000, где int_max будет максимальным значением 8-битных целых чисел. - person Alex S; 14.08.2011
comment
Отличный материал, Джо, я провожу тест прямо сейчас, но я думаю, что теперь у меня есть это, порядок байтов, вероятно, добьется цели! Благодаря тонну! Алекс. - person Alex S; 15.08.2011