Lekce 6 - Rozostření a vyhlazování obrázků v Pythonu
V předchozí lekci, Bitové operace a filtrování barev obrázků v Pythonu, jsme se zaměřili na bitové operace. Ukázali jsme si jak odfiltrovat barvy z obrázku v knihovně OpenCV.
V dnešním Python tutoriálu se podíváme na aplikaci vyhlazování pomocí filtrů a rozostřování.
Filtrování
Pro ukázku použiji tento obrázek s nízkým rozlišením, který si
uložte k projektu jako soubor low_res.jpg
:

Nejdříve si vysvětlíme, jak fungují 2D filtry. Filtr aplikuje
kernel
o velikosti x*x pixelů, z kterých se spočítá
průměrná hodnota. Kernel je numpy pole, v našem případě vyplněné
číslem 1
. Následně použijeme funkci
cv2.filter2d()
pro aplikaci kernelu, tato funkce má následující
parametry:
- obrázek
- hloubka - hloubka výsledného obrázku, pokud je hodnota
-1
, zůstává stejná - kernel - numpy pole o velikosti x*x, podle kterého se obrázek rozdělí na jednotlivé bloky a z těch se následně spočítá průměrná hodnota
Kód naší aplikace bude následující:
import cv2 import numpy as np img = cv2.imread("low_res.jpg") kernel = np.ones((4, 4), dtype=np.uint8) / (4 * 4) vyhlazeno = cv2.filter2D(img, -1, kernel) cv2.imshow("vyhlazeno", vyhlazeno) cv2.imshow("original", img) cv2.waitKey() cv2.destroyAllWindows()
Načteme si náš obrázek s nízkým rozlišením, poté si vytvoříme
numpy pole o velikosti 4x4, každý prvek následně vydělíme velikostí pole
kernel = np.ones((4, 4), dtype=np.uint8) / (4 * 4)
. Aplikujeme 2D
filtr s naším polem
vyhlazeno = cv2.filter2D(img, -1, kernel)
.
Výsledek:

Rozostření a vyhlazování
Rozostření se většinou používá k odstranění nedostatků a šumu z obrázků. K rozostření/vyhlazování obrázků se používají podobné filtry, jako jsme použili k vyhlazování obrázku výše.
Udělejme si další příklad:
import cv2 import numpy as np img = cv2.imread("letadlo.jpg") img = cv2.resize(img , (640, 480)) #Přídáme šum noise = np.zeros((img.shape), dtype = np.uint8) noise = cv2.randn(noise, 0, 150) img = img + noise cv2.imshow("original", img) img = cv2.blur(img , (7, 7)) cv2.imshow("rozostreny", img) cv2.waitKey() cv2.destroyAllWindows()
Obrázek načteme a zmenšíme, poté vytvoříme šum, který k obrázku
přidáme. Poté aplikujeme rozostření s kernelem o velikosti 7*7 jako
img = cv2.blur(img , (7, 7))
.

Gaussian Blur
Zkusíme na obrázek aplikovat různé druhy rozostření/vyhlazování, které OpenCV obsahuje. Tento typ požaduje mimo velikosti kernelu (velikost musí být lichá) tyto parametry:
- sigmaX - odchylka na ose X
- sigmaY - odchylka na ose Y, pokud je rovno
0
, velikost bude stejné jakosigmaX
Kód ukázky:
import cv2 import numpy as np img = cv2.imread("letadlo.jpg") img = cv2.resize(img , (640, 480)) #Přídáme šum noise = np.zeros((img.shape), dtype = np.uint8) noise = cv2.randn(noise, 0, 150) img = img + noise cv2.imshow("original", img) img = cv2.GaussianBlur(img , (7, 7), 0) cv2.imshow("rozostreny", img) cv2.waitKey() cv2.destroyAllWindows()
A výsledek:

Median Blur
Tento typ použije medián všech pixelů v bloku/kernelu, velikost bloku/kernelu musí být lichá:
import cv2 import numpy as np img = cv2.imread("letadlo.jpg") img = cv2.resize(img , (640, 480)) #Přídáme šum noise = np.zeros((img.shape), dtype = np.uint8) noise = cv2.randn(noise, 0, 150) img = img + noise cv2.imshow("original", img) img = cv2.medianBlur(img, 7) cv2.imshow("rozostreny", img) cv2.waitKey() cv2.destroyAllWindows()
Osobně si myslím, že tento typ odstranil náš šum nejlépe, jen se podívejte na rozdíl mezi originálem a rozostřeným obrázkem:

Bilateral Filter
Tento typ ponechá filtru původní hrany a nejefektivněji odstraní šum. Má následující parametry:
- obrázek
- sigmaColor - hodnota, které určuje jak moc se barvy smixují
- sigmaSpace - hodnota, která určuje jak moc se budou ovlivňovat vzdálenější pixely
Náš kód bude následující:
import cv2 import numpy as np img = cv2.imread("letadlo.jpg") img = cv2.resize(img , (640, 480)) #Přídáme šum noise = np.zeros((img.shape), dtype = np.uint8) noise = cv2.randn(noise, 0, 150) img = img + noise cv2.imshow("original", img) img = cv2.bilateralFilter(img, 7, 70, 70) cv2.imshow("rozostreny", img) cv2.waitKey() cv2.destroyAllWindows()
A výsledek:

Zdrojový kód najdete ke stažení v příloze článku.
V další lekci, Detekce objektu v obrázku podle barvy a detekce okrajů, si ukážeme detekci objektu v obrázku pode jeho barvy a detekci okrajů objektů 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 25x (640 B)
Aplikace je včetně zdrojových kódů v jazyce Python