Body zdarma Java týden
Využij podzimních slev a získej od nás až 40 % bodů zdarma! Více zde
Pouze tento týden sleva až 80 % na Java e-learning!

Lekce 3 - Práce s pixely a operace s obrázky v Pythonu

Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem.
Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, Práce s videem v Pythonu a kreslení a psaní do obrázků, jsme si ukázali, jak načíst a uložit video a jak kreslit různé tvary a text na obrázky. V dnešním Python tutoriálu si ukážeme, jak pracovat s pixely a provádět aritmetické operace s obrázky.

Práce s pixely

Z předchozích lekcí již víme, že video se skládá z jednotlivých snímku/obrázků, které se skládají z pixelů a ty jsou uspořádány v 2D listu.

Jako vždy budu v ukázkách používat obrázek níže:

Ukázkový obrázek letadla

Nejdříve si obrázek načteme:

import cv2
import numpy as np

img = cv2.imread("letadlo.jpg")

Změna barvy pixelu

Vypíšeme si barvu pixelu, který se nachází na pozici 250x330. V numpy se index u vícerozměrných polí rozděluje pomocí čátky ,:

print(img[250, 330])

Barvu pixelu zkusíme také změnit a obrázek znovu vykreslit:

print(img[250, 330])
img[250, 330] = [255,255,255]
print(img[250, 330])

cv2.imshow("obrazek", img)
cv2.waitKey()
cv2.destroyAllWindows()

Ujistíme se, že se barva opravdu změnila.

Změna pixelů obrázku v Pythonu

Změna barvy oblasti v obrázku

Takto můžeme změnit barvu vybrané části obrázku a ne pouze jednomu pixelu. Níže vybereme oblast od bodu [250:500] do bodu [330:600]:

img[250:500, 330:600] = [255,255,255]

cv2.imshow("obrazek", img)
cv2.waitKey()
cv2.destroyAllWindows()
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Při indexování můžeme použít jednu z následujících hodnot:

  • img.size - počet bodů v obrázku (u obrázku letadla = 2980680)
  • img.shape - rozměry obrázku a počet barevných složek (u obrázku letadla = (842, 1180, 3))
  • Pokud chceme znát datový typ obrázku, zjistíme ho pomocí img.dtype

Nyní si zkusíme zkopírovat vybrané pixely a vložit je na libovolnou pozici:

img[200:300, 500:600] = img[400:500, 200:300]

Výsledek:

Zkopírování části obrázku a její vložení do obrázku v Pythonu

Aritmetické operace s obrázky

Abychom si mohli ukázat aritmetické operace s obrázky, potřebujeme druhý obrázek. Já použiji tento:

Ukázkový obrázek kočky

Nejprve zkusíme pole pixelů obrázků sečíst:

letadlo = cv2.imread("letadlo.jpg")
kocka = cv2.imread("kocka.jpg")

kocka = kocka[:letadlo.shape[0], :letadlo.shape[1]]

img = letadlo + kocka

cv2.imshow("obrazek", img)
cv2.waitKey()
cv2.destroyAllWindows()

Jelikož obrázek s kočkou je větší, musíme ho přizpůsobit velikosti letadla pomocí kocka = kocka[:letadlo.shape[0], :letadlo.shape[1]]. Poté je jednoduše sečteme pomocí img = letadlo + kocka.

Sčítání pixelů obrázku v Pythonu

Tohle se nám úplně nevydařilo, jelikož jen tak 2 obrázky sečíst nemůžeme. Obrázek je strašně světlý, protože při sčítaní pixelů, např. hodnot [150, 200, 230] + [50, 80, 140] nám vyjde [200, 280, 370], což se ořízne na maximální hodnoty [200, 255, 255].

Abychom tomuto předešli, obrázky do sebe prolneme funkcí cv2.addWeighted(obrázek1, poměr/váha obrázku1, obrázek2, poměr/váha obrázku2, gamma):

img = cv2.addWeighted(letadlo, 0.4, kocka, 0.75, 0)

Výsledek je mnohem působivější:

Prolnutí dvou obrázků v Pythonu

Obrázek je ale stále poměrně světlý, proto nastavíme hodnotu gamma na -100:

img = cv2.addWeighted(letadlo, 0.4, kocka, 0.75, -100)

Výsledný obrázek vypadá mnohem lépe :)

Prolnutí dvou obrázků v Pythonu s úpravou světlosti pomocí hodnoty gamma

Vložení obrázku do obrázku bez prolnutí

Na závěr si ukážeme pro nás poměrně náročnou operaci, kdy vložíme jeden obrázek do druhého bez prolnutí. Jako ukázku si vložíme logo ITnetworku do obrázku s letadlem. Logo je následující obrázek typu PNG:

Vložení obrázku do obrázku v Pythonu

Na letadlo jej vložíme tak, aby byla bílá barva průhledná. Uveďme si nejprve kompletní zdrojový kód, který si záhy popíšeme:

letadlo = cv2.imread("letadlo.jpg")
itn = cv2.imread("itn.png")

region = letadlo[ 0:itn.shape[0], 0:itn.shape[1] ]
itn_seda = cv2.cvtColor(itn, cv2.COLOR_BGR2GRAY)

ret, maska = cv2.threshold(itn_seda, 150, 255, cv2.THRESH_BINARY_INV)
maska_inv = cv2.bitwise_not(maska)

letadlo_bg = cv2.bitwise_and(region, region, mask = maska_inv)
itn_bez_bg = cv2.bitwise_and(itn, itn, mask = maska)

logo_celek = cv2.add(letadlo_bg, itn_bez_bg)
letadlo[ 0:itn.shape[0], 0:itn.shape[1] ] = logo_celek

Nejdříve si definujeme region v obrázku letadlo, kam logo vložíme. My jej vložíme do levého horního rohu, region tedy bude region = letadlo[ 0:itn.shape[0], 0:itn.shape[1] ]. Logo převedeme z barevného na šedé pomocí itn_seda = cv2.cvtColor(itn, cv2.COLOR_BGR2GRAY), abychom později mohli oddělit pozadí. Vytvoříme masku, která nám oddělí bílé pozadí jako cv2.threshold(obrázek, práh, maximální hodnota, typ operace). Tato funkce převede pixely buď na černé nebo bílé. Poté použijeme bitovou operaci a vytvoříme tak další masku s opačnou hodnotou maska_inv = cv2.bitwise_not(maska). Aplikujeme maska_inv na vybraný region z obrázku letadlo jako letadlo_bg = cv2.bitwise_and(region, region, mask = maska_inv). Poté aplikujeme maska na logo pomocí bitové operace, tím se zbavíme pozadí itn_bez_bg = cv2.bitwise_and(itn, itn, mask = maska) a nakonec logo vložíme do obrázku jako letadlo[ 0:itn.shape[0], 0:itn.shape[1] ] = logo_celek.

Na bitové operace a thresholding se podíváme podrobněji v následujících lekcích :)

Vložení obrázku do obrázku v Pythonu

Zdrojový kód najdete ke stažení v příloze článku. V příští lekci, Thresholding a analýza obrázků v Pythonu, si vysvětlíme jak funguje thresholding a k čemu je vlastně dobrý.


 

Stáhnout

Staženo 5x (520.98 kB)
Aplikace je včetně zdrojových kódů v jazyce Python

 

 

Aktivity (2)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!