Moravian instruments
Vyhledávání
Hlavní menu
Hlavní stránka
O společnosti
Stažení software
Stažení dokumentů
Obchodní partneři
Registrace
Vstup pro partnery
Produkty
Programový systém Control Web
Strojové vidění VisionLab
Kamery DataCam a  osvětlovače DataLight
Průmyslový počítačový systém DataLab
Vědecké CCD kamery
Speciální technika
Ceník
Aktivace produktů
Control Web online
Služby
Školení
Zakázková řešení
Podpora


Hlavní stránka  Produkty  Strojové vidění VisionLab

Využití grafických procesorů v systémech strojového vidění
 Co jsou zač ty podivné grafické procesory, které máme všichni ve svých počítačích? Máme se o ně zajímat? Zabýváme-li se aplikacemi strojového vidění, pak je dobré vědět, jak grafické procesory (GPU - Graphics Processing Unit) pracují, kde nám mohou vydatně pomoci a na co si naopak musíme dát pozor.

Grafický procesor se stal běžnou a již samozřejmou součástí většiny počítačů. Současný počítač tak představuje heterogenní výpočetní prostředí, ze kterého velké většina programového vybavení bohužel stále používá jen jeho, v určitém směru, méně výkonnou část. Právě algoritmy strojového vidění jsou velmi náročné na výpočetní výkon a často jsou také velmi dobře paralelizovatelné. Proto plné využití potenciálu počítačů se může pro aplikace strojového vidění a vizuální inspekce stát značnou konkurenční výhodou.

GPU mohou provádět mnoho operací s daty, které jsou tradičně prováděny pomocí CPU, a některé z těchto operací mohou velmi významně urychlit. Zatímco CPU mají jen několik výpočetních jader, GPU jich mají několik set. Grafické procesory byly původně navrženy pouze pro akceleraci počítačové grafiky a pro práci s grafickými daty. I když dnešní systému mohou pracovat i s obecnými daty, funkčnost grafických procesorů stále zůstává hodně omezená a zdaleka ne všechny typy úloh je vhodné řešit prostřednictvím GPU.

Na úvod si připomeňme základní koncepce architektury GPU v grafických adaptérech počítačů a nakonec se zaměříme na využití programovatelných GPU s systému strojového vidění VisionLab.

Vnitřní architektury GPU hlavních výrobců NVIDIA, AMD a Intel se navzájem hodně liší. Jedná se o velmi složité obvody. Jen jako ilustraci složitosti a výkonnosti moderních GPU si uveďme několik parametrů grafického procesoru GeForce GTX 680:

Počet tranzistorů 3.5 miliardy
Počet výpočetních jader 1536
Hodinové frekvence GPU 1006 MHz
Výkon přístupu k texturám 128.8 miliard pixelů za sekundu
Šířka sběrnice grafické paměti 384 bitů
Datová propustnost 192.2 GB za sekundu
Výpočetní výkon (single presision) 3.79 TFLOPS

Při pohledu na tyto působivé parametry je zřejmé, jak velká škoda by byla nechat tento potenciál ležet ladem.

Tento procesor má již uniformní architekturu shaderů a je dalším důkazem, že vývoj v této oblasti stále více směřuje k vyšší použitelnosti GPU pro obecné výpočty než jen pro akceleraci grafiky. Tento trend začal u firmy NVIDIA uvedením přelomového procesoru G80 v roce 2006. V uniformní architektuře mohou všechny procesory v GPU podle aktuálních potřeb vystupovat v roli vertexových, fragmentových nebo geometrických shaderů.

Cesta k dnešní uniformní architektuře nebyla krátká. S využitím grafických akcelerátorů pro akceleraci výpočtů se dokonce experimentovalo již době, kdy tyto čipy měly pouze pevně danou funkčnost a nebylo je možno programovat. Využívaly se hardwarové interpolátory a rasterizery, filtry textur, míchání vektorů, operace s accumulator a stencil bufferem atd. Tyto postupy vyžadovaly od programátorů hlubokou znalost principů fungování grafického řetězce a značnou kreativitu. Dalším krokem ve vývoji byly pak programovatelné fragmentové procesory s již standardizovanými pseudo assemblery, které se staly součástí grafických ovladačů. Hardware i instrukční soubory jednotlivých GPU byly a jsou doposud odlišné a právě překladače v grafických ovladačích umožnily přenositelnost kódů shaderů (zde máme trochu zmatení pojmů, označení shader se používalo jak pro programovatelné fragmentové procesory, tak pro programy těchto procesorů). Tento způsob programování GPU byl stále pro většinu programátorů zcela nestravitelný a používala jej jen hrstka nadšenců.

