Как я могу добавить изображения .png, модифицированные с помощью Pillow, в видео OpenCV? - PullRequest
0 голосов
/ 28 декабря 2018

Я здесь новичок и хочу решить проблему, которая меня тошнит в последние недели ...

Это проблема, у меня есть 2 кода, один из которых захватывает видео из каталога (это может быть веб-камера, чтобы) с OpenCV и читать покадровый текст на каждом кадре, выводить одну переменную (только для тестирования), показывать мне видео и сохранять его в каталоге файлов python, это код .... («MyPath» - это путь к файлу, который не имеет значения для вопроса)

import cv2
import random

capture = cv2.VideoCapture(r"MyPath\Car.mp4")
out = cv2.VideoWriter('Test.avi',cv2.VideoWriter_fourcc('M','P','4','2'), 25, (1280, 720))

def velocity():
    now = (random.randint(0,100))
    return now

while True:
    ret, frame = capture.read()
    if ret:
        font=cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(frame,'Velocity:',(15,580),font,0.7,(255,255,255),1)
        cv2.putText(frame,'Distance:',(15,620),font,0.7,(255,255,255),1)
        cv2.putText(frame,'Inclination:',(15,660),font,0.7,(255,255,255),1)
        cv2.putText(frame,'Orientation:',(15,700),font,0.7,(255,255,255),1)
        cv2.putText(frame, str(velocity()), (130,580),font,0.7,(255,255,255),1)
        cv2.putText(frame,'KM/H',(165,580),font,0.7,(255,255,255),1)
        out.write(frame)
        cv2.imshow("Testing", frame)

    else:
        break

capture.release()
out.release()
cv2.destroyAllWindows()

Это работает нормально, здесь нет проблем, и у меня есть другой код с подушкой, который открывает фоновое изображение (jpg)и 4 изображения в png, которые изменяют размер и перемещают их, затем код вставляет изображения над фоном (я сделал фон только для тестирования, изображения этого 4 png должны отображаться в видеокадрах, но теперь это просто тестирование ...) затемпокажи мне и сохрани фон с png выше ... и снова, он работает отлично!

from PIL import Image

back = Image.open(r"MyPath\Eagle.jpg")
vel = Image.open(r"MyPath\Velocímeter.png")
dis = Image.open(r"MyPath\Distance.png")
inp = Image.open(r"MyPath\Inclination.png")
orz = Image.open(r"MyPath\Orientation.png")

vel = vel.resize((60, 60), Image.LANCZOS)
dis = dis.resize((55, 55), Image.LANCZOS)
inp = inp.resize((60, 60), Image.LANCZOS)
orz = orz.resize((60, 60), Image.LANCZOS)

back.paste(vel, (10, 420), vel)
back.paste(dis, (10, 510), dis)
back.paste(inp, (10, 583), inp)
back.paste(orz, (10, 655), orz)

back.show()
back.save("Test.jpg")

Проблема в том, что Pillow - это библиотека изображений, поэтому я не могу открыть видеои вставьте изображения, и OpenCV не будет легко принимать изображения в формате PNG, как Подушка ... есть ли способ смешать эти 2 кода в 1 и делать то, что я хочу сделать?(построение изображений PNG в видеокадрах для получения видео рендеринга с текстом и изображениями) Этот проект предназначен для получения информации о датчиках и графиках, поэтому я сделал тестовую функцию только для просмотра (изображения - это деталь, которую я хочудобавить в проект).Если вы любите мой код и это полезно для вас, не стесняйтесь использовать его!большое спасибо за чтение !!!Я надеюсь, что вы можете помочь мне (я не говорю по-английски оооочень, извините за возможные ошибки, но я могу отлично прочитать ваши ответы).

1 Ответ

0 голосов
/ 29 декабря 2018

Вы можете смешивать PIL / Pillow и OpenCV.Вам нужно знать три вещи ...

Чтобы преобразовать изображение OpenCV в изображение PIL:

pilimage = Image.fromarray(opencvimage)

Чтобы преобразовать изображение PIL в изображение OpenCV:

opencvimage = np.array(pilimage)

И, наконец, OpenCV сохраняет изображения в порядке BGR, в то время как PIL использует RGB, поэтому красные и синие цвета будут заменены местами, если вы не остерегаетесь - cvtColor (BGR2RGB) ваш друг здесь.

Теперь мы можем смешать эти две части кода:

#!/usr/bin/env python3

import cv2
import random
import numpy as np
from PIL import Image

# Load a speedo image which has transparency
speedo = Image.open('speedo.png').convert('RGBA')

capture = cv2.VideoCapture("movie.mov")
out = cv2.VideoWriter('test.mov',cv2.VideoWriter_fourcc('a','v','c','1'), 25, (1280, 720))

def velocity():
    now = (random.randint(0,100))
    return now

while True:
    ret, frame = capture.read()
    if ret:
        font=cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(frame,'Velocity:',(15,580),font,0.7,(255,255,255),1)
        cv2.putText(frame,'Distance:',(15,620),font,0.7,(255,255,255),1)
        cv2.putText(frame,'Inclination:',(15,660),font,0.7,(255,255,255),1)
        cv2.putText(frame,'Orientation:',(15,700),font,0.7,(255,255,255),1)
        cv2.putText(frame, str(velocity()), (130,580),font,0.7,(255,255,255),1)
        cv2.putText(frame,'KM/H',(165,580),font,0.7,(255,255,255),1)

        # Make PIL image from frame, paste in speedo, revert to OpenCV frame
        pilim = Image.fromarray(frame)
        pilim.paste(speedo,box=(80,20),mask=speedo)
        frame = np.array(pilim)

        out.write(frame)
        cv2.imshow("Testing", frame)
        cv2.waitKey(1)

    else:
        break

capture.release()
out.release()
cv2.destroyAllWindows()

Вот спидометр, который я использовал:

enter image description here


Если вы хотите, чтобы цвета правильно передавались в OpenCV из PIL, вам нужно переупорядочить каналы в соответствии с тем, что ожидает OpenCV, а именно BGRA.Таким образом, вы можете изменить загрузку изображения следующим образом:

# Open speedo image, split into separate RGBA channels, then re-combine in BGRA order for OpenCV
speedo = Image.open('speedo.png').convert('RGBA')
R,G,B,A = speedo.split()
speedo = Image.merge('RGBA',(B,G,R,A))
...