Narozeniny Black friday
Brno? Vypsali jsme pro vás nové termíny školení Základů programování a OOP v Brně!
Rozdáváme body k 9. výročí založení ITnetwork Získat dárkové kódy

Lekce 6 - Rozostření a vyhlazování obrázků 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, Bitové operace a filtrování barev obrázků v Pythonu, jsme si detailněji představili bitové operace v knihovně OpenCV a odfiltrovali barvy. 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:

Obrázek kočky s nízkým rolišením

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:

Aplikování filtru vyhlazování na obrázek v Pythonu

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í/vyh­lazová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)).

Filtr rozostření a šumu na obrázku v Pythonu

Gaussian Blur

Zkusíme na obrázek aplikovat různé druhy rozostření/vyh­lazová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é jako sigmaX

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:

Median Blur filtr na obrázku v Pythonu

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:

Bilateral Filter na obrázku v Pythonu

Zdrojový kód najdete ke stažení v příloze článku. V příští lekci, Detekce objektu v obrázku podle barvy a detekce okrajů, se podíváme na detekci předmětu v obrázku podle barvy a detekci okrajů.


 

Stáhnout

Staženo 3x (640 B)
Aplikace je včetně zdrojových kódů v jazyce Python

 

 

Aktivity (3)

 

 

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í!