• No results found

Realtidsvideobehandling för användning i labbkurser - en fältundersökning

N/A
N/A
Protected

Academic year: 2021

Share "Realtidsvideobehandling för användning i labbkurser - en fältundersökning"

Copied!
67
0
0

Loading.... (view fulltext now)

Full text

(1)

Examensarbete

LITH-ITN-MT-EX--07/027--SE

Realtidsvideobehandling för

användning i labbkurser - en

fältundersökning

Olof Jonsson

2007-05-24

(2)

LITH-ITN-MT-EX--07/027--SE

Realtidsvideobehandling för

användning i labbkurser - en

fältundersökning

Examensarbete utfört i medieteknik

vid Linköpings Tekniska Högskola, Campus

Norrköping

Olof Jonsson

Handledare Stefan Gustavson

Examinator Stefan Gustavson

(3)

Rapporttyp Report category Examensarbete B-uppsats C-uppsats D-uppsats _ ________________ Språk Language Svenska/Swedish Engelska/English _ ________________ Titel Title Författare Author Sammanfattning Abstract ISBN _____________________________________________________ ISRN _________________________________________________________________

Serietitel och serienummer ISSN

Title of series, numbering ___________________________________

Nyckelord

Keyword

Datum

Date

URL för elektronisk version

Avdelning, Institution

Division, Department

Institutionen för teknik och naturvetenskap Department of Science and Technology

2007-05-24

x

x

LITH-ITN-MT-EX--07/027--SE

Realtidsvideobehandling för användning i labbkurser - en fältundersökning

Olof Jonsson

I min rapport presenterar jag en fältundersökning för att hitta olika lösningar för att behandla

realtidsvideo. De programmeringsgränssnitt som det främst riktar sig till är Matlab och Java. Rapporten är tänkt att ge vägledning och fungera som en guide för dem som önskar arbeta med enklare former av realtidsbehandling av video. Jag kommer dels att gå igenom rena Matlab- och javalösningar och dels visa hur olika tekniker kan kombineras för att åstadkomma ytterligare tekniker för att behandla realtidsvideo.

För full förståelse av rapportens alla delar rekommenderas att läsaren har grundläggande kunskaper om programmering i Matlab och Java.

(4)

Upphovsrätt

Detta dokument hålls tillgängligt på Internet – eller dess framtida ersättare –

under en längre tid från publiceringsdatum under förutsättning att inga

extra-ordinära omständigheter uppstår.

Tillgång till dokumentet innebär tillstånd för var och en att läsa, ladda ner,

skriva ut enstaka kopior för enskilt bruk och att använda det oförändrat för

ickekommersiell forskning och för undervisning. Överföring av upphovsrätten

vid en senare tidpunkt kan inte upphäva detta tillstånd. All annan användning av

dokumentet kräver upphovsmannens medgivande. För att garantera äktheten,

säkerheten och tillgängligheten finns det lösningar av teknisk och administrativ

art.

Upphovsmannens ideella rätt innefattar rätt att bli nämnd som upphovsman i

den omfattning som god sed kräver vid användning av dokumentet på ovan

beskrivna sätt samt skydd mot att dokumentet ändras eller presenteras i sådan

form eller i sådant sammanhang som är kränkande för upphovsmannens litterära

eller konstnärliga anseende eller egenart.

För ytterligare information om Linköping University Electronic Press se

förlagets hemsida

http://www.ep.liu.se/

Copyright

The publishers will keep this document online on the Internet - or its possible

replacement - for a considerable time from the date of publication barring

exceptional circumstances.

The online availability of the document implies a permanent permission for

anyone to read, to download, to print out single copies for your own use and to

use it unchanged for any non-commercial research and educational purpose.

Subsequent transfers of copyright cannot revoke this permission. All other uses

of the document are conditional on the consent of the copyright owner. The

publisher has taken technical and administrative measures to assure authenticity,

security and accessibility.

According to intellectual property law the author has the right to be

mentioned when his/her work is accessed as described above and to be protected

against infringement.

For additional information about the Linköping University Electronic Press

and its procedures for publication and for assurance of document integrity,

please refer to its WWW home page:

http://www.ep.liu.se/

(5)

Sammanfattning

I min rapport presenterar jag en fältundersökning för att hitta olika lösningar för att behandla realtidsvideo. De programmeringsgränssnitt som det främst riktar sig till är Matlab och Java. Rapporten är tänkt att ge vägledning och fungera som en guide för dem som önskar arbeta med enklare former av realtidsbehandling av video. Jag kommer dels att gå igenom rena Matlab- och javalösningar och dels visa hur olika tekniker kan kombineras för att åstadkomma ytterligare tekniker för att behandla realtidsvideo. För full förståelse av rapportens alla delar rekommenderas att läsaren har grundläggande kunskaper om programmering i Matlab och Java.

Abstract

In my report, I present a field survey to find different solutions for processing real time video. The programming interfaces mainly targeted are Matlab and Java. This report is meant to give guidance for those who wish to work with simpler forms of real time video processing. I will go through pure Matlab and Java solutions as well as show how

different techniques can be mixed in order to produce further techniques for real time video processing.

For full comprehension of the report it is recommended that the reader has basic knowledge in programming in Matlab and Java.

(6)

Innehållsförteckning

1. Inledning ... 1

2. Angående mina praktiska tester ... 2

2.1 Hårdvarufakta ... 2

2.2 Mjukvarufakta ... 2

2.3 Ett par ord om kvalitet och prestanda ... 3

2.4 Viktiga faktorer vid behandling av realtidsvideo... 3

3. Arbetsgång ... 6

4. Video for Windows och DirectShow... 7

5. Image Acquisition Toolbox... 8

5.1 Grundläggande beskrivning av Image Acquisition Toolbox... 8

5.2 Kodgenomgång av Image Acquisition Toolbox ... 9

5.2.1 Imacqdemo.m ...9

6. JMF (Java Media Framework) ... 12

6.1 Bildbehandling i realtid i Java med hjälp av JMF... 12

6.2 Kodgenomgång av JMF... 13

6.2.1 TestEffect.java...13

6.2.2 BallFinder.java ...17

6.3 Legoroboten, JMF och iCommand... 20

6.4 Kodgenomgång av iCommand ... 23 6.4.1 BallFinder.java ...23 7. RoboRealm ... 24 8. Hybridlösningar ... 25 8.1 Testade lösningar... 25 8.1.1 Matlab/JMF...25 8.1.2 Roborealm/Java...25 8.1.3 C-plugin i Matlab...25 8.2 Otestade lösningar ... 26 8.2.1 Matlab/RoboRealm ...26

8.2.2 C-plugin till Java...27

9. Andra plattformar... 28

9.1 Linux... 28

9.2 Mac OS X ... 28

(7)

10.2 Slutsats ... 30

10.3 För- och nackdelar gällande hybridlösningarna ... 30

11. Källförteckning ... 32

12. Appendix ... 33

A. Ordförklaringar och förkortningar B. TestEffect.java C. BallFinder.java D. imacqdemo.m E. display_frame.m F. display_frame2.m G. free_mem.m

(8)

1. Inledning

Jag har i mitt examensarbete undersökt olika möjligheter att behandla livevideo i realtid på diverse olika sätt. Resultatet är tänkt att vara Linköpings Tekniska Högskola (LiTH) behjälpligt vid planering av kurser/kurslaborationer där behandling av bilder i realtid kan tänkas vara ett moment. Det bör observeras att min rapport gäller den tidsperiod då jag gjort mitt examensarbete och endast är avsett att ge en bild av hur alternativen och möjligheterna för det jag undersökt såg ut just då. Detta är ett område där förändringar kan ske snabbt, varför rapportens resultatdel och mina slutsatser inte kan garanteras ge de bästa lösningarna och svaren efter examensarbetets slutdatum.

Mina praktiska undersökningar har endast ägt rum på Windows-plattformen. Jag har dock även tittat lite på andra plattformar för att se vad det kan finnas för alternativ till

Windows och vilka för- och nackdelar dessa lösningar i så fall kan ha.

För att kunna göra en så grundlig fältundersökning som möjligt har det känts viktigt att veta vad LiTH verkligen är intresserade av och skulle kunna behöva. Jag har därför haft två ”kunder” för att se om deras behov kunnat tillgodoses. I det första fallet har jag tittat på hur en bildbehandlingskurs, som använder sig av Matlab för att behandla bilder, kunnat utvecklas till att även innefatta behandling av realtidsvideo. I det andra fallet har jag tittat på Ivan Rankins1 kurs Datamodeller för kognitiva processer för att se hur bildbehandling i det här fallet kan användas till att ge en robot möjlighet att fatta olika beslut utifrån behandlade bilder.

