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 75x (24.91 MB)
Aplikace je včetně zdrojových kódů v jazyce Python

