Dnes se naučíme detekovat čáry a kruhy v obrázku pomocí techniky zvané Houghova transformace.
Co je to Houghův prostor
Než začneme na obrázky aplikovat Houghovu transformaci, musíme pochopit, co je to Houghův prostor, a to se dozvíme na příkladu.
Parametrický prostor
Při práci s obrázky si můžeme představit, že obrázek je 2d matice nad nějakými souřadnicemi x a y, pod kterou by se dala linie popsat jako y = mx + b
Ale v parametrickém prostoru, který budeme nazývat Houghův prostor, mohu místo toho tutéž čáru reprezentovat jako m
vs b
, takže charakteristika čáry v obrazovém prostoru, bude jediný bod na pozici m-b
v Houghově prostoru.
Máme však problém, u y = mx + b
nemůžeme znázornit svislou přímku, protože její sklon je nekonečný. Potřebujeme tedy lepší způsob parametrizace, polární souřadnice (rho a theta).
Houghův prostor
- rho: popisuje vzdálenost přímky od počátku
- theta: popisuje úhel vzdálený od vodorovné roviny
Jeden velmi důležitý postřeh však je, co se stane, když vezmeme více bodů kolem přímky a transformujeme je do našeho Houghova prostoru.
Jediný bod v obrazovém prostoru se převede na křivku v Houghově prostoru, přičemž zvláštností je, že body mezi přímkou v obrazovém prostoru budou reprezentovány více křivkami s jedním dotykovým bodem.
A to bude náš cíl, najít body, kde se skupina křivek protíná.
Co je Houghova transformace?
Houghova transformace je metoda extrakce rysů pro detekci jednoduchých tvarů, jako jsou kružnice, čáry atd. v obraze.
„Jednoduchá“ charakteristika je odvozena reprezentací tvaru z hlediska parametrů. „Jednoduchý“ tvar bude reprezentován pouze několika parametry, například přímka může být reprezentována svým sklonem a průsečíkem nebo kružnice, kterou lze reprezentovat pomocí x, y a poloměru.
V našem příkladu s přímkou bude Houghova transformace zodpovědná za zpracování bodů na obrázku a výpočet hodnot v Houghově prostoru.
Algoritmus pro uskutečnění transformace a následné nalezení průsečíků křivek je trochu komplikovaný, a proto je mimo rozsah tohoto příspěvku. Podíváme se však na implementaci tohoto algoritmu, která je součástí knihovny OpenCV.
Detekce čar pomocí OpenCV
V OpenCV je detekce čar pomocí Houghovy transformace implementována ve funkcích HoughLines
a HoughLinesP
(pravděpodobnostní Houghova transformace). My se zaměříme na druhou z nich.
Funkce očekává následující parametry:
-
image
: 8bitový, jednokanálový binární zdrojový obrázek. Obraz může být funkcí upraven. -
lines
: Výstupní vektor řádků. Každá čára je reprezentována čtyřprvkovým vektorem (x_1, y_1, x_2, y_2) , kde (x_1,y_1) a (x_2, y_2) jsou koncové body každého detekovaného úseku čáry. -
rho
: -
theta
: -
threshold
: Úhlové rozlišení akumulátoru v radiánech: Parametr prahové hodnoty akumulátoru. Vrátí se pouze ty řádky, které získají dostatečný počet hlasů -
minLineLength
: Minimální délka řádku. Úseky čar kratší než tato hodnota jsou odmítnuty. -
maxLineGap
:
Příliš složité? jednodušší je to s příkladem:
# Read image img = cv2.imread('lanes.jpg', cv2.IMREAD_COLOR)# Convert the image to gray-scalegray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Find the edges in the image using canny detectoredges = cv2.Canny(gray, 50, 200)# Detect points that form a linelines = cv2.HoughLinesP(edges, 1, np.pi/180, max_slider, minLineLength=10, maxLineGap=250)# Draw lines on the imagefor line in lines: x1, y1, x2, y2 = line cv2.line(img, (x1, y1), (x2, y2), (255, 0, 0), 3)# Show resultcv2.imshow("Result Image", img)
A zde je výsledek:
Je velmi důležité, abychom jako parametr pro Houghovu transformaci skutečně použili pouze obraz s hranami, jinak algoritmus nebude fungovat tak, jak má.
Detekce kružnic pomocí OpenCV
Postup je přibližně stejný jako u čar s tím rozdílem, že tentokrát použijeme jinou funkci z knihovny OpenCV. Nyní použijeme HoughCircles
, která přijímá následující parametry:
-
image
: 8bitový, jednokanálový vstupní obrázek ve stupních šedi. -
circles
: Výstupní vektor nalezených kružnic. Každý vektor je kódován jako tříprvkový vektor s pohyblivou řádovou čárkou (x, y, poloměr) . -
circle_storage
: Ve funkci C se jedná o paměťové úložiště, které bude obsahovat výstupní posloupnost nalezených kružnic. -
method
: Metoda detekce, která se má použít. V současné době je implementována pouze metoda CV_HOUGH_GRADIENT , což je v podstatě 21HT -
dp
: Inverzní poměr rozlišení akumulátoru k rozlišení obrazu. Například pokud dp=1 , má akumulátor stejné rozlišení jako vstupní obraz. Pokud dp=2 , má akumulátor poloviční šířku a výšku. -
minDist
: Minimální vzdálenost mezi středy detekovaných kruhů. Pokud je parametr příliš malý, může být kromě pravého kruhu falešně detekováno i více sousedních kruhů. Pokud je příliš velký, mohou být některé kruhy přehlédnuty. -
param1
: První parametr specifický pro metodu. V případě CV_HOUGH_GRADIENT je to vyšší práh ze dvou předaných detektoru hran Canny() (nižší je dvakrát menší). -
param2
: Druhý parametr specifický pro metodu. V případě CV_HOUGH_GRADIENT , je to prahová hodnota akumulátoru pro středy kruhů ve fázi detekce. Čím je menší, tím více falešných kruhů může být detekováno. Kružnice, které odpovídají větším hodnotám akumulátoru, budou vráceny jako první. -
minRadius
: -
maxRadius
:
Pamatujte, že parametry musí být jiné, protože kružnici nemůžeme popsat stejnou parametrizací, jakou jsme použili pro čáry, a místo toho musíme použít rovnici jako (x - x0)^^2 + (y - y0)^^2 = r^^2
.
A ke kódu:
# Read image as gray-scaleimg = cv2.imread('circles.png', cv2.IMREAD_COLOR)# Convert to gray-scalegray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Blur the image to reduce noiseimg_blur = cv2.medianBlur(gray, 5)# Apply hough transform on the imagecircles = cv2.HoughCircles(img_blur, cv2.HOUGH_GRADIENT, 1, img.shape/64, param1=200, param2=10, minRadius=5, maxRadius=30)# Draw detected circlesif circles is not None: circles = np.uint16(np.around(circles)) for i in circles: # Draw outer circle cv2.circle(img, (i, i), i, (0, 255, 0), 2) # Draw inner circle cv2.circle(img, (i, i), 2, (0, 0, 255), 3)
Všimněte si, že oproti předchozímu příkladu zde nepoužíváme žádnou funkci detekce hran. Je to proto, že funkce HoughCircles
má zabudovanou detekci hran.
A výsledek:
Závěr
Houghova transformace je vynikající technika pro detekci jednoduchých tvarů v obrazech a má řadu aplikací, od lékařských aplikací, jako je rentgenová analýza, CT a MRI, až po samořídící automobily. Pokud máte zájem dozvědět se o Houghově prostoru více, doporučuji, abyste kód skutečně spustili, sami vyzkoušeli různé konfigurace a abyste se podívali do dokumentace OpenCV, kde najdete další informace.
Díky za přečtení!