Důležitým momentem byl příchod vysokoúrovňových jazyků pro programování shaderů. Všichni tři zástupci ( Cg ( NVIDIA pro DirectX i OpenGL), HLSL „High-Level Shading Language“( Microsoft DirectX) a GLSL „OpenGL Shading Language“(dodnes standardní jazyk shaderů pro OpenGL) ) mají podobné schopnosti a jejich zápis se velmi podobá jazyku C. Tyto jazyky jsou již velmi dobře použitelné pro programování obecných výpočtů, to znamená, že jsou jim přístupny téměř veškeré vlastnosti současných GPU, nicméně stále ještě z programátorů nesnímají nutnost znát vlastnosti grafického řetězce a přistupovat k GPU prostřednictvím grafického API. Původní základní princip GPU, totiž vytváření obrázků je i v jazycích vysoké úrovně stále viditelný.

Dnes existuje řada softwarových prostředí a nástrojů, které programátora izolují od této původní podstaty GPU a předkládají mu obecně přijatelnější programovací model. Tyto nástroje, k nimž patří např. Sh (Rapid Mind), BrookGPU, Accelerator (Microsoft), PeakStream (Google), Ashli (nadstavba nad Cg, HLSL a GLSL), CTM ( AMD ), CUDA (NVIDIA), ArBB (Intel), OpenCL atd. Tyto nástroje více či méně obcházejí grafické ovladače, umožňují pracovat s pamětí v podobě proměnných a polí C jazyka a někdy dokonce i ukazatelů (CUDA) a především zajišťují upload vstupních dat do textur v grafické paměti, download výsledků z frame bufferu grafické paměti a just-in-time kompilaci a optimalizaci kódu shaderů. Vstupní i výstupní data mají obvykle podobu polí vektorů. Objevují se systémy, kde rozhraním na GPU je virtuální stroj, který zajistí přenositelnost kódu. V této oblasti je stále situace velice nepřehledná, probíhá zde rychlý vývoj a chybí silné a hlavně dlouhodobě stabilní standardy.

Naštěstí v oboru strojového vidění pracujeme převážně s obrazovými daty a tradiční podoba grafického řetězce nám většinou velmi dobře vyhovuje.

Obr.1: Řetězec zpracování grafických dat v GPU

Obr.1: Řetězec zpracování grafických dat v GPU

Při obecných výpočtech pracuje GPU velice podobně. Pouze místo obrazových dat se pracuje se vstupními a výstupními bloky obecných dat a shadery jsou do jisté míry obecnými paralelními vlákny. Obraz z kamery vstupuje do GPU jako objekt textury, který musí být na začátku přenesen ze systémové paměti počítače do grafické paměti, které je přístupná pro GPU. Výsledný obrazový buffer nakonec také musí být často přenesen nazpět do systémové paměti počítače. Také bloky obecných dat musí být takto přenášeny mezi systémovou a grafickou pamětí. Tento princip může být pro programátora částečně zakryt programovým rozhraním vývojového prostředí, limity z něj plynoucí však překonat nelze.

Právě přenosy velkých objemů dat mezi systémovou a grafickou pamětí (grafické adaptéry jsou obvykle připojeny přes sběrnici PCI-Express) mohou představovat citelné zpomalení a stát se tím rozhodujícím problémem v neprospěch využití GPU.

Úloha vhodná pro GPU také musí mít několik charakteristických znaků. CPU má jen několik jader, ale každé toto jádro může pracovat na zcela odlišné úloze. GPU má výpočetních jader velmi mnoho, ale zjednodušeně řečeno, všechna jádra musí, byť s různými vstupními daty, zpracovávat tutéž úlohu. Výhody takovéto masivní paralelizace se více projeví v úlohách s vysokou výpočetní intenzitou, velkými objemy paralelně zpracovávaných dat a s minimálními závislostmi mezi jednotlivými těmito daty. Výsledek každého paralelního výpočtu v GPU závisí jen na vstupních datech a nikoliv na výsledky výpočtů ostatních paralelních procesů. Jednotlivá výpočetní jádra se tedy v průběhu výpočtů nemohou ovlivňovat, pouze mohou číst mnoho vstupních vektorových dat z mnoha datových polí.

Prostředky GPU

Pro zpracování obrazu nás zajímají především:

  • Programovatelné procesory – v uniformní architektuře mohou vystupovat jako vertexové, fragmentové a geometrické. Při zpracování obrazu z kamery využijeme tradiční funkce vertexových a fragmentových shaderů:

    • Vertexový shader je spuštěn pro každý vertex, vykreslujeme-li např. trojúhelník, je spušten celkem třikrát. Jeho výsledkem je grafický element, který je předán do rasterizeru.

    • Fragmentový shader je spoušten výstupem rasterizeru pro každý fragment, tedy pro každý obrazový bod vykreslované scény.

  • Rasterizer – prostřednictvím interpolace vytváří jednotlivé fragmenty z obrazových elementů. Základním obrazovým elementem je trojúhelník, definovaný třemi vertexy. V jeho ploše jsou pak resterizerem interpolovány texturové souřadnice nebo barvy fragmentů.

  • Textury – jsou bloky grafické paměti, které mohou být čteny fragmentovými procesory. Data z texturových objektů lze pouze číst, zápis do nich není fragmentovými shadery možný.

  • Framebuffer – je blok paměti, do které fragmentové procesory zapisují výsledku běhu fragmentových shaderů. Data uvnitř framebufferu nelze fragmentovým procesorem číst a dokonce každý s paralelně běžících fragmentových shaderů může zapsat jen do jediné pozice v bufferu, která odpovídá jeho instanci v rámci plochy obrazu.

Omezení textur jako zdrojů dat, do kterých není možno zapisovat, a framebufferů jako cílů, které nelze číst, klade další nároky na kopírování bloků dat v grafické paměti během opakovaného vícenásobného spouštení shaderů pro daný framebuffer. Proto dnes existuje možnost přiřazení textury jako cíle vykreslování. Tato možnost umožňuje realizovat vícenásobné vykreslování maximálně efektivně.

Datové typy a programovatelnost

GPU byly navrženy pro práci s obrazovými daty a zpočátku tak byly podporovány pouze celočíselné datové typy, které popisovaly fragmenty, tj. obrazové body – pixely. Pro všeobecné výpočty je důležitá schopnost dnešních GPU pracovat s poli vektorů čísel s plovoucí řádovou čárkou s jednoduchou (FP32 – 4 byte na jedno číslo s plovoucí řádovou čárkou –float) i dvojnásobnou (FP64 – 8 byte na jedno číslo s plovoucí řádovou čárkou - double) přesností. Vstupní a výstupní data mohou být obvykle v těchto formátech:

  • 8 bitů na pixel – takto je reprezentován buď index do palety barev nebo dva bity pro červenou, tři zelenou a tři modrou barvu

  • 16 bitů na pixel – obvykle pět bitů určuje červenou a po šesti bitech má k dispozici zelená a modrá barva

  • 24 bitů na pixel – osmibitový červený, zelený a modrý kanál

  • 32 bitů na pixel – osmibitový červený, zelený, modrý a alpha kanál reprezentující míru průhlednosti

  • 1 až 4 čísla v plovoucí řádové čárce na pixel, kdy každé číslo má přesnost na 16, 24, 32 nebo 64 bitů (FP16, FP24, FP32 nebo FP64)

Podstatnou vlastností paralelních procesorů v GPU je také to, že pracují v jedné instrukci s celými vektory. Např. při sečítání dvou čtyřrozměrných vektorů jsou současně sečteny všechny jejich příslušné složky.

Ovladače grafických adaptérů

Se začleněním překladačů vysokoúrovňových jazyků se grafické ovladače dále zkomplikovaly a jejich dlouholetá pověstná chybovost se mohla rozšířit do nových rozsáhlých oblastí. Na počátcích těchto technologií to opravdu programátoři neměli jednoduché. Relativně nejméně chyb vždy bývalo v ovladačích pro grafické adaptéry NVIDIA. Dnes již je v této oblasti situace naštěstí celkem stabilní a software využívající GPU obvykle pracuje spolehlivě s ovladači všech hlavních výrobců.

Využití GPU v systému strojového vidění VisionLab

Algoritmy strojového vidění často pracují s velkými objemy dat a v těchto případech nebývá nikdy výpočetního výkonu nazbyt. Využití GPU všude tam, kde je to rozumné, nejenže přináší podstatnou akceleraci zpracování, ale dokonce umožňuje realizovat takové algoritmy, které by jinak byly v akceptovatelném čase nerealizovatelné.

V programovém systému Control Web existují dva základní typy kamerových virtuálních přístrojů. Kromě základního přístroje camera existuje ještě přístroj gl_camera, který pro zpracování obrazových dat z kamery i jejich zobrazování používá vykreslovací stroj systému Control Web, který se vyznačuje architekturou klient-server a pracuje ve vlastním paralelním vláknu. Tento vykreslovací server mohutně využívá programovatelné GPU. V optimální situaci se tedy jedno jádro CPU stará o přípravu grafických dat a jejich transport do grafické paměti, kde jsou tato data masivně paralelně zpracována grafický procesorem. Takové řešení přináší výjimečně vysoký výkon při minimálním zatěžování vláken v reálném čase běžící aplikace. Zde je několik příkladů:

Pokročilá adaptivní interpolace barevné mozaiky

Podstatnou věcí ve prospěch kvality obrazu je možnost číst z barevných kamer syrová data a interpolovat barevnou mozaiku až v počítači a nikoliv již v kameře. Řada operací s obrazem je vzhledem k omezeným možnostem čipů kamerových řídicích jednotek velmi kompromisní. Kamera při interpolaci barevné mozaiky musí zůstat omezena na základní bilineární interpolaci, která je řešitelná celočíselnými výpočty. Obraz je pak zatížen všemi nežádoucími artefakty tohoto postupu, které plynou mimo jiného ze vzájemného prostorového posunu červeného a modrého barevného kanálu. Ve výsledku pak pozorujeme v blízkosti kontrastních hran šachovnicové vzory a modročervené lemování. Pokročilé algoritmy, které produkují výrazně čistší a ostřejší obraz, musí využívat výpočtů v plovoucí řádové čárce a obsahují více průchodů plochou obrazu. Takový algoritmus již není možno v reálném čase na proudu dat z kamery řešit ani pomocí vícejádrových CPU, je však příkladem ideální úlohy pro masivní paralelizaci v GPU. Virtuální přístroj gl_camera umožňuje volit mezi několika algoritmy interpolace barevné mozaiky.

Obr. 2 a obr. 3: Srovnání kvality bilineární ...

Obr. 2 a obr. 3: Srovnání kvality bilineární ...

... a adaptivní interpolace barevné mozaiky

... a adaptivní interpolace barevné mozaiky

Adaptivní interpolace je v CPU nerealizovatelná v reálném čase a použití jakéhokoliv, byť "zastaralého" GPU je velkým přínosem.

Korekce geometrických zkreslení obrazu

Programovatelná GPU umožňují velmi elegantně řešit problematiku změn geometrie obrazu, tzv. pixel displacement. Virtuální přístroj gl_camera tímto způsobem elegantně řeší nejen kalibraci geometrických zkreslení objektivů, ale dokáže např. i korigovat perspektivní zkreslení, odstranit natočení obrazu, rozvinout obraz z povrchu válce či koule. Umožňuje srovnat libovolně nelineárně deformovaný obraz.

Tato úloha je rozdělena na dva klíčové problémy: za prvé jak informaci o správných pozicích získat a zadruhé jak obraz kvalitně zpracovat v reálném čase bez neúnosné zátěže počítače.

Nejprve musíme získat obrazovou mapu, která popisuje změny pozic všech pixelů výsledného obrazu. Mapu získáme tak, že do zobrazovací roviny vložíme bodový rastr a systém si uloží kalibrační data pro daný objektiv a konfiguraci měření. Algoritmus měření mapy objektivy pracuje v CPU s přesností na setiny pixelu. Zde nám tolik nezáleží na rychlosti, tvorba mapy proběhne jen jednou, ale požadujeme nejvyšší přesnost.

Rychlost geometrických korekcí každého snímku z kamery je již kritická a tento algoritmus musí běžet v GPU. Ukazuje se, že kvalita hardwarových texturových filtrů a interpolátorů u námi vyzkoušených GPU není dostatečná pro kvalitu obrazu požadovanou pro tuto úlohu. Proto je tvorba výsledného obrazu řešena s vysokou subpixelovou přesností programem fragmentového shaderu, který poskytuje zaručeně kvalitní a stabilní výsledky na veškerých GPU.

Obr. 4: Znázornění obrazové mapy pro geometrickou kalibraci

Obr. 4: Znázornění obrazové mapy pro geometrickou kalibraci

Některé systémy strojového vidění se pokouší kalibraci geometrie obrazového pole řešit v CPU. Výsledky ale odpovídají tomu, že z důvodů šetření výpočetním výkonem musí být zavedena řada omezení a kompromisů. Často se používá po částech bilineární interpolace obrazové mapy a také filtrace obrazu nemůže být dostatečně kvalitní. Výsledkem je pak nespojitý schodovitý obraz.

Tato funkce je i prostředky nejvýkonnějších vícejádrových CPU realizovatelná jen problematicky a použití i slabšího zastaralého GPU je velkým přínosem.

Obrazové filtry

Obrazové filtry vypadají na první pohled jako optimální úlohy pro řešení v GPU. Často tomu tak je, ale nemusí to platit univerzálně. Potíž může být v tom, že řada jednoduchých kernelových filtrů nemá příliš vysokou výpočetní intenzitu (a současné vícejádrové CPU také nepočítají až tak zoufale pomalu). Režie přenosu obrazových dat mezi systémovou a grafickou pamětí pak může i stonásobně vyšší rychlost výpočtů kernelu v GPU oproti CPU znehodnotit.

Obr. 5: Rychlost i velmi komplexních GPU filtrů je omezena převážně režií přenosu dat

Obr. 5: Rychlost i velmi komplexních GPU filtrů je omezena převážně režií přenosu dat

Situace se ale dramaticky změní v případě filtrů s nutností složitějších výpočtů v plovoucí řádové čárce, jako je tomu např. u transformací barevných prostorů, řešení saturační matic, šumových filtrů atd. Pak nám může využití GPU zrychlit tyto kroky až o dva řády.

Obr. 6: Anisotropický šumový filtr využívá výkonu GPU ve výpočtech s plovoucí řádovou čárkou

Obr. 6: Anisotropický šumový filtr využívá výkonu GPU ve výpočtech s plovoucí řádovou čárkou

Jednoznačnou úlohou pro GPU jsou i takové filtry, kdy pro výpočet každého pixelu je nutno číst mnoho pixelů z jeho okolí – příkladem mohou být algoritmy lokálního prahování obrazu. Pak schopnost GPU načítat desítky gigapixelů za sekundu z textur je nenahraditelná. GPU řešení může být i několiksetkrát rychlejší než snaha o totéž v CPU.

Obr. 7: Lokálně prahovací filtr využívá mohutného datového toku GPU při čtení pixelů textur

Obr. 7: Lokálně prahovací filtr využívá mohutného datového toku GPU při čtení pixelů textur

Ve prospěch GPU se situace dále přiklání ve všech případech, kdy je nutno určitý filtr vícekrát opakovat. Tento požadavek je charakteristický např. u morfologických filtrů, které nejsou samy o sobě výpočetně příliš náročné, ale často potřebují desítky i stovky opakovaných běhů – příkladem může být např. hledání koster objektů nebo segmentace ploch kolem objektů. Obrazová data během opakovaných běhů filtru neopouští grafickou paměť a jsou stále rychle přístupná pro GPU. Pro tyto algoritmy je masivní paralelizace velkým přínosem.

Transformační kódování

Příkladem zde může výt dvojrozměrná Fourierova transformace - převod obrazu z prostorové (časové) do frekvenční domény (krok gpu_fast_fourier_transform_2D). Byť je zde použit algoritmus rychlé Fourierovy transformace (FFT), transformace obrazu je natolik výpočetně intenzivní, že v reálném čase není jinak než s využitím GPU realizovatelná. Zde již není možno použít starší GPU, potřebné jsou vektory vstupních textur i výstupních bufferů s plovoucí řádovou čárkou. Takže nemáme na výběr – bez moderního grafického procesoru to v tomto případě nejde.

Obr. 8: Dvourozměrná obrazová funkce ...

Obr. 8: Dvourozměrná obrazová funkce ...

Obr. 9: ... a její obraz ve frekvenční doméně

Obr. 9: ... a její obraz ve frekvenční doméně

GPU dokáže realizovat rychlou dvourozměrnou Fourierovu transformaci na proudu obrazových dat z kamery v reálném čase.

Další možnosti

Veškeré dosud uváděné příklady byly celkem jednoznačné. Existují však i problematické úlohy, kde přínosy GPU nemusejí být takto jasné.

Příkladem takové úlohy může být např. rozpoznávání vzorů realizované prostřednictvím GPU (krok gpu_match_monochrome v systému VisionLab). Během hledání obrazového vzoru musí systém mnohokrát provádět normalizovanou křížovou korelaci s velkým počtem pixelů. To vyžaduje mnohonásobně opakované výpočty středních jasů, směrodatných odchylek, odmocnin atd. – to vše s plovoucí řádovou čárkou. Navíc krok hledá i pootočené nebo zvětšené či zmenšené obrazy předloh. Veškeré výpočty tedy navíc podléhají lineárním transformacím. Toto všechno vypadá na první pohled jaké výborná úloha pro GPU. Je však zde závažná potíž – výpočetní intenzita algoritmu je natolik vysoká, že není hrubou silou rozumně proveditelný ani nejvýkonnějšími GPU. Podobně jako v algoritmech pro CPU, musí i zde nastoupit řada optimalizací. A právě v těchto optimalizacích, bez kterých ale problém tak jako tak řešit nelze, se skrývá kámen úrazu. Algoritmus je nutno rozdělit do více fází, mezi kterými musí probíhat výměna dat mezi GPU a CPU. Časové ztráty přináší jednak kopírování bloků dat, ale také to, že CPU i GPU musí na sebe vzájemně mezi jednotlivými fázemi čekat a nemohou běžet paralelně. Tento krok je tedy výhodné použít jen s moderními velmi výkonnými GPU – čas hledání může být až desetinásobně kratší než na vícejádrových CPU. S méně výkonnými grafickými procesoru se ale může situace obrátit a krok může být i pomalejší než obdobný realizovaný čistě v CPU. Autor aplikace tedy musí vše zvážit a prakticky vyzkoušet.

Obr. 10: Hledání vzorů realizované prostřednictvím GPU - tento příklad trvá asi 50ms na procesoru G80

Obr. 10: Hledání vzorů realizované prostřednictvím GPU - tento příklad trvá asi 50ms na procesoru G80

Obdobně, jako existují úlohy, pro které nelze použít masivně paralelní algoritmy v GPU, je zde i spousta úloh, které nelze efektivně řešit dokonce ani paralelními vlákny v CPU. Neexistuje zde jediný lék na všechno.

Pro každou aplikaci musí její autor zvolit nejlepší způsob řešení. A k tomuto rozhodování patří i to, kde využije mohutného potenciálu grafických procesorů.

Závěr

Systém strojového vidění VisionLab poskytuje krokům, které využívají GPU značný prostor. S vykreslovacím jádrem systému Control Web i virtuálním přístrojem gl_camera komunikují jen prostřednictvím velmi jednoduchého povelového rozhraní. Kroky dostanou k dispozici paměťový pixel buffer dané velikosti a formátu pixelů a mohou si zcela samostatně alokovat libovolné prostředky GPU – mohou si vytvářet např. vlastní texturové objekty, další frame buffer objekty, samozřejmě mohou načítat a spouštět vlastní shadery atd. Kroky strojového vidění tak mohou využívat veškerá nejnovější rozšíření, které přinášení aktuální grafické ovladače. Tyto možnosti umožňují systému strojového vidění VisionLab stále sledovat poslední vývoj technologií a přinášet tak svým uživatelům vysoký užitek a konkurenční výhodu.

rc

 
 | O společnosti | Produkty | Podpora | Stažení software | Stažení dokumentů | 
Moravské přístroje, a.s., Masarykova 1148, Zlín-Malenovice, 76302