Lekce 2 - Práce s videem v Pythonu a kreslení a psaní do obrázků
V předchozí lekci, Úvod do analýzy obrazu a videa v Pythonu, jsme si představili knihovny OpenCV, PIL, numpy a matplotlib.
V dnešním Python tutoriálu si ukážeme jak načíst, zobrazit a uložit video ve formátu MP4. Naučíme se také kreslit tvary na obrázky a psát do nich text.
Nejdříve si musíme sehnat nějaké ukázkové video, s kterým budeme pracovat. Pro potřeby kurzu jsem použil video níže. Pokud chcete, můžete použít samozřejmě i nějaké vlastní.
Soubor s videem si uložte jako video.mp4
do složky s dnešním
projektem.
Načtení videa
V první ukázce si video načteme, snímek po snímku zmenšíme na velikost 640x480px a zobrazíme. Přehrávání zmenšeného videa se ukončí klávesou X:
import cv2 vc = cv2.VideoCapture("video.mp4") while True: v_poradku, snimek = vc.read() snimek = cv2.resize(snimek, (640, 480)) cv2.imshow("video", snimek) if cv2.waitKey(1) & 0xFF == ord("x"): break vc.release() cv2.destroyAllWindows()
Nejříve si video načteme pomocí cv2.VideoCapture(zdroj)
a
poté vytvoříme cyklus. V něm získáme snímek funkcí
vc.read()
, která vrací krom snímku booleanovskou hodnotu, zda
byl snímek přečten v pořádku. Video má rozlišení 1280x720
,
to je moc a proto jej zmenšíme na rozlišení 640x480
funkcí
cv2.resize(snimek, (velikost -> tuple)
. Nakonec přidáme
podmínku zda uživatel stiskl klávesu X. Pokud ano, vyskočíme z
cyklu a odpojíme zdroj videa pomocí vc.release()
a všechna okna
zavřeme funkcí cv2.destroyAllWindows()
.
Kdybychom chtěli snímat obraz z webkamery, použili bychom namísto názvu
souboru parametr 0
, záleží kolik bychom měli zařízení,
např. jako cv2.VideoCapture(0)
:
import cv2 vc = cv2.VideoCapture("video.mp4") while True: v_poradku, snimek = vc.read() if not v_poradku: vc.set(cv2.CAP_PROP_POS_FRAMES, 0) continue snimek = cv2.resize(snimek, (640, 480)) cv2.imshow("video", snimek) if cv2.waitKey(1) & 0xFF == ord("x"): break vc.release() cv2.destroyAllWindows()
Po skončení přehrávání naše aplikace zatím spadne s chybou.
Přehrávání videa ve smyčce
Pokud video skončí, dosavadní skript vyvolá error. Abychom tomuto
předešli a video se mohlo přehrávat stále dokola, využijeme hodnotu
v_poradku
, kterou vrací funkce vc.read()
. Pokud se
snímek nepřečte v pořádku, nastavíme ukazatel na snímek 0
pomocí vc.set(cv2.CAP_PROP_POS_FRAMES, 0)
a video se přehraje
znovu.
Zobrazení více snímků naráz a černobílý efekt
Nyní si zobrazíme 2 snímky naráz, ten druhý však bude šedý:
import cv2 vc = cv2.VideoCapture("video.mp4") while True: v_poradku, snimek = vc.read() if not v_poradku: vc.set(cv2.CAP_PROP_POS_FRAMES, 0) continue snimek = cv2.resize(snimek, (640, 480)) snimek_gray = cv2.cvtColor(snimek, cv2.COLOR_BGR2GRAY) cv2.imshow("video", snimek) cv2.imshow("video_gray", snimek_gray) if cv2.waitKey(1) & 0xFF == ord("x"): break vc.release() cv2.destroyAllWindows()
Výsledek:

Uložení videa
Důležitou dovedností je bezesporu umět video uložit. Následuje ukázka kódu, která přesně toto dělá, s vysvětlením níže:
vc = cv2.VideoCapture("video.mp4") codec = cv2.VideoWriter_fourcc(*"MP4V") vw = cv2.VideoWriter("vytvorene_video.mp4", codec, 24, (640, 480)) while True: v_poradku, snimek = vc.read() if not v_poradku: break snimek = cv2.resize(snimek, (640, 480)) vw.write(snimek) cv2.imshow("video", snimek) if cv2.waitKey(1) & 0xFF == ord("x"): break vc.release() vw.release() cv2.destroyAllWindows()
Video si načteme a poté definujeme codec
cv2.VideoWriter_fourcc(znak1, znak2, znak3, znak4)
. Jelikož funkce
požaduje předat více znaků, používáme takzvanou starred
expression, která nám řetězec rozseká na jednotlivé znaky.
Nakonec vytvoříme VideoWriter
, který bude zapisovat do souboru
pomocí cv2.VideoWriter(soubor, codec, fps, velikost)
. Jednotlivé
snímky uložíme funkcí vw.write(snimek)
a po ukončení zápisu
VideoWriter
odpojíme funkcí vw.release()
.
Kreslení do videa
Na snímky videa můžeme samozřejmě kreslit. A to od čáry až po mnohoúhelník či vkládání textu na obrázek či video.
V ukázce budu používat opět obrázek níže, pokud však chcete používat vlastní, nic vám v tom nebrání. Také můžete upravovat přímo jednotlivé snímky videa.

Nejprve si jako vždy načteme náš obrázek a vykreslíme jej na obrazovku:
import cv2 import numpy as np img = cv2.imread("letadlo.jpg") cv2.imshow("obrazek", img)
Dále do něj vykreslíme čáru a počkáme na libovolnou klávesu:
cv2.line(img, (0, 0), (300, 550), (255, 255, 255), 10) cv2.imshow("obrazek", img) cv2.waitKey() cv2.destroyAllWindows()
Kreslíme jednoduchou bílou čáru pomocí funkce
cv2.line(obrázek, počáteční pozice, konečná pozice, barva jako BGR, tloušťka)
.
Výsledek:

Výtečně, jako další si ukážeme čtverec:
cv2.rectangle(img, (50, 50), (300, 300), (150, 200, 0), -1)
Pro vykreslení čtverce používáme funkci
cv2.rectangle(obrazek, pozice vlevo nahoře, pozice vpravo dole, barva, tloušťka)
.
Všimněte si, že jsme použili tloušťku -1
, to znamená, že se
čtverec vyplní:

Jako další tvar si vykreslíme kruh:
cv2.circle(img, (250, 250), 90, (0,0,255), 8)
Pro vykreslení kruhu použijeme funkci
cv2.circle(obrazek, střed, poloměr, barva, tloušťka)
.
Zkusme i vykrojenou elipsu:
cv2.ellipse(img, (1050, 400), (145, 50), 195, 0, 270, (0, 0, 255), -1) cv2.circle(img,(985, 350), 5, (0, 255, 0), -1)
Pro vykreslení elipsy používáme funkci
cv2.circle(obrazek, střed, velikost os, rotace, počáteční úhel, konečný úhel, barva, tloušťka)
.
A výsledek:

Posledním tvarem je mnohoúhelník neboli polygon:
pts = np.array([ [0, 0], [200, 500], [300, 300], [10, 50] ]) `cv2.polylines(img, [pts], True, (0, 255, 255), 3)`
Nejdříve si vytváříme numpy pole, kde jsou uloženy pozice jednotlivých
bodů mnohoúhelníku pomocí
np.array(list, datový typ - zde není nutné)
. Poté z těchto
bodů vytvoříme samotný mnohoúhelník funkcí
cv2.polylines(obrázek, [body], booleanovska hodnota - zda se má spojit první a poslední bod , barva, tloušťka)
.
Výsledný obrázek:

Tvary máme za sebou a nyní se podíváme na vkládání textu:
cv2.putText(img, "Python", (50, 250), cv2.FONT_ITALIC, 5, (224, 157, 33), 3, cv2.LINE_4) cv2.putText(img, "na", (50, 400), cv2.FONT_HERSHEY_COMPLEX_SMALL, 5, (50, 201, 209), 3, cv2.LINE_8) cv2.putText(img, "ITnetworku!", (50, 550), cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, 5, (224, 157, 33), 3, cv2.LINE_AA)
Pro vložení textu do obrázku použijeme funkci
cv2.putText(obrázek, text, pozice, font, velikost fontu, barva), tloušťka, typ linie/čáry)
.
Opět si ukažme výsledný obrázek:

Bonus
Pokud vás kreslení opravdu zaujalo, zkuste si nakreslit domeček jedním
tahem funkcí cv2.polylines()
. Hotové řešení naleznete ke
stažení v příloze článku spolu s dalšími zdrojovými kódy.

V další lekci, Práce s pixely a operace s obrázky v Pythonu, si ukážeme práci s jednotlivými pixely a aritmetické operace s obrázky v knihovně OpenCV v Pythonu.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 73x (24.91 MB)
Aplikace je včetně zdrojových kódů v jazyce Python