cv2 перекрывает кадры в выводе вместо записи новых кадров - PullRequest
0 голосов
/ 29 октября 2019

Итак, я пытаюсь использовать cv2 для записи AVI-файла волны. Вот мой код

import math

import cv2
import numpy as np
from PIL import Image, ImageFilter


def hex_to_rgb(h):
    return tuple([int(h[i:i + 2], 16) for i in range(0, 6, 2)])


def prep_frame(frame):
    img = Image.fromarray(frame.astype(np.uint8)).filter(ImageFilter.GaussianBlur(radius=0.5))
    imgarr = np.array(img, np.uint8)[:, :, ::-1]
    return imgarr


def sine_spiral(amplitude,
           periods,
           dims,
           hshift=0,
           vshift=None,
           wavelength=2 * math.pi,
           color=(255, 0, 0),
           width=3) -> np.array:
    """Returns a sine spiral wave

   Params
   ------
   amplitude: real
       amplitude of wave
   periods: real
       number of periods of the wave
   dims: tuple[int, int]
       dimensions of the plane on which the wave is drawn in (y, x) form
   hshift: int, optional
       horizontal shift of the wave
       -math.pi / 2 == cosine wave
       default 0
   vshift: int, optional
       vertical shift of the wave. If vshift is None, defaults to dims[0] // 2
       default None
   wavelength: real, optional
       wavelength of the wave
       default 2 * math.pi
   color: tuple[int, int, int]
       color of the wave
       default (255, 0, 0)
   width: int, optional
       width of the colored part of the wave
       default 3
   """
    color = np.array(color) / 2
    time = np.linspace(0, periods * wavelength, dims[1])
    plane = np.zeros((*dims, 3), np.uint8)
    if vshift is None:
        vshift = dims[0] // 2
    for idx, t in enumerate(time):
        y = int(vshift + amplitude * round(math.sin(t - hshift), 2))
        plane[y:y + width, idx] = color * (1 + math.sin(t - hshift)) ** 0.5
    return plane



if __name__ == '__main__':
    dimensions = (input('Input screen dimensions y x (default "768 1366"): ') or '768 1366').split()
    dimensions = tuple(map(int, dimensions))
    colors = []
    fourcc = cv2.VideoWriter_fourcc(*'MJPG')
    out = cv2.VideoWriter(f'{input("Filename (without extension): ")}.avi', fourcc, 60, dimensions[::-1])
    while True:
        try:
            color = input('Input rgb triple or hex string, separated by spaces ("q" to quit): ')
            colors.append(tuple(map(int, color.split())))
        except ValueError:
            if color == 'q':
                break
            colors.append(hex_to_rgb(color))
    amplitude = int(input('Wave amplitude: '))
    framedata = np.zeros((*dimensions, 3), np.uint16)
    for idx, i in enumerate(np.linspace(0, 2 * math.pi, 300)):
        for coloridx, shift in enumerate(np.linspace(0, math.pi / 2, len(colors))):
            hshift = (-1) ** (coloridx % 2) * (shift + i + amplitude * np.sin(coloridx))
            wave = sine_spiral(amplitude * math.sin(i), 2, (768, 1366), hshift, color=colors[coloridx])
            framedata = np.clip(framedata + wave, 0, 255)
        frame = prep_frame(framedata)
        out.write(frame)
        print(idx)
        framedata[:] = 0
    out.release()

(ссылка на Pastebin с кодом здесь ) Ожидаемый результат - это , где вокруг кадра движется одна волна. Однако вывод, который я получаю при использовании cv2, равен this . Мне кажется, что out.write(frame) пишет поверх каждого последовательного кадра, а не просто пишет новый кадр. Есть идеи, что происходит?

РЕДАКТИРОВАТЬ : Я забыл сбросить framedata[:] = 0 Я тупой

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...