Lekce 5 - Bitové operace a filtrování barev obrázků v Pythonu
V předchozí lekci, Thresholding a analýza obrázků v Pythonu, jsme se zaměřili na thresholding v knihovně OpenCV.
V dnešním Python tutoriálu se podíváme na bitové operace, které jsme načali v předešlých lekcích. Ukážeme si jak fungují masky a odfiltrujeme si barvy z obrázku v OpenCV.
Bitové operace
Bitové operace, jak jsme se již dozvěděli ve 3. lekci, se používají k oddělení nějaké části obrázku od zbytku, v případě 3. lekce k oddělení pozadí od loga.
Tyto operace v knihovně OpenCV můžeme použít například pro vložení obrázku, odfiltrování pozadí/barvy, pro obrácení hodnot masky a mnohem více. Ukážeme si, jak fungují na následujících 2 obrázcích jednoduchých tvarů:

Začněme rovnou naší ukázkovou aplikací:
import cv2 import numpy as np img1 = np.zeros((300, 300), dtype=np.uint8) cv2.rectangle(img1, (0, 0), (200, 200), (255, 255, 255), -1) img2 = np.zeros((300, 300), dtype=np.uint8) cv2.rectangle(img2, (100, 100), (300, 200), (255, 255), -1)
Vytváříme 2 numpy pole np.zeros((300, 300), dtype=np.uint8)
,
která obsahují pouze hodnoty 0
, o rozměrech 300x300px a
datového typu np.uint8
. Poté do každého vložíme tvar jako na
obrázku.
Nyní aplikujeme všechny bitové operace z knihovny OpenCV na tyto 2 obrázky:
import cv2 import numpy as np img1 = np.zeros((300, 300), dtype=np.uint8) cv2.rectangle(img1, (0, 0), (200, 200), (255, 255, 255), -1) img2 = np.zeros((300, 300), dtype=np.uint8) cv2.rectangle(img2, (100, 100), (300, 200), (255, 255), -1) cv2.imshow("img1", img1) cv2.imshow("img2", img2) vystup = np.zeros((300,300), dtype=np.uint8) cv2.bitwise_and(img1, img2, vystup) cv2.imshow("and", vystup) cv2.bitwise_not(img1, vystup) cv2.imshow("not", vystup) cv2.bitwise_or(img1, img2, vystup) cv2.imshow("or", vystup) cv2.bitwise_xor(img1, img2, vystup) cv2.imshow("xor", vystup) cv2.waitKey() cv2.destroyAllWindows()
Výsledek jednotlivých operací vidíme na obrázku níže:

Odfiltrování barev
Ukážeme si, jak využít bitové operace pro odfiltrování barev. Jako vždy budu používat obrázek letadla:

Nejdříve si vytvoříme 2 numpy pole, která budou obsahovat rozsah barev, které se budou nacházet v masce. Nejdříve si ukážeme, jak vypadá naše maska, a poté aplikujeme bitovou operaci:
import cv2 import numpy as np img = cv2.imread("letadlo.jpg") barva_od = np.array([100, 50, 50]) barva_do = np.array([200, 200, 200]) maska = cv2.inRange(img, barva_od, barva_do) cv2.imshow("obrazek", img) cv2.waitKey() cv2.destroyAllWindows()
Jako vždy si načteme obrázek img = cv2.imread("letadlo.jpg")
.
Vytvoříme 2 numpy pole, která použijeme při tvorbě masky, což je rozmezí
barev, které chceme ponechat. Vytvoříme samotnou masku, která bude obsahovat
černá místa (obsahující naše vybrané barvy) a bílá (ostatní)
maska = cv2.inRange(img, barva_od, barva_do)
.
Maska letadla tedy vypadá takto:

Nyní masku aplikujeme a využijeme bitovou operaci
bitwise_and()
s naší maskou:
import cv2 import numpy as np img = cv2.imread("letadlo.jpg") barva_od = np.array([100, 50, 50]) barva_do = np.array([200, 200, 200]) maska = cv2.inRange(img, barva_od, barva_do) img = cv2.bitwise_and(img, img, mask = maska) cv2.imshow("obrazek", img) cv2.waitKey() cv2.destroyAllWindows()
Výsledek:

Černá místa nyní vyplníme obrázkem s kočkou:
import cv2 import numpy as np img = cv2.imread("letadlo.jpg") img2 = cv2.imread("kocka.jpg") img2 = img2[:img.shape[0], :img.shape[1]] barva_od = np.array([100, 50, 50]) barva_do = np.array([200, 200, 200]) maska = cv2.inRange(img, barva_od, barva_do) img = cv2.bitwise_and(img, img, mask = maska) maska_inv = cv2.bitwise_not(maska) img2_selected = cv2.bitwise_and(img2, img2, mask = maska_inv) celek = cv2.add(img, img2_selected) cv2.imshow("obrazek", celek) cv2.waitKey() cv2.destroyAllWindows()
Výsledek:

Nejprve aplikujeme bitovou operaci NOT na naši masku
maska_inv = cv2.bitwise_not(maska)
. Poté použijeme masku pro
výběr regionu z obrázku kočky
img2_selected = cv2.bitwise_and(img2, img2, mask = maska_inv)
.
Vybraný region a odfiltrovaný obrázek letadla spojíme
celek = cv2.add(img, img2_selected)
.
Zdrojový kód ukázkové aplikace najdete ke stažení v příloze článku.
V další lekci, Rozostření a vyhlazování obrázků v Pythonu, se zaměříme na aplikaci vyhlazování pomocí filtrů a rozostření pomocí funkcí v knihovně OpenCV.
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 21x (518.66 kB)
Aplikace je včetně zdrojových kódů v jazyce Python