Možnosti vývoje aplikací pro zpracování snímků DPZ

Ing. Stanislav Šumbera
Mendelova zemědělská a lesnická univerzita
Zemědělská 3
Brno, 60200
E - mail: ambrosa@mendelu.cz

Abstract

Paper introduces possibilities of software development for image processing. For user code programming it is necessary to select proper programming language, integrated development environment, basic raster system and software development kit for fundamental operations with image. It is necessary differentiate presentation level of application from logical and data one. Paper shows also example application architecture for image processing.

Abstrakt

Příspěvek seznamuje s možnostmi vývoje aplikací pro zpracování snímku. Pro vývoj uživatelských aplikací je nutné vybrat vhodný programovací jazyk, prostředí, resp. základní systém pro práci s rastry a s ním spojenou knihovnu funkcí, která poskytuje fundamentální operace se snímkem. Dále je vhodné koncipovat architekturu programu tak, aby byla minimálně prezentační vrstva aplikace oddělena od vrstvy logické a datové. Jednotlivé možnosti jsou v příspěvku nastíněny a v závěru je uveden také konkrétní příklad implementace uživatelské aplikace.

Úvod

Programy pro zpracování snímků často neposkytují v základní konfiguraci moduly pro realizaci speciálních operací. Tyto operace si uživatel většinou programuje pomocí maker, dostupných knihoven nebo si speciální modul musí dokoupit. Většina současných GIS softwarů poskytuje vývojové nástroje pro rozšiřování funkčnosti daného programu. Např. Arc-View disponuje jazykem AVENUE, MicroStation obsahuje MicroStation Development Language (MDL), Er-Mapper umožňuje vytváření uživatelského kódu v podobě DLL knihoven, Map Info lze programovat pomocí Map Basicu, apod. U programů zabývajících se zpracováním snímku (image processing) je situace obdobná. Chce-li operátor automatizovat libovolnou činnost, resp. je-li nutné vytvořit novou funkci, je potřeba tyto procedury naprogramovat. Z tohoto důvodu jsou často potřebné alespoň základní znalosti principů programování a schopnost programovat alespoň v jednom jazyce. Operace pro zpracování obrazu mohou být rozděleny do pěti fundamentálních tříd (ENGEL at al. 1999) :

1. Zvýrazňování - úprava obrazu - Image Enhancement :

2. Obnovení obrazu - Image Restoration

3. Analýza obrazu - Image Analysis

4. Komprese obrazu - Image Compression

5. Rekonstrukce obrazu - Image Reconstruction

Podle tohoto přístupu lze problém zpracování obrazu řešit od nejvyšší úrovně aplikace postupně k jednotlivým operacím a metodám. ENGEL at al.(1999) definují 4 primární úrovně zpracování obrazu. Tyto úrovně lze postavit do souvislosti s programovými prostředky dané aplikace:

Úroveň podle Engela

Odpovídající prostředek realizace

1. Aplikace

Uživatelské rozhraní

2. Fundamentální třídy

Makra

3. Operace

Skriptovací jazyky

4.Procesy (metody, funkce)

SDK, knihovny funkcí

Následující pasáž obsahuje přehled možností nejznámějších systémů pro zpracování obrazu z pohledu možností pro vývoj vlastních programů v podobě samostatných programů, nadstavbových nástrojů nebo maker a skriptů :

ERDAS IMAGINE 8.5:

ER MAPPER 6.2 :

IDRISI v32, r.2 :

TOPOL 2001 :

ENVI :

PCI :

IMAGE ANALYST:

Operace a uživatelsky konkrétní metody pro zpracování obrazu jsou většinou příliš nákladné pro zakoupení. Vždy může navíc vzniknout situace, že daný problém nebude řešen v žádném softwaru, resp. nebudou k dispozici potřebné funkce a bude nutné tuto funkčnost doprogramovat. Dalším problémem je vyhraněnost řešení daného programu pro daný systém. V případě jednoduchých maker resp. skriptů je tato skutečnost nepodstatná, protože se jedná o kustomizaci v daném systému. Pokud se ovšem programuje v některém z programovacích jazyků a využívá se aplikačního programového rozhraní, ať už v podobě DLL knihoven nebo OLE/COM objektů, a řešení daného problému by mělo být obecné a široce využitelné, je nutné zhodnotit nezávislost vyvíjené aplikace, popřípadě konečnou cenu za řešení daného problému. Pokud samotná aplikace má hodnotu řádově tisíce korun nebo je dokonce zdarma, ale je nutné dokoupit systém pro zpracování rastru, ve kterém aplikace může běžet za řádově desetitisíce korun je zřejmé, že potenciální využití aplikace bude menší. Vždy je nutné zhodnotit rychlost vývoje, použitý programovací jazyk, rozšiřitelnost řešení, přenositelnost, závislost na externích modulech, cenu a míru zobecnění řešení problému v implementaci softwaru.

Jedním z nejlepších konceptů rozšiřitelnosti software podává produkt Er-mapper. Tento software dokonce dodává zdrojové kódy k některým funkcím a run-time (tj. knihovnu funkcí) je možno volně distribuovat. Tímto způsobem je zaručeno, že jakákoli aplikace využívající funkce Er Mapperu bude v zásadě spustitelná i na počítači, který nemá instalovaný tento produkt. Strategie tohoto řešení podněcuje vývojáře k tvorbě aplikací nad touto knihovnou, neboť zisky z jejich aplikací budou maximální a přitom přijatelné, protože cena je stanovena pouze za danou funkčnost jejich aplikace (vývojáři nebudou muset platit za knihovnu funkcí a uživatelé za run-time prostředí). Naopak vývojové nástroje např. pro Erdas Imagine je nutné dokoupit.

Jednotlivé programovací nástroje výše uvedené jsou zaměřeny pro využití určitou skupinou uživatelů, resp. pro určité role uživatele daného systému, jak uvádí následující přehled :

Nástroj

Konfigurace

Makro

Skriptovací jazyk

SDK knihovny

Role

Administrátor

Uživatel

Pokročilý uživatel

Programátor

Popis jednotlivých rolí :

Různé možnosti systému pro zpracování snímků umožňují vyvíjet vlastní programy v některém z běžných jazyků. Vždy je nutné brát zřetel na možnosti a omezení daného programovacího jazyka pro vývoj funkcí na zpracování snímku DPZ. Následující přehled tyto vlastnosti uvádí. Přehled je sestaven podle vlastních zkušeností s vývojem, efektivitou a rychlostí programování v daném jazyce.

Vývoj aplikace pro zpracování rastru lze rozdělit do třech logických vrstev podle účelu programu. Realizace těchto vrstev v aplikaci odpovídá možnostem a přizpůsobení jednotlivých programovacích jazyků, jak zobrazuje obr.1.

Obr. 1. Relace mezi vrstvami aplikace a programovacími jazyky. Legenda:WFC - Windows Foundation Classes, MFC - Microsoft Foundation Classes , VB - Visual Basic, ASM - assembler.

Z obrázku je patrné, že jedna z nejdůležitějších a klíčových vlastností každé aplikace je komunikační rozhraní (API). Dále je zřejmé, že pro danou úroveň aplikace je pro rychlost a efektivitu programování nejvhodnější využít příslušný programovací jazyk, resp. knihovny. Např. pro uživatelské rozhraní je vhodné využít jazyk Visual Basic, zatímco pro výkonnou část aplikace jazyk C/C++. Zde ovšem vyvstává důležitá otázka - jak komunikovat mezi rozdílnými "světy" programovacích jazyků (např. C++ a VisualBasic, Java a C++, komunikace mezi procesy apod.). Je-li zvládnuta technologie komunikace mezi programovými moduly, lze snadno aplikaci rozčlenit podle výše uvedených vrstev a programovat příslušnou část v nejvhodnějším programovacím jazyku. Proto bude v následujících kapitolách tomuto problému věnována patřičná pozornost.

Technologie .NET

Pro úplnost je nutné zmínit řešení výše uvedeného problému pomocí nejnovější technologie s názvem .NET (v současné době existuje 2. beta verze). Pro .NET platformu jsou všechny jazyky a jejich možnosti rovnocenné. .NET platforma umožňuje vyvíjet aplikace v libovolném jazyce (C#, Visual C++ .NET, Visual Basic.NET apod.) přičemž jednotlivé jazyky mohou mezi sebou libovolně komunikovat - to je zajištěno společným jmenovatelem těchto jazyků (IL) . Při kompilaci se zdrojový kód kompiluje do tzv. IL - Intermediate Language spolu s metadaty kódu (závislosti na knihovnách) - tyto produkty jsou označovány jako "assembly". IL je nezávislý na instrukcích procesoru a tím umožňuje platformovou a hardwarovou nezávislost kódu, který je závislý pouze na přítomnosti run-time modulu .NET. IL jazyk je zpracován pomocí "Common Language Runtime", který přeloží IL jazyk do nativního kódu pro daný procesor při prvním spuštění aplikace. Překladač ovšem nepřekládá celý kód, ale pouze tu část (třídu), která je právě vykonávaná. Navíc umožňuje optimalizovat kód s ohledem na právě přítomný procesor, stav operačního sytému a pod. (označováno jako JIT - just in time compiler) (RICHTER 2000). Prostředí .NET tímto kombinuje pozitivní znaky z jednotlivých programovacích jazyků a umožňuje volit programátorovi jemu nejbližší techniku programování a poskytuje snadnou komunikaci mezi programovacími jazyky.

Příklad vývoje uživatelské aplikace pro zpracování snímků z DPZ

Jako příklad pro vývoj aplikace na výše uvedených principech je zde uveden nekomerční program "Kernel Processor". Základní funkcí programu je zpracování posloupnosti tzv. uživatelský kódů, konvolucí a modulů. Aplikace je napsaná pro platformu operačního systému Win32. a je nezávislá na přítomnosti určitého softwarového programu pro zpracování rastrů. Vstupně/výstupní operace pracují s následujícími formáty rastrových souborů: BMP - typ RGB, 24 bitů/pixel, TIFF - typ RGB, 24 bitů/pixel a 64 bitů/pixel, RST - typ RGB 24bitů/pixel a 32bitů/pixel (formát pro IDRISI). Výkonná část kódu je zajištěna uživatelským kódem v podobě DLL knihovny, ve které je obsažena implementace daného problému. Tento uživatelský kód je kompatibilní s uživatelským kódem využívaným produktem Er-mapper. Aplikaci lze spustit ve dvou módech : jako konzolovou aplikaci z příkazové řádky nebo jako aplikaci s uživatelským rozhraním. Uživatelské rozhraní umožňuje export pixelů z rastru do Excelu a umožňuje rastr zobrazovat.

Architektura software

Program byl navržen tak, aby bylo maximálně využito potenciálu dostupných programovacích jazyků, technologií a rychlosti zpracování. Obr 2. uvádí přehled jednotlivých části aplikace.

Obr.2. Architektura příkladové aplikace

Datová vrstva: Na této vrstvě se realizují vstupně/výstupní operace pro formáty BMP, TIFF a RST. Pro formát TIFF byla využita již napsaná knihovna libgeotiff.lib.Pro formát BMP a RST byla napsána speciální knihovna BMP.DLL v jazyku C.

Logická vrstva: Na této vrstvě se implementují hlavní procesy aplikace. Především je to řízení toku programu a zpracování uživatelského kódu. Hlavní tok programu uskutečňuje obecnou operaci konvoluce:

kde I(x,y) je obraz nad kterým probíhá konvoluce a h(x,y) je tzv. konvoluční jádro (kernel) o rozměru 2*k+1 x 2*k+1 pixelů. Konvoluční jádro je funkce, kterou definuje uživatel. Kernel processor umožňuje tři typu této funkce: uživatelská funkce, uživatelský modul a konvoluce pomocí maticer pixelů.

Uživatelská funkce pro rotující okno :

Uživatelská funkce musí obsahovat následující parametry:

_declspec(dllexport)
double nazev_funkce /*<= hodnota pixelu */
(
int nr_rows, /*=> počet řádků rotujícího okna */
int nr_cols, /*=> počet sloupců rotujícího okna */
double **array /*=> 2D matice aktuální pozice rotujícího okna */
)

Klauzule _declspec(dllexport) zajistí, že se funkce z DLL knihoven exportují a tedy budou k dispozici pro jádro aplikace Kernel Processor. Pokud je nutné provést inicializaci před vlastním procesem rotujícího okna, lze vytvořit stejnojmennou funkci s příponou _init. Parametry funkce jsou následující :

_declspec(dllexport)
double nazev_funkce_init
(
int nr_rows, /*=> počet řádků rotujícího okna */
int nr_cols, /*=> počet sloupců rotujícího okna */
char *params /*=> vstupní parametry */
)

resp. po ukončení procesu rotujícího okna, lze příponou _final stanovit funkci, která se zde zavolá:

_declspec(dllexport)
void nazev_funkce_final(void)

Uživatelský modul pro celý snímek

Pokud je nutné provést operaci nad celým snímkem, je možné vytvořit funkci, jejíž argumenty jsou vstupní, výstupní soubor a vstupní parametry. Parametr Callback umožňuje zavolat funkci z jádra aplikace, která registruje v procentech průběh zpracování snímku (např. při časově náročných operací):

_declspec(dllexport)
double název_funkce
(
char *Name1, /* => Vstupní soubor */
char *Name2, /* => Vystupní soubor */
char *params, /* => Vstupní parametry */
void (*cbAddPart) (void) /* ==> Callback funkce */
)

Konvoluce

Operace konvoluce se specifikuje maticí konvoluční masky přímo v textovém souboru .ker (viz dále).

Pro kompilaci do DLL knihovny je nutné, aby kód obsahoval vstupní hlavní funkci pro načtení knihovny:

BOOL APIENTRY DllMain( HANDLE hModule, DWORD reason, LPVOID reserved )
return TRUE;

Všechny tři typu uživatelského kódu se specifikují v textovém meta souboru, který definuje velikost rotujícího okna, knihovnu a funkci. Tento soubor je shodný s kernel soubory používanými v Er-mapperu :

Kernel Begin

   
 

Description

= "Odstraňuje duplicitní pixely "

 

Type

= User

 

Rows

= 3

 

Columns

= 3

 

UserCodeFileName

= "KPproc.dll"

 

UserFunctionName

= "tree_top "

 

InterfaceType

= C

Kernel End

   

V tomto souboru je velikost rotujícího okna 3x3 pixelů, a pro každou pozici se provede funkce tree_top definovaná v modulu KProc.dll.

Uživatelská vrstva :

Tato vrstva je napsaná ve Visual Basicu a komunikuje s jádrem aplikace prostřednictvím následujícího API :

Kernel operace

CONV_SetKernel

přidá kernel do procesu rotujícího okna

CONV_processKernels

spustí proces rotujícího okna

CONV_freeKernel

vypustí kernely z procesu

Operace nad pixely

CONV_openPixel

inicializuje čtení pixelů

CONV_closePixel

ukončí čtení pixelů

CONV_getPixel

funkce vrátí pixel na dané souřadnici

CONV_getFreq

funkce vrátí histogram snímku

Technologie komunikace mezi Visual Basicem a DLL knihovnou je zobrazena na obr. 3

Obr 3. Technologie komunikace mezi Visual Basicem a DLL knihovnou 1. deklarace importované funkce z Kpdll.DLL (knihovna Kernel processoru), 2.přístup na deklarovanu funkci se zadáním callback funkce. 3 Vyvolání callback funkce.

Důležitou částí uživatelského rozhraní je možnost komunikace s tabulkovým procesorem - Excel. To je umožněno prostřednictvím technologie OLE automation (Object Linking and Embeding). Visual Basic je v tomto ohledu nejsnáze použitelný jazyk pro využívání této technologie. Následující kód tuto skutečnost demonstruje na příkladu zápisu hodnoty pixelu do daného řádku a sloupce tabulky Excelu. :

Dim ExcelObj As Object
Set ExcelObj = GetObject(NazevExcel_souboru, "Excel.Sheet")

ExcelObj.Application.ActiveSheet.Cells(radek,sloupec)
= getPixel(y,x,kanal)

Postup práce s aplikací Kernel processor:

1. Stanoví se vstupní soubor

2. Stanoví se název výstupního souboru

3. Definuje se algoritmus prostřednictvím posloupnosti kernelových souborů

4. Spustí se proces rotujícího okna

5. Pixely se exportují do Excelu

6. Výsledný snímek se zobrazí

Obr . 4. Postup práce s Kernel Procesorem a realizace postupu v uživatelském rozhraní

Závěr

Příspěvek si kladl za cíl seznámit běžné uživatele systémů pro zpracování snímků na možnosti jejich rozšíření pomocí programování uživatelských aplikací. Na příkladu aplikace Kernel Processor je demonstrována jednoduchost vytvoření samostatné aplikace pro zpracování snímku formou rotujícího okna a na něm definovaných funkcí a dále možnost kombinace různých prostředí programovacích jazyků (C/Visual Basic) pro rychlý vývoj jak uživatelského rozhraní, tak výkonné části softwaru.

Literatura

  1. ENGEL,A., ZUMBRUNN,R.,MUELLER, D.,STAHLBERG, H., 1999. Digitale Bildverarbeitung in Naturwissenschaften und Medizin. Maurice E. Müller Institut Biozentrum der Universität Basel. Skriptum www.mih.unibas.ch
  2. ERDAS Imagine, 2001. White Paper IMAGINE Developer't Toolkit.
  3. GENAWAREHOUSE , 2000. An Architectural Guide to RasDB Common Raster Data Storage and Access Issue and the RasDB Solution, Whitepaper Series
  4. PCI GEOMATICS, 2001. Geomatica Prime Technical Specificaitons.
  5. RESEARCH SYSTEMS, 2000. W hat's new in IDL 5.4.
  6. RICHTER, J., 2000. Microsoft .NET Framework Delivers the Platform for Integrated Service-Oriented Web. In: MSDN magazine. Vol.15, No.9. 2000, p 60-69.