Ausgabe
Ich habe ein Bild der Größe 1000 x 1000 (Graustufen). Ich möchte mit einer weißen Leinwand beginnen und die Pixelwerte einzeln auf diese Leinwand zeichnen und daraus ein Video erstellen. Wie können wir das erreichen?
Lösung
Es gibt viele Möglichkeiten, dies zu tun. Ich zeige nur 2 Möglichkeiten:
- mit OpenCV und seinen eingebauten
VideoWriter
, und - mit PIL/Kissen und
ffmpeg
extern
Sie können OpenCV und seine VideoWriter
wie folgt verwenden:
#!/usr/bin/env python3
import numpy as np
import cv2
# Load image in greyscale
im = cv2.imread('paddington.png', cv2.IMREAD_GRAYSCALE)
h, w = im.shape
# Make empty white RGB canvas same size
# I don't think VideoWriter likes greyscale frames, only 3-channel ones
canvas = np.full((h,w,3), 255, np.uint8)
# Create video writer
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out = cv2.VideoWriter("output.avi", fourcc, 30.0, im.shape)
cnt = 0
for y in range(h):
for x in range(w):
# Copy a grey pixel from image to RGB canvas
canvas[y,x,:] = im[y,x], im[y,x], im[y,x]
# Write every 100th frame to video to speed it up
if cnt % 100 == 0:
out.write(canvas)
# Count frames
cnt += 1
out.release()
Oder, wenn Sie es vorziehen – oder OpenCV nicht installieren können – können Sie PIL/Pillow und ffmpeg
so für das gleiche Ergebnis verwenden:
#!/usr/bin/env python3
################################################################################
# Run like this:
#
# ./plotPaddington2.py | ffmpeg -y -f rawvideo -pix_fmt gray8 -video_size 400x400 -i - -c:v h264 -pix_fmt yuv420p video.mov
################################################################################
from PIL import Image
import sys
# Load image in greyscale
im = Image.open('paddington.png').convert('L')
h, w = im.size
# Make empty white canvas same size
canvas = Image.new('L', im.size, 'white')
cnt = 0
for y in range(h):
for x in range(w):
# Copy a pixel from image to canvas
canvas.putpixel((x,y), im.getpixel((x,y)))
# Write every 100th frame to video to speed it up
if cnt % 100 == 0:
sys.stdout.buffer.write(canvas.tobytes())
# Count frames
cnt += 1
Dann würden Sie die Ausgabe dieses Skripts in ffmpeg
(mit angepassten Größenparametern, die zu Ihrem Video passen:
./plotPaddington2.py | ffmpeg -y -f rawvideo -pix_fmt gray8 -video_size 400x400 -i - -c:v h264 -pix_fmt yuv420p video.mov
Beachten Sie, dass Sie, wenn Sie ein Bild mit 1000 x 1000 Pixeln haben und für jedes einzelne Pixel einen neuen Videoframe erstellen, 1.000.000 Videoframes erhalten. Wenn Sie 30 Frames/Sekunde anzeigen, was für Videos ziemlich normal ist, dauert es 9 Stunden, bis Ihr Video fertig ist … also habe ich jeden 100. Frame gezeichnet:
hours = WIDTH * HEIGHT / (30 fps * 3600 seconds/hr) = 9.2 hrs
Beantwortet von – Mark Setchell
Antwort geprüft von – Robin (FixError Admin)