Under arbetet har det stått mig relativt fritt att själv hitta lämpliga exempel på tillämpningar för att testa lösningarna. Vad gäller bildbehandlingen i Matlab har jag använt en del tekniker och algoritmer som används i kursen Bildanalys och

Bildbehandling och försökt applicera dem på bilder i realtid. Gällande robotdelen

diskuterade jag möjliga tillämpningar med Ivan Rankin. Vi kom fram till att sökning och klassificering av objekt i en bild kunde vara intressant att prova.

Den som läser min rapport bör vara insatt i åtminstone grundläggande Matlab- och javaprogrammering för att få fullt utbyte av rapportens mer tekniska delar.

(9)

2. Angående mina praktiska tester

2.1 Hårdvarufakta

Jag har utfört mina tester på två olika maskiner. Maskin 1 är en HP med en AMD Sempron 3200+ processor på 1,79 GHz och 448 MB RAM. Maskin 2 har två Intel Pentium 4 processorer på 3,20 GHz och 1 GB RAM.

Webbkameran jag använt är en Next, maxupplösning 640x480 pixlar, inköpt på Claes Ohlson för 300 kr. Ingen proffskamera med andra ord, men den duger gott för enklare tester.

Den trådlösa kameran jag använt har en maxupplösning på 720x576 pixlar. Kameran sänder till en mottagare som tar emot videosignalen och skickar den vidare analogt. Den analoga signalen tas emot av en digitaliseringsadapter (Kjell&Company, 700 kr) som omvandlar den analoga signalen till en digital signal och för över den till datorn via USB. Roboten som använts för praktiska tester till vissa möjliga framtida kurslabbar är en Lego Mindstorms NXT som tar emot styrkommandon från datorn via Bluetooth. Robotens specifikationer är följande enligt Legos hemsida [1]:

Technical specifications

• 32-bit ARM7 microcontroller • 256 Kbytes FLASH, 64 Kbytes RAM • 8-bit AVR microcontroller

• 4 Kbytes FLASH, 512 Byte RAM

• Bluetooth wireless communication (Bluetooth Class II V2.0 compliant) • USB full speed port (12 Mbit/s)

• 4 input ports, 6-wire cable digital platform (One port includes a IEC 61158 Type 4/EN 50 170 compliant expansion port for future use)

• 3 output ports, 6-wire cable digital platform • 100 x 64 pixel LCD graphical display

• Loudspeaker - 8 kHz sound quality. Sound channel with 8-bit resolution and 2-16 KHz sample rate.

• Power source: 6 AA batteries

2.2 Mjukvarufakta

• Båda maskinerna jag använt kör Windows XP SP 2.

• Versionen av Matlab är R2006b och Image Acquisition Toolbox version 2.0. • Versionen av Java är 1.5.0 och JMF (Java Media Framework) version 2.1.1e • iCommand, ett Java-API som används för styrning av Legos robot, är version 0.5.

(10)

2.3 Ett par ord om kvalitet och prestanda

Målet med mitt examensarbete har ju varit att hitta tillfredsställande lösningar för att kunna behandla video i realtid, dels i Matlab och dels i Java eftersom Java visat sig vara en bra plattform för robottillämpningar.

De tillämpningar jag testat har varit relativt enkla och har inte krävt en speciellt hög upplösning på bilderna. För de flesta testerna har jag använt en upplösning på 640x480 pixlar och aldrig använt mig av högre upplösningar än så. Webbkameran jag använt var ju också begränsad till just 640x480 pixlar.

Med realtid menas i huvudsak att det som sker framför kameran ska dyka upp direkt på skärmen utan någon, eller möjligen med en ytterst liten, fördröjning [2]. Ingen av lösningarna når riktigt upp till detta, speciellt efter att bilden genomgått någon form av behandling. En fördröjning av bilden på upp till en sekund är därför ganska vanligt förekommande. För att inte krångla till det har jag dock ändå valt att använda mig av termen realtid då det för de flesta enklare tillämpningar antagligen ändå inte spelar någon roll om det är en kort fördröjning på bilden.

2.4 Viktiga faktorer vid behandling av realtidsvideo

Vad är viktigt att ta hänsyn till vid behandling av realtidsvideo? Det finns ett antal faktorer som har stor inverkan på slutresultatet.

Bildkvalitet

En alltför grynig, mörk eller på annat sätt undermålig bild gör det ytterst svårt att få ett önskat resultat. En klar rekommendation är att i största möjliga mån använda sig av en digital bildkälla, såsom exempelvis en webbkamera, då (billiga) analoga bildkällor oftare ger upphov till oönskade störningar i bilden. Bilderna nedan visar på skillnaderna mellan de båda kamerorna. Den analoga bilden är mörkare och har en tendens att ge falska resultat vid tillämpningar då det analoga bruset bl.a. medför missfärgningar av bilden. Den digitala bilden är som synes klarare och skarpare, speciellt i förgrunden där fokus ligger.

(11)

Figur 1. Bild tagen med den trådlösa analoga kameran

(12)

Bildens upplösning

Det som bör tas hänsyn till när det gäller upplösning är att den bör vara tillräckligt god för att önskad process ska kunna utföras på bilden. Vissa applikationer kan kräva högre detaljrikedom än andra. I mina egna tester har jag inte använt någon högre upplösning än 640x480 pixlar.

Ljus

Ljuset i rummet har stor inverkan på resultatet av bildbehandlingen. En för mörk bild där viktiga detaljer som färger och former är svåra att urskilja innebär en betydligt mindre chans att uppnå önskat resultat. Självklart kan olika kameror kräva olika mycket ljus men det bör ändå tas hänsyn till att en kamera inte har samma förmåga till mörkerseende som vi människor, varför ett dåligt upplyst rum kan ge ett riktigt dåligt resultat.

(13)

3. Arbetsgång

Till en början var mitt examensarbete tänkt att ha en något annorlunda inriktning än vad det slutligen fick. Jag skulle skriva en plugin till Matlab som skulle göra det möjligt att ta in och behandla realtidsvideo. Senare skulle jag möjligen också hitta en liknande lösning för Java. När det väl var dags att sätta igång visade det sig att Image Acquisition Toolbox precis installerats för Matlab, om än i endast två licenser som delas av hela universitetet. Alltså kunde en färdig lösning kanske redan finnas. Detta gjorde att jag till en början, när jag väl fått tag på en webbkamera och en dator, fick sätta igång att utvärdera Image Acquisition Toolbox.

Då jag frågade olika personer på skolan om mitt arbete kunde vara av något intresse för dem kom jag genom Ivan Rankin och Ole Pedersen2 också in på robotspåret i mitt arbete. När jag väl testat och hunnit utvärdera Image Acquisition Toolbox satte jag igång att hitta en fungerande lösning för Java, som kunde tänkas vara ett lämpligt val för bildhantering i robottillämpningarna. Tekniken jag testade, JMF, hade jag till en början problem med att installera. Efterforskningar på Internet visade att även andra haft problem med

installationen, men ingen av lösningarna som presenterades fungerade för mig. Så småningom löste det sig dock och jag kunde börja arbeta med JMF. Jag upptäckte att det var ganska svårt att hitta bra exempel på hur JMF kunde användas till att göra det jag önskade. Jag gjorde ganska många olika försök innan jag hittade en bra lösning, och det är den lösningen jag valt att presentera i den här rapporten.

När det gällde robotdelen gällde det att hitta ett sätt att med hjälp av javakod kunna styra den typ av robot jag använde. När jag väl hittat den lösning för realtidsvideobehandling i Java jag letat efter fanns det först inget lämpligt alternativ för att kunna styra roboten. iCommand fanns till en början bara i en version som inte riktigt uppfyllde de krav de tänkta tillämpningarna ställde. Efter ett tag kom som tur var iCommand i en nyare version, och jag kunde sätta igång att arbeta med roboten. Snart hade jag lärt mig de viktigaste funktionerna i iCommand och jag kunde sätta ihop iCommand med JMF för att åstadkomma den plattform som var lämplig för robottillämpningarna.

(14)

4. Video for Windows och DirectShow

Video for Windows (VfW) är ett system som gör det möjligt att spela upp digital video i Windows. VfW kom 1992 som ett svar på Apples QuickTime-teknologi på Macintosh-plattformen. Det släpptes först som ett gratis tillägg till Windows 3.1 och 3.11 för att senare bli en fast del av Windows 95. I och med VfW introducerades även filformatet AVI (Audio Video Interleaved) för att kunna lagra digital video. VfW inkluderade också ett programmeringsgränssnitt, vilket gör det möjligt för utvecklare att använda sig av video i sina program, samt en rad program som t.ex. Media Player.

I juli 1996 ersattes VfW till största delen av ActiveMovie. ActiveMovie bytte sedan namn till DirectShow och är det system som används idag.

Från början var VfW begränsat till en upplösning på 320x240 pixlar samt en framerate på 30 fps.

(15)

5. Image Acquisition Toolbox

5.1 Grundläggande beskrivning av Image Acquisition Toolbox

Image Acquisition Toolbox (IAT) gör det möjligt att hämta in bilder i Matlab från i princip valfri källa (webbkameror, FireWire-kameror, Framegrabbing-kort...).

Många av IAT:s toolboxfunktioner är m-filer. Det går även att skriva egna m-filer för att utöka IAT:s funktioner. IAT kan självklart också kombineras med andra toolboxes (Image Processing, Data Acquisition...)

För att avgöra vilka kopplingar som finns mellan Matlab och tillgängliga bildkällor körs kommandot imaqhwinfo. Med detta kommando fås sedan också info angående vilka enheter som är tillgängliga genom de olika kopplingarna. Toolboxen använder två typer av objekt för att representera anslutningen till en bildkälla:

- Video input objects - Video source objects

Video input objects representerar kopplingen mellan Matlab och en bildkälla. IAT är objektorienterat, och det första som görs sedan bildkällan hittats är att skapa ett video input object. (Se genomgången av m-filerna för mer detaljerade beskrivningar hur allt går till). Ett video input object kan skapas med olika inställningar för färgformat/upplösning beroende på vad som är möjligt för aktuell kamera (eller annan bildkälla). När ett video input object skapas, skapar toolboxen automatiskt ett eller flera video source objects associerat med aktuellt video input object. Antalet video source objekt som skapas beror på enheten och videoformatet som specifierats. Endast ett av video source-objekten kan vara aktivt vid ett och samma tillfälle. Detta är källan som används för inhämtningen av bilder.

För att ett video input object ska börja samla in bilder måste det först startas och sedan triggas. Videoinputobjektet startas genom start-funktionen. start förbereder objektet för bildinsamling, t.ex. låser vissa värden så att de blir read-only. Den startar dock inte själva insamlingen, för det behövs en trigger. Triggertypen beror på hur parametern

TriggerType är konfigurerad och kan vara manuell, automatisk eller styrd av hårdvara. Är

triggern automatisk startar insamlingen när videoinputobjektet startar. Annars kan triggern ske exempelvis efter att en viss tid förflutit. Inhämtade bilder kan sedan

importeras till workspace som en bildsekvens. stop behöver kallas på om insamlingen är kontinuerlig.

Inbyggda funktioner finns för att kunna se på och behandla bilder i form av en

livevideoström i realtid. För att visa och behandla bilder i realtid finns främst två olika möjligheter.

(16)

Metod 1: Använda den inbyggda preview-funktionen, preview(vid). I en m-fil skapas ett

Matlab-fönster och bestämmer att preview-funktionen ska köras i detta fönster. För varje ny frame som visas kallas en funktion på. Denna funktion skrivs i en separat m-fil och fungerar så att den först extraherar bilddatan ur ett bildobjekt, utför en funktion på den, och sätter tillbaka bilddatan. Fördelen med denna metod är att mycket optimerad kod används i form av preview-funktionen som gör att det flyter på ganska bra. Nackdelen är att inte ha full kontroll över vad som händer i och med att en ganska komplex inbyggd funktion används.

Metod 2: Visa bilderna snabbt efter varandra genom att hela tiden uppdatera ett

imshowfönster. Detta görs genom att använda sig av s.k. callback-funktioner. Callback-funktioner utförs vid vissa händelser, som att ett videoobjekt startat, att en frame precis hämtats in o.s.v. Det som händer i detta fall är alltså att en bild i taget visas upp och en funktion utförs på bilden. Fördelen med denna metod är att full kontroll uppnås över vad som händer och hur bilden visas, till skillnad från när preview-funktionen används. Bilddatan kan fås direkt genom exempelvis funktionen peekdata och behöver inte hämtas ur ett annat objekt som i metod 1. Nackdelen med den här metoden är att datorn kan få svårt att hinna med att hämta och visa alla bilder från minnesbufferten.

5.2 Kodgenomgång av Image Acquisition Toolbox

5.2.1 Imacqdemo.m

Det här är huvudfilen som de två olika metoderna för att visa och behandla livevideo i Matlab kan anropas. Här visas de mest grundläggande funktionerna i Image Acquisition Toolbox som behövs för att visa video i realtid. För fullständig kod (d.v.s. de övriga m-filerna som används/anropas) hänvisas till appendix.

(17)

Här hämtas information om de tillgängliga enheter som finns i systemet. Info hämtas för vald enhet och ett videoobjekt skapas.

Metod 1, metoden där den inbyggda funktionen preview används. Mindre kontroll men bättre prestanda jämfört med metod 2.

%% 3a. Skapa en livevideoström genom metod 1

%vid = videoinput('winvideo'); % Skapa ett videoobjekt (om det inte redan % är gjort)

figure; % Skapa fönstret som videon ska visas i

vidRes = get(vid, 'VideoResolution'); % Hämta aktuell upplösning

nBands = get(vid, 'NumberOfBands'); % Hämta aktuellt antal färgband

hImage = image( zeros(vidRes(2), vidRes(1), nBands) ); % Skapa ett bildobjekt

h = @display_frame2; % Skapa ett handle till funktionen display_frame2

setappdata(hImage,'UpdatePreviewWindowFcn',h); % Gör så att display_frame2 kommer % att köras för varje ny frame

preview(vid, hImage); % Starta själva previewfunktionen, med tillägget att det är

% det skapade bildobjektet som ska visas.

%% 1. Hämta info om tillgängliga capture devices

imaqhwinfo % Listar vilka kopplingar som finns mellan Matlab och capture devices

imaqhwinfo('winvideo') % Ger info om vilka capture devices som finns genom den här

% kopplingen. Här finns webcamen i det här fallet.

dev_info = imaqhwinfo('winvideo',1)

celldisp(dev_info.SupportedFormats) % Ger info om vilka olika format och % upplösningar som är tillgängliga för % den här kameran

%% 2. Skapa ett videoobjekt

vid = videoinput('winvideo'); %skapa ett videoobjekt med defaultformat/upplösning %vid = videoinput('winvideo', 1,'RGB24_640x480');

%vid = videoinput('winvideo', 1,'RGB24_160x120');

get(vid,'Source') %Webcamen har en källa, input1

out = imaqhwinfo(vid) % Info om videoobjektet

get(vid) % All info om videoobjektet

src = getselectedsource(vid) % Egenskaper för källan

frameRates = set(src, 'FrameRate') % Listar möjliga framerates

(18)

Metod 2, uppdatera ett figure-fönster. I filen display_frame.m bestäms vad som ska hända vid varje uppdatering av figure-fönstret

%% 3b. SKapa en livevideoström genom metod 2

%vid = videoinput('winvideo'); % Skapa ett videoobjekt (om det inte redan är gjort)

set(vid,'FramesPerTrigger', 1); % Hämta in en bild åt gången

set(vid,'TriggerRepeat', Inf); % Upprepa i oändlighet

set(vid,'FramesAcquiredFcnCount', 1); % Hur ofta ska en funktion köras för % inhämtade frames?

% 1 => för varje frame

set(vid,'FramesAcquiredFcn', {'display_frame'}); % Funktionen display_frame % kallas på för varje frame

set(vid, 'FrameGrabInterval', 1);

set(vid,'ErrorFcn', {'free_mem'}); % Frigör minne när man avbryter istället % för att fylla det

(19)

6. JMF (Java Media Framework)

6.1 Bildbehandling i realtid i Java med hjälp av JMF

JMF är Javas framework för att hantera media i Java. Teknologin är ganska gammal, första versionen kom 1998, och i dagsläget är det osäkert om den kommer fortsätta stödjas av Sun. Den erbjuder dock ett relativt smidigt sätt att hantera behandling av livevideo i Java.

Många har länge sett ner på Java när det kommer till så pass krävande saker som

realtidsbehandling av video. Mycket av denna negativa kritik är dock oförtjänt. När JMF kom år 2000 var datorerna inte lika snabba som idag. Det enda som dög till att behandla bilder i realtid då var i princip C eller C++. Java var helt enkelt för långsamt även om teknologin fanns. Nuförtiden är dock Java ett alternativ för livevideobehandling och JMF är ett relativt välfungerande system vad gäller livevideobehandling i Java. Tyvärr är bra exempel som kan visa på vad som är möjligt att göras och hur det görs svåra att hitta. Dessutom är JMF:s framtid långtifrån självklar. Den senaste uppdateringen av JMF kom 2003 och sedan dess har det varit ganska tyst från SUN:s sida vad gäller JMF. I maj 2006 utannonserade Tony Wyant, som styr utvecklingen av JMF sedan 2005, att SUN snart skulle redogöra för sina planer gällande JMF [3] vilket i skrivande stund ännu inte har inträffat.

Bland Sun:s exempelkod för JMF [4] finns bl.a. ett exempel där en videofil spelas upp och behandlas i realtid. Jag använde detta exempel som en grund och skrev om det så att det istället tar in en livevideoström från en webbkamera och behandlar den bilden istället. Enligt vad jag erfarit under mina tester är det här det helt klart lämpligaste sättet att behandla video i realtid i Java på.

Det fungerar så att det dels finns en klass som innehåller main-metoden och som öppnar upp själva videoströmmen och dels en klass där det bestäms vilka effekter som ska läggas på videoströmmen. Klassen som ger möjlighet att behandla bilddatan kallas för en Codec. Denna Codec ger tillgång till bilddatan som bytevärden. Det finns också möjlighet att skriva flera Codecs och köra flera stycken på videoströmmen.

Exemplet är som sagt ursprungligen ett exempel från Sun där de visar hur olika effekter kan läggas på en förinspelad videofil. Programmet kan fortfarande användas på detta sätt men defaultinställningen är att en webbcam ska användas. Då programmet startar hämtar det info om tillgängliga enheter genom att använda sig av CaptureDeviceManager och CaptureInfo-objekt. Listan med tillgängliga enheter gås igenom tills första webbcamen hittats (eller första objektet som använder en Video for Windows-drivrutin). Sedan skapas en MediaLocator som innehåller information om var objektet i fråga finns att tillgå. CaptureDeviceManagern används igen för att ta reda på möjliga format för webbkameran.

(20)

6.2 Kodgenomgång av JMF

6.2.1 TestEffect.java

Jag kommer att gå igenom delar av koden och förklara ungefär vad den gör. Först de delar som har med JMF att göra och sedan de delar som använde iCommand. För fullständig kod hänvisas till appendix.

En del av mainmetoden. Det här är det som sker om programmet inte ges tillgång till en färdiginspelad videofil. En lista med tillgängliga bildkällor skapas med hjälp av en CaptureDeviceManager. Objekten i listan gås sedan igenom ett efter ett och görs om till CaptureDeviceInfo-objekt. Med hjälp av metoden getName() fås namnet på aktuell enhet och om namnet börjar med ”vfw” är den antagligen den enhet vi söker. MediaLocatorn

ml (deklarerad tidigare) initieras med hjälp av devInfo för att hitta kameran i fråga.

Format-arrayen formats fylls med de olika videoformaten som är möjliga för kameran. Det som sedan händer är att metoden open körs, som returnerar true om allt går som det ska.

else {

CaptureDeviceInfo devInfo = null;

Vector list = CaptureDeviceManager.getDeviceList ( null ); String name;

for(int i =0; i<list.size(); i++) { CaptureDeviceInfo temp = (CaptureDeviceInfo)list.elementAt(i); name = temp.getName(); if ( name.startsWith ("vfw:")) { devInfo = (CaptureDeviceInfo)list.elementAt(i); break; } } ml = devInfo.getLocator(); formats = devInfo.getFormats(); }

TestEffect fa = new TestEffect(); if (!fa.open(ml))

System.exit(0); }

(21)

Det som händer först i metoden open är att processorn p initieras. Processor-objekt och player-objekt är två grundläggande begrepp inom JMF. En player är ett objekt som styr och renderar mediadata. En processor är ungefär samma sak som en player med

skillnaden att det finns möjlighet att behandla datan. Båda objekten skapas via klassen Manager. För att kunna skapa en Player eller Processor måste Managern veta var någonstans mediadatan finns. Denna information kan som sagt fås bl.a. genom en MediaLocator, i detta fall vår MediaLocator ml. Metoden addControllerListener specifierar att det är till det här objektet som en Controller kommer att skicka events. Det som händer när configure() körs på processorn är att det blir möjligt att behandla video- och eventuella ljudspår samt bestämma utgående format på strömmarna.

setContentDescriptor(null) gör att processorn kan användas som en player, alltså så att vi

kan rendera mediadatan och titta på den.

Track controls används för att manipulera de olika strömmarna. public boolean open(MediaLocator ml) {

try {

p = Manager.createProcessor(ml); } catch (Exception e) {

System.err.println("Failed to create a processor from the given url: " + e);

return false; }

p.addControllerListener(this);

// Put the Processor into configured state. p.configure();

if (!waitForState(p.Configured)) {

System.err.println("Failed to configure the processor."); return false;

}

// So I can use it as a player. p.setContentDescriptor(null);

// Obtain the track controls.

TrackControl tc[] = p.getTrackControls(); if (tc == null) {

System.err.println("Failed to obtain track controls from the processor.");

return false; }

(22)

Sök efter videospåret så att vi vet vilket spår vi ska manipulera. Sedan sätts videoformatet till önskat format bland dem som finns att välja på i format-arrayen.

Här sätts effekterna, codecs, för det valda spåret. Alla codecs skrivs alltså i separata klasser. Det är möjligt att använda en eller flera codecs.

Processorns prefetch-metod förbereder processorn och gör att den kan starta så fort som möjligt.

// Search for the track control for the video track. TrackControl videoTrack = null;

for (int i = 0; i < tc.length; i++) {

if (tc[i].getFormat() instanceof VideoFormat) { videoTrack = tc[i];

break; }

}

if (videoTrack == null) {

System.err.println("The input media does not contain a video track.");

return false; }

// Set video format

form = formats[4];

videoTrack.setFormat ( form );

System.err.println("Video format: " + videoTrack.getFormat());

// Instantiate and set the frame access codec to the data flow path. try {

Codec codec[] = { new BallFinder() }; videoTrack.setCodecChain(codec); } catch (UnsupportedPlugInException e) {

System.err.println("The processor does not support effects."); }

// Realize the processor. p.prefetch();

if (!waitForState(p.Prefetched)) {

System.err.println("Failed to realize the processor."); return false;

(23)

Här sätts layouten och själva videobilden samt att kontrollen för videospåret hämtas. Sedan startas processorn.

// Display the visual & control component if there's one. setLayout(new BorderLayout()); Component cc; Component vc; if ((vc = p.getVisualComponent()) != null) { add("Center", vc); } if ((cc = p.getControlPanelComponent()) != null) { add("South", cc); }

// Start the processor. p.start();

setVisible(true);

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent we) { p.close(); System.exit(0); } }); return true; }

(24)

6.2.2 BallFinder.java

Detta är alltså codec- eller effektklassen där vad som ska hända med bilddatan bestäms. Format-objekt för att hantera den okomprimerade RGB-datan skapas.

Dessa fyra är standardmetoder för interfacet Codec. De behövs för att klassen ska kunna public class BallFinder implements Effect {

. . . public BallFinder() {

inputFormats = new Format[] { new RGBFormat(null, Format.NOT_SPECIFIED, Format.byteArray, Format.NOT_SPECIFIED, 24, 3, 2, 1, 3, Format.NOT_SPECIFIED, Format.TRUE, Format.NOT_SPECIFIED) };

outputFormats = new Format[] { new RGBFormat(null, Format.NOT_SPECIFIED, Format.byteArray, Format.NOT_SPECIFIED, 24, 3, 2, 1, 3, Format.NOT_SPECIFIED, Format.TRUE, Format.NOT_SPECIFIED) }; }

public Format[] getSupportedInputFormats() { .

. .

public Format [] getSupportedOutputFormats(Format input) { .

. .

public Format setInputFormat(Format input) { .

. .

public Format setOutputFormat(Format output) { .

. .

(25)

I metoden process behandlas bilddatan. Datan passerar från en ingående buffert,

behandlas och skickas till en utgående buffert. Datan hämtas från buffertarna och läggs i byte-arrayer. Längden på den utgående byte-arrayen kontrolleras så att den stämmer överens med bildens bredd gånger bildens höjd gånger tre färgkanaler.

Här är ett sätt att göra om de tre färgkanalernas bytevärden till heltalsvärden mellan 0 och 255. Det är naturligtvis till stor hjälp vid bildbehandlingen. Efter det kan dessa värden användas till att behandla bilden på passande sätt. I mitt test gjorde jag en relativt enkel funktion som fick legoroboten att leta efter röda objekt. Detta gjorde jag genom att filtrera ut den röda färgen och använda mig av en labeling-funktion. Detta är en funktion som används för att hitta objekt i en bild genom att märka pixlarna i bilden. Närliggande pixlar som uppfyller ett visst villkor (t.ex. överstiger ett tröskelvärde) får samma

märkning och på så sätt kan pixlarna grupperas i separata objekt. Här användes labeling-funktionen för att hitta det största röda objektet i bilden (så att roboten inte ska intressera sig för enstaka röda pixlar som orsakas av brus). Roboten styr sedan mot mittpunkten av det röda objektet. För kod vad gäller själva bildbehandlingen hänvisas till appendix då denna genomgång mest syftar till att visa hur JMF och iCommand kan användas.

public int process(Buffer inBuffer, Buffer outBuffer) { int outputDataLength = ((VideoFormat)outputFormat).getMaxDataLength(); validateByteArraySize(outBuffer, outputDataLength); outBuffer.setLength(outputDataLength); outBuffer.setFormat(outputFormat); outBuffer.setFlags(inBuffer.getFlags()); // Parameters that change from frame to frame

byte [] inData = (byte[]) inBuffer.getData(); byte [] outData = (byte[]) outBuffer.getData();

. . .

if ( outData.length < iw*ih*3 ) {

System.out.println("the buffer is not full"); return BUFFER_PROCESSED_FAILED;

}

for(int h=0;h<iw*ih*3;h+=3) {

int red = (int)inData[h] & 0xFF; int green = (int)inData[h+1] & 0xFF; int blue = (int)inData[h+2] & 0xFF;

. . .

(26)

Slutet av metoden. Bilddatan läggs i outData-arrayen och färgas beroende på vilken label de har fått. Integern BUFFER_PROCESSED_OK (som tillhör Plugin-interfacet, se nedan) returneras vilket innebär att ingående data lyckats konverteras till utgående data.

Standardmetoder för Plugin-interfacet. Codec-interfacet är ett subinterface till Plugin och det är egentligen Plugin som har hand om databehandlingen.

for (int w = 0; w<labels.length; w++){ outData[w*3] = inData[w*3]; outData[w*3+1] = inData[w*3+1]; outData[w*3+2] = inData[w*3+2]; if (labels[w] == flest) { outData[w*3] = (byte)0; outData[w*3+1] = (byte)255; outData[w*3+2] = (byte)0; } if(labels[w] == point){ outData[w*3] = (byte)255; outData[w*3+1] = (byte)0; outData[w*3+2] = (byte)0; } if(labels[w] == frame){ outData[w*3] = (byte)0; outData[w*3+1] = (byte)0; outData[w*3+2] = (byte)255; } } return BUFFER_PROCESSED_OK; }

// methods for interface PlugIn public String getName() { return "Rotation Effect"; }

public void open() { }

public void close() { }

public void reset() { }

(27)

Standardmetoder för Controls-interfacet. Controls gör det möjligt att bl.a. få upp information om framerate.

6.3 Legoroboten, JMF och iCommand

Det jag använde för robottillämpningarna var alltså JMF för att ta in bilder och

iCommand för styrning av roboten. De olika hårdvarusammansättningarna har sett ut på följande vis:

• Maskin 1 • Roboten

• Webbkameran, kopplad via USB till maskin 1 och fastsatt på roboten • En bluetooth-adapter

• Maskin 2 • Roboten

• Webbkameran, kopplad via USB till maskin 2 och fastsatt på roboten • En bluetooth-adapter

• Maskin 2 • Roboten

• Den trådlösa kameran, fastsatt på roboten • Signalmottagare för den trådlösa kameran

• Digitaliseringsadapter, ansluten via en RCA-kabel till signalmottagaren och via USB till maskin 2

• En bluetooth-adapter

Anledningen till att maskin 1 byttes ut mot maskin 2 var att vissa problem uppstod med USB och Bluetooth. För mer information om problemen hänvisas till problemdelen i Resultat och slutsatser.

Testprogrammet jag gjorde var att låta roboten leta efter och plocka upp en röd boll. Själva bildbehandlingen bestod i att först sortera ut röda objekt, sedan via en

labelingalgoritm sortera ut det största röda objektet. Jag satte inga geometriska

restriktioner, att objektet skulle vara runt eller liknande, eftersom det skulle ha krävt lite högre bildkvalitet och framför allt mer ljus. Då roboten hittat bollen styrde den fram till

// methods for interface javax.media.Controls public Object getControl(String controlType) { return null;

}

public Object[] getControls() { return null;

(28)

När programmet startas etableras först kontakten med roboten via Bluetooth. Sedan startas kameran och javaprogrammet tar in bilder genom JMF. Bilden behandlas och olika beslut fattas utifrån hur bilden ser ut. Sedan skickas olika styrkommandon till roboten via Bluetooth.

(29)
(30)

6.4 Kodgenomgång av iCommand

6.4.1 BallFinder.java

Den här koden visar hur iCommand kan användas till att styra legoroboten. Klassen Motor styr de tre motorerna framåt eller bakåt, ett visst antal varv eller tills ett annat kommando ges.

// Look for the ball

if(boxSize < 70000 && robot){ if(allDone){ Motor.A.backward(); Motor.B.backward(); } else if(noObjects) { Motor.A.stop(); Motor.B.stop(); found = false; }

else if(found && !grab){ Motor.A.forward(); Motor.B.forward();

System.out.println("approaching ball"); }

else if(found && grab){ Motor.A.forward(); Motor.B.forward(); System.out.println("grabbing ball"); Motor.C.backward(); allDone = true; } else if(!noObjects) { if((left + (right-left)/2) < 90){ found = false; System.out.println("go left"); Motor.A.forward(); Motor.B.stop(); } . . .

(31)

7. RoboRealm

RoboRealm är ett gratisprogram som används tillsammans med en webbkamera av valfri sort för att kunna analysera och behandla livevideo. Programmet används med fördel inom robotområdet då det även har inbyggda funktioner för att styra vissa typer av robotar, bl.a. Legos NXT.

RoboRealm har flera kraftfulla bildbehandlingsfunktioner som t.ex. kan mäta sig med de funktioner som finns i Image Processing Toolbox i Matlab. Här finns funktioner för att hantera färger, histogram, matchningsfunktioner, labeling, filtreringar, morfologiska operationer m.m. Det går också att använda sig av VB-script i programmet.

Programmet fungerar ihop med såväl Video for Windows-drivrutiner som DirectShow-drivrutiner.

(32)

8. Hybridlösningar

Jag har förutom rena Java- och Matlablösningar även tittat en del på hur olika tekniker kan kombineras för att möjliggöra ett sätt att behandla realtidsvideo på.

8.1 Testade lösningar

8.1.1 Matlab/JMF

Då Image Acquisition Toolbox är ganska kostsam vore en annan lösning för att få in och kunna bearbeta realtidsvideo i Matlab välkommen. Eftersom Matlab har en inbyggd javakompilator gjorde jag ett försök där jag kombinerade Matlab med ett enkelt program skrivet i Java där JMF används för videodelen. Dock lyckades jag aldrig få programmet att kompileras eftersom Matlab alltid frös då ett Player-objekt skulle skapas. Eftersom Player- och Processor-objekt är grundläggande för att överhuvudtaget kunna visa någon video i JMF fick jag ge upp den här lösningen. Det kändes inte som om det var värt att lägga mer tid på något som det var osäkert hur bra det skulle fungera och som det dessutom var helt omöjligt att hitta någon support för.

8.1.2 Roborealm/Java

Bland Roborealms funktioner finns bl.a. möjligheten att skicka data till ett Javaprogram via en socket. Bilddatan kommer in i Roborealm och skickas vidare till ett Javaprogram där datan tas emot som bytevärden. Efter att ha konverterat bytevärdena till heltalsvärden kan bilden behandlas på valfritt sätt och sedan skicka tillbaka bilden till Roborealm där resultatet visas upp. Det här ger ju även möjligheten att kombinera bildoperationerna i Java med Roborealms inbyggda funktioner för bildbehandling vilket säkert kan ge tillfredsställande resultat för diverse tillämpningar. Med ett enkelt testprogram i Java ger detta bildfrekvenser i upp till ca 20 fps.

8.1.3 C-plugin i Matlab

Det här kan vara ett annat sätt att använda Matlab för realtidsvideohantering utan att behöva gå genom Image Acquisiton Toolbox. Då det inte funnits någon tid för det har jag inte skrivit någon egen plugin, men jag har tittat på ett par exempel [5],[6]. Båda

implementationerna är skrivna av samma person och den ena använder sig av Video for Windows medan dess efterföljare använder sig av DirectShow. De är skrivna som MEX-funktioner, alltså funktioner skrivna i C som kan ta emot data från Matlab, behandla den

(33)

Också det här är ett bra sätt att få video i Matlab bara den plugin som används sig av är tillräckligt bra. Tyvärr var dokumentationen för de implementationer jag tittade på ytterst bristfällig, men ett par enkla test lyckades jag få till och potentialen att få till en bra lösning utan alltför stor arbetsinsats finns helt klart.

Figur 6. Så här kan det se ut när pluginerna körs. I fönstret till höger läggs några olika effekter på i realtid

Både den version som använder sig av Video for Windows och den version som använder sig av DirectShow fungerar bra. Antal fps är helt klart tillräckligt för olika tillämpningar. Dessutom är det helt gratis att använda och till VfW-implementationen finns källkod att tillgå.

8.2 Otestade lösningar

Utöver de lösningar jag testat finns det ett par lösningar till som jag visserligen inte undersökt med några praktiska tillämpningar men som kanske ändå kan vara av intresse.

8.2.1 Matlab/RoboRealm

Det är möjligt att RoboRealm via en MEX-funktion skulle kunna förse Matlab med bilddata i realtid. Det är inte heller omöjligt att RoboRealm förr eller senare skulle kunna få en plugin för Matlab för just detta avseende. Hursomhelst kanske det är onödigt omständligt att skriva en C-plugin som länkar RoboRealm med Matlab då det istället

(34)

8.2.2 C-plugin till Java

Att använda C-kod i Java är möjligt via JNI – Java Native Interface. Det påminner en del om att skriva MEX-funktioner till Matlab. Den som har tid och tålamod att sätta sig in i hur detta fungerar kan säkert lyckas åstadkomma åtminstone en enklare fungerande lösning för att behandla video i Java.

(35)

9. Andra plattformar

Även om alla mina praktiska tester utförts i Windows XP finns tänkbara lösningar även för andra plattformar.

9.1 Linux

JMF finns tillgängligt också för olika distributioner av Linux. Hur väl det fungerar är svårt att säga då jag inte gjort några egna tester. Det bör dock nämnas att JMF inte verkar ha full funktionalitet för andra plattformar än Windows. Jag har t.ex. hittat exempel på stöd för vissa format som bara fungerat i Windows samt kod som endast går att

kompilera i Windows-miljö.

iCommand för styrning av Lego Mindstorms NXT-robotar är inte tillgänglig för denna plattform.

Matlab finns tillgängligt även för Linux men Image Acquisition Toolbox finns enbart i en Windowsversion. Det gör att en annan lösning måste hittas för att behandla realtidsvideo i Matlab på Linux-plattformen.

9.2 Mac OS X

JMF är möjligt att installera även på den här plattformen. Men som jag nämnde i avsnittet om Linux finns antagligen vissa begränsningar i denna distribution av JMF jämfört med Windows-versionen.

iCommand är inte tillgängligt för Mac OS X heller, utan är än så länge bara tillgängligt för Windows.

Vad gäller Matlab är det ungefär samma sak som med Linux. I skrivande stund finns en komplett version av Matlab för Macdatorer med PPC-processor och en betaversion för Macdatorer med Intel-processor (i vilken det för övrigt inte är möjligt att använda extra toolboxes alls just nu). Men eftersom Image Acquisition Toolbox bara fungerar på Windowsplattformen måste även här en annan lösning sökas.

(36)

10. Resultat och slutsatser

Till att börja med har detta varit ett intressant och givande arbete som gett mig stor insikt inom ett område jag är intresserad av. Mitt arbete har fungerat som en typ av

konsultuppdrag, dock med mycket egna tester och försök i och med att jag velat undersöka hur väl lösningarna fungerat för kurserna det främst riktat sig mot.

Det jag i huvudsak har kommit fram till är att tekniken absolut finns, även om de flesta lösningar inte riktigt fungerar tillräckligt bra för att kunna användas i exempelvis en kurslab just nu. Det har varit mycket problem med drivrutiner och inkompatibla hårdvarukonfigurationer, se problemdelen nedan.

Vad gäller bildbehandlingskurserna är det ju Matlab som gäller för att utföra arbetet. Den helt klart enklaste lösningen för att behandla realtidsvideo är Image Acquisition Toolbox. IAT har i princip färdiga lösningar för detta ändamål (se kapitlet om IAT). Problemet med IAT är priset. Att införskaffa IAT för en enda lab är helt enkelt inte prisvärt. Om däremot behandling av realtidsvideo är det huvudsakliga ämnet i en kurs är dock IAT ett självklart val.

För Ivan Rankins AI-kurs och andra kurser där styrning av en robot med hjälp av bildbehandling kan vara av intresse är Java tillsammans med Bluetooth ett bra val. Här kommer dock många av de problem jag stött på under arbetets gång in. Dessa gås igenom i detalj i problemdelen

iCommand-API:t som jag använt för att kunna kommunicera med roboten är fortfarande under utveckling vilket innebär att alla funktioner inte är fullt implementerade och fungerande än. iCommand utvecklas av en entusiastisk privatperson och förhoppningsvis kommer utvecklingen att fortsätta.

Att använda RoboRealm som enda plattform för att t.ex. ta hand om robottillämpningarna har sina nackdelar. Dels blir man beroende av ett tredjepartsprogram som inte är

garanterat att fungera vid framtida systemkonfigurationer, dels måste i så fall VB-script användas för att kommunicera med roboten vilket kan ställa till problem i labbar då studenter på exempelvis Medieteknik-programmet för närvarande inte lär sig det programmeringsspråket i någon kurs.

10.1 Problem

De största problemen jag haft under arbetet har orsakats av Bluetooth. Bluetooth fungerar överhuvudtaget mycket dåligt i Windows XP. (Se t.ex. [7]). Att använda en webbkamera via USB samtidigt som Bluetooth via USB används kan ge minst sagt oönskade resultat. På en av maskinerna ledde detta till upprepade blåskärmar då både kameran och

(37)

Den digitaliseringsadapter jag använde för att ta in video från den trådlösa kameran fick jag inte alls att fungera på den ena maskinen och på den andra maskinen gav den upphov till blåskärmar då och då.

T.ex. är det sällan Bluetooth-kopplingen mellan datorn och roboten lyckas då Java-programmet startas vilket jag åtminstone misstänker beror på iCommand då kopplingen vanligen lyckas då den görs manuellt direkt i Windows. Fast Bluetooth-adaptern jag använde finns inte heller på Legos lista över fungerande Bluetooth-adaptrar [8] så det kan ju ha med den saken att göra.

10.2 Slutsats

Den slutgiltiga slutsatsen är alltså att det finns metoder och lösningar för att arbeta med realtidsbehandling av video på ett enkelt sätt. Dock är problemen alltför många för att det garanterat ska kunna fungera smidigt, åtminstone på Windows-plattformen där Bluetooth ju är tämligen dåligt implementerat. Det är förstås möjligt att det går att uppnå bättre resultat med annan/dyrare utrustning men frågan är naturligtvis hur långt man är villig att gå prismässigt.

Vad gäller andra plattformar har jag ju inte gjort några praktiska tester men det är möjligt att ett annat operativsystem än Windows vore ett bättre val i dagens läge.

10.3 För- och nackdelar gällande hybridlösningarna

Video i Matlab

1. En MEX-funktion som förser Matlab med bilddata via VFW/DirectShow

Fördelar: kostnadsfritt, oberoende av tredjepartsutvecklare (möjligt att uppdatera vid behov)

Nackdelar: svårt att få det lika enkelt och funktionellt som Image Acquisition Toolbox

2. Roborealm via MEX eller liknande

Fördelar: många färdiga funktioner, enkelt gränssnitt, gratis programvara

Nackdelar: beroende av en programvara som inte är garanterad att fungera vid framtida systemkonfigurationer.

Video i Java

1. C-koppling

Fördelar: egenutvecklad programvara, lätt att uppdatera vid behov Nackdelar: inte lika enkelt som att använda inbyggda klasser

(38)

2. Roborealm via en socket

Fördelar: många färdiga funktioner, enkelt gränssnitt, gratis

Nackdelar: beroende av en programvara som inte är garanterad att fungera vid framtida systemkonfigurationer.

(39)

11. Källförteckning

[1] LEGO.com MINDSTORMS Overview,

http://mindstorms.lego.com/Overview/The_NXT.aspx, 20061216 [2] Realtid, Wikipedia, http://sv.wikipedia.org/wiki/Realtid, 20070119

[3] JMF-INTEREST archives – May 2006 (#68), http://archives.java.sun.com/cgi-bin/wa?A2=ind0605&L=jmf-interest&F=&S=&P=7372, 20061118

[4] Rotation Effect,

http://java.sun.com/products/java-media/jmf/2.1.1/solutions/RotationEffect.html#source, 20061020

[5] MATLAB, http://www.ikko.k.hosei.ac.jp/~matlab/matkatuyo/, 20061114 [6] Kazuyuki Kobayashi, Hosei Univ.,

http://www.ikko.k.hosei.ac.jp/~matlab/matkatuyo/vcapg2.htm, 20061114 [7] Andy Pennell’s Blog: Windows XP Bluetooth Support: A Rant,

http://blogs.msdn.com/andypennell/archive/2004/02/17/75276.aspx, 20070123 [8] LEGO.com MINDSTORMS Overview,

(40)

12. Appendix

A. Ordförklaringar och förkortningar

DirectShow – det nuvarande systemet som används för att hantera digital video i

Windows.

Capture device – enhet för inhämtning av bilder/video Figure-fönster – ett fönster i Matlab i vilket grafik kan visas Fps – frames per second, antal visade bilder per sekund Framerate – bildfrekvens

M-fil – fil innehållande Matlab-kod.

MEX-funktion – en funktion i Matlab som använder sig av C-kod i optimeringssyfte VfW – Video for Windows, det tidigare systemet för att hantera digital video i Windows.

(41)
(42)
(43)

// Put the Processor into configured state. p.configure(); if (!waitForState(p.Configured)) { System.err.println("Failed to configure the processor."); return false; } // So I can use it as a player. p.setContentDescriptor(null); // Obtain the track controls. TrackControl tc[] = p.getTrackControls(); if (tc == null) { System.err.println("Failed to obtain track controls from the processor."); return false; } // Search for the track control for the video track. TrackControl videoTrack = null; for (int i = 0; i < tc.length; i++) { if (tc[i].getFormat() instanceof VideoFormat) { videoTrack = tc[i]; break;

(44)

videoTrack.setCodecChain(codec); } catch (UnsupportedPlugInException e) { System.err.println("The processor does not support effects."); } // Realize the processor. p.prefetch(); if (!waitForState(p.Prefetched)) { System.err.println("Failed to realize the processor."); return false; } // Display the visual & control component if there's one. setLayout(new BorderLayout()); Component cc; Component vc; if ((vc = p.getVisualComponent()) != null) { add("Center", vc); } if ((cc = p.getControlPanelComponent()) != null) { add("South", cc); } // Start the processor. p.start(); setVisible(true); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent we) { p.close(); System.exit(0);

(45)

return true; super.addNotify(); pack(); synchronized (waitSync) { try { while (p.getState() != state && stateTransitionOK) waitSync.wait();

} catch (Exception e) {} } return stateTransitionOK; if (evt instanceof ConfigureCompleteEvent || evt instanceof RealizeCompleteEvent || evt instanceof PrefetchCompleteEvent) { synchronized (waitSync) { stateTransitionOK = true; waitSync.notifyAll();

} } else if (evt instanceof ResourceUnavailableEvent) { synchronized (waitSync) { stateTransitionOK = false; waitSync.notifyAll();

(46)
(47)
(48)
(49)
(50)
(51)
(52)
(53)
(54)
(55)
(56)
(57)
(58)
(59)
(60)
(61)

I M A C Q D E M O . M % D e m o n s t r a t i o n a v b e h a n d l i n g a v l i v e v i d e o m e d I m a g e A c q u i s i t i o n T o o l b o x % 1 . H ä m t a i n f o o m t i l l g ä n g l i g a c a p t u r e d e v i c e s m a q h w i n f o % L i s t a r v i l k a k o p p l i n g a r s o m f i n n s m e l l a n M a t l a b o c h c a p t u r e d e v i c e s % I d e t h ä r f a l l e t f i n n s ' c o r e c o ' o c h ' w i n v i d e o ' m a q h w i n f o ( ' w i n v i d e o ' ) % G e r i n f o o m v i l k a c a p t u r e d e v i c e s s o m f i n n s g e n o m d e n h ä r % k o p p l i n g e n . H ä r f i n n s w e b c a m e n i d e t h ä r f a l l e t . e v _ i n f o = i m a q h w i n f o ( ' w i n v i d e o ' , 1 ) e l l d i s p ( d e v _ i n f o . S u p p o r t e d F o r m a t s ) % G e r i n f o o m v i l k a o l i k a f o r m a t o c h u p p l ö s n i n g a r % s o m ä r t i l l g ä n g l i g a f ö r d e n h ä r k a m e r a n % 2 . S k a p a e t t v i d e o o b j e k t i d = v i d e o i n p u t ( ' w i n v i d e o ' ) ; % s k a p a e t t v i d e o o b j e k t m e d d e f a u l t f o r m a t / u p p l ö s n i n g v i d = v i d e o i n p u t ( ' w i n v i d e o ' , 1 , ' R G B 2 4 _ 6 4 0 x 4 8 0 ' ) ; v i d = v i d e o i n p u t ( ' w i n v i d e o ' , 1 , ' R G B 2 4 _ 1 6 0 x 1 2 0 ' ) ; e t ( v i d , ' S o u r c e ' ) % W e b c a m e n h a r e n k ä l l a , i n p u t 1 u t = i m a q h w i n f o ( v i d ) % I n f o o m v i d e o o b j e k t e t e t ( v i d ) % A l l i n f o o m v i d e o o b j e k t e t r c = g e t s e l e c t e d s o u r c e ( v i d ) % E g e n s k a p e r f ö r k ä l l a n r a m e R a t e s = s e t ( s r c , ' F r a m e R a t e ' ) % L i s t a r m ö j l i g a f r a m e r a t e s r c . F r a m e R a t e = f r a m e R a t e s { 1 } ; % S ä t t e r f r a m e r a t e n t i l l ö n s k a t v ä r d e % 3 a . S k a p a e n l i v e v i d e o s t r ö m g e n o m m e t o d 1 v i d = v i d e o i n p u t ( ' w i n v i d e o ' ) ; % S k a p a e t t v i d e o o b j e k t ( o m d e t i n t e r e d a n ä r g j o r t ) i g u r e ; % S k a p a f ö n s t r e t s o m v i d e o n s k a v i s a s i i d R e s = g e t ( v i d , ' V i d e o R e s o l u t i o n ' ) ; % H ä m t a a k t u e l l u p p l ö s n i n g B a n d s = g e t ( v i d , ' N u m b e r O f B a n d s ' ) ; % H ä m t a a k t u e l l t a n t a l f ä r g b a n d I m a g e = i m a g e ( z e r o s ( v i d R e s ( 2 ) , v i d R e s ( 1 ) , n B a n d s ) ) ; % S k a p a e t t b i l d o b j e k t = @ d i s p l a y _ f r a m e 2 ; % S k a p a e t t h a n d l e t i l l f u n k t i o n e n d i s p l a y _ f r a m e 2

(62)

p p d a t a ( h I m a g e , ' U p d a t e P r e v i e w W i n d o w F c n ' , h ) ; % G ö r s å a t t d i s p l a y _ f r a m e 2 k o m m e r a t t k ö r a s % f ö r v a r j e n y f r a m e i e w ( v i d , h I m a g e ) ; % S t a r t a s j ä l v a p r e v i e w f u n k t i o n e n , m e d t i l l ä g g e t a t t d e t ä r % d e t s k a p a d e b i l d o b j e k t e t s o m s k a v i s a s b . S k a p a e n l i v e v i d e o s t r ö m g e n o m m e t o d 2 = v i d e o i n p u t ( ' w i n v i d e o ' ) ; % S k a p a e t t v i d e o o b j e k t ( o m d e t i n t e r e d a n ä r g j o r t ) v i d , ' F r a m e s P e r T r i g g e r ' , 1 ) ; % H ä m t a i n e n b i l d å t g å n g e n v i d , ' T r i g g e r R e p e a t ' , I n f ) ; % U p p r e p a i o ä n d l i g h e t v i d , ' F r a m e s A c q u i r e d F c n C o u n t ' , 1 ) ; % H u r o f t a s k a e n f u n k t i o n k ö r a s f ö r i n h ä m t a d e f r a m e s ? % 1 = f ö r v a r j e f r a m e v i d , ' F r a m e s A c q u i r e d F c n ' , { ' d i s p l a y _ f r a m e ' } ) ; % F u n k t i o n e n d i s p l a y _ f r a m e k a l l a s p å f ö r v a r j e f r a m e v i d , ' F r a m e G r a b I n t e r v a l ' , 1 ) ; v i d , ' E r r o r F c n ' , { ' f r e e _ m e m ' } ) ; % F r i g ö r m i n n e n ä r m a n a v b r y t e r i s t ä l l e t f ö r a t t f y l l a d e t t ( v i d ) % S t a r t a v i d e o o b j e k t e t o c h i n h ä m t n i n g e n a v b i l d e r

(63)

D I S P L A Y _ F R A M E . M u n c t i o n d i s p l a y _ f r a m e ( o b j , e v e n t ) % 1 . R e n s a m i n n e t s å d e t i n t e b l i r f u l l t r i g d a t a = i m a q m e m ; e m L e f t = t r i g d a t a . F r a m e M e m o r y L i m i t -t r i g d a t a . F r a m e M e m o r y U s e d ; s g = ' M e m o r y l e f t f o r f r a m e s ' ; p r i n t f ( ' % s : % d ' , m s g , m e m L e f t ) f ( ( m e m L e f t < 2 0 0 0 0 0 0 0 ) ) f l u s h d a t a ( o b j ) ; n d % 2 . H ä m t a i n a k t u e l l f r a m e a m p l e _ f r a m e = p e e k d a t a ( o b j , 1 ) ; a m p l e _ f r a m e = i m 2 d o u b l e ( s a m p l e _ f r a m e ) ; % 3 a G a u s s -b l u r i f o u r i e r p l a n e t z = s i z e ( s a m p l e _ f r a m e ) ; f ( s z ( 1 ) = = 2 4 0 ) b i l d = s a m p l e _ f r a m e ( : , : , 1 ) ; b i l d _ f f t = f f t 2 ( b i l d ) ; f f t _ s h i f t = f f t s h i f t ( b i l d _ f f t ) ; [ X , Y ] = m e s h g r i d ( -1 6 0 : 1 : 1 5 9 , -1 2 0 : 1 : 1 1 9 ) ; Z = e x p ( -( X . ^ 2 + Y . ^ 2 ) / ( 2 * 5 0 0 ) ) ; f f t _ g a u s s e d = f f t _ s h i f t . * Z ; b i l d _ i n v = i f f t s h i f t ( f f t _ g a u s s e d ) ; b i l d = i f f t 2 ( b i l d _ i n v ) ; i m s h o w ( r e a l ( b i l d ) , [ ] ) d r a w n o w ; % U p p d a t e r a f i g u r e -f ö n s t r e t n d

(64)

b S o b e l -f i l t e r i s p a t i a l p l a n e t = s i z e ( s a m p l e _ f r a m e ) ; ( s z ( 1 ) = = 2 4 0 ) h = f s p e c i a l ( ' s o b e l ' ) ; s a m p l e _ f r a m e = i m f i l t e r ( s a m p l e _ f r a m e , h ) ; i m s h o w ( s a m p l e _ f r a m e ) ; d r a w n o w ; % U p p d a t e r a f i g u r e -f ö n s t r e t d

(65)

D I S P L A Y _ F R A M E 2 . M u n c t i o n d i s p l a y _ f r a m e 2 ( o b j , e v e n t , h I m a g e ) % 1 . H ä m t a b i l d d a t a e t ( h I m a g e , ' C D a t a ' , e v e n t . D a t a ) ; % H ä m t a b i l d i n f o r m a t i o n t i l l h I m a g e y I m a g e D a t a = g e t ( h I m a g e ) ; % G ö r d a t a n å t k o m l i g y I m a g e = i m 2 d o u b l e ( m y I m a g e D a t a . C D a t a ) ; % H ä m t a s j ä l v a b i l d d a t a n ( C d a t a ) % 2 a S o b e l f i l t r e r i n g z = s i z e ( m y I m a g e ) ; f ( s z ( 1 ) = = 2 4 0 ) = f s p e c i a l ( ' s o b e l ' ) ; y I m a g e 2 = i m f i l t e r ( m y I m a g e , h ) ; y I m a g e 2 = i m 2 u i n t 8 ( m y I m a g e 2 ) ; % K o n v e r t e r a t i l l b a k a b i l d e n t i l l U I N T 8 e t ( h I m a g e , ' C D a t a ' , m y I m a g e 2 ) ; % S ä t t C d a t a -v ä r d e t t i l l d e n b e h a n d l a d e b i l d e n n d % 2 b a = m y I m a g e ( 7 1 : 1 2 8 , 7 6 : 1 3 2 ) ; m y I m a g e 2 = i f f t 2 ( f f t 2 ( h ) . * f f t 2 ( m y I m a g e ) ) ; C = r e a l ( i f f t 2 ( f f t 2 ( b w ) . * f f t 2 ( r o t 9 0 ( a , 2 ) , 2 5 6 , 2 5 6 ) ) ) ; s z = s i z e ( m y I m a g e ) ; i f ( s z ( 1 ) = = 2 4 0 ) b i l d = m y I m a g e ( : , : , 1 ) ; b i l d _ f f t = f f t 2 ( b i l d ) ; f f t _ s h i f t = f f t s h i f t ( b i l d _ f f t ) ; s = s i z e ( b i l d ) ; % [ X , Y ] = m e s h g r i d ( -s ( 2 ) / 2 : 1 : s ( 2 ) / 2 -1 , -s ( 1 ) / 2 : 1 : s ( 1 ) / 2 -1 ) ; [ X , Y ] = m e s h g r i d ( -1 6 0 : 1 : 1 5 9 , -1 2 0 : 1 : 1 1 9 ) ;

(66)

= e x p ( -( X . ^ 2 + Y . ^ 2 ) / ( 2 * 5 0 0 ) ) ; f t _ g a u s s e d = f f t _ s h i f t . * Z ; i l d _ i n v = i f f t s h i f t ( f f t _ g a u s s e d ) ; i l d = r e a l ( i f f t 2 ( b i l d _ i n v ) ) ; i l d = i m 2 u i n t 8 ( b i l d ) ; % K o n v e r t e r a t i l l b a k a b i l d e n t i l l U I N T 8 y I m a g e ( : , : , 1 ) = b i l d ; y I m a g e ( : , : , 2 ) = b i l d ; y I m a g e ( : , : , 3 ) = b i l d ; e t ( h I m a g e , ' C D a t a ' , b i l d ) ; % S ä t t C d a t a -v ä r d e t t i l l d e n b e h a n d l a d e b i l d e n n d 2 c A v e r a g i n g f i l t e r = o n e s ( 5 , 5 ) / 2 5 ; y I m a g e 2 = i m f i l t e r ( m y I m a g e , h ) ; y I m a g e 2 = i m 2 u i n t 8 ( m y I m a g e 2 ) ; % K o n v e r t e r a t i l l b a k a b i l d e n t i l l U I N T 8 e t ( h I m a g e , ' C D a t a ' , m y I m a g e 2 ) ; % S ä t t C d a t a -v ä r d e t t i l l d e n b e h a n d l a d e b i l d e n

(67)

F R E E _ M E M . M u n c t i o n f r e e _ m e m ( o b j , e v e n t ) t o p ( o b j ) ; l u s h d a t a ( o b j ) ;

References

Related documents

Vid den slutliga handläggningen har också följande deltagit: överdirektören Fredrik Rosengren, rättschefen Gunilla Hedwall, enhetschefen Pia Gustafsson och sektionschefen

Socialstyrelsen har inget att erinra mot promemorians förslag om ändringar i lag- stiftningen om sociala trygghetsförmåner efter det att Förenade kungariket har lämnat

Samhällsvetenskapliga fakulteten har erbjudits att inkomma med ett yttrande till Områdesnämnden för humanvetenskap över remissen Socialdepartementet - Ändringar i lagstiftningen

Områdesnämnden för humanvetenskap har ombetts att till Socialdepartementet inkomma med synpunkter på remiss av Ändringar i lagstiftningen om sociala trygghetsförmåner efter det att

Sveriges a-kassor har getts möjlighet att yttra sig över promemorian ”Ändringar i lagstiftningen om sociala trygghetsförmåner efter det att Förenade kungariket har lämnat

- SKL anser att Regeringen måste säkerställa att regioner och kommuner får ersättning för kostnader för hälso- och sjukvård som de lämnar till brittiska medborgare i

När interaktiva media eller internet nu har blivit modernt uppstår en rädsla för att vem som helst ska få bidra till den samlade kunskapen och att det därigenom kommer att

Vi valde ut tre deltagare från Paralympics i Peking 2008 för intervjuer, Ingela Lundbäck, Peter Wikström och Anders Grönberg.. I våra intervjuer har vi även valt att prata om