Masinnägemine Robootika Kodulaboris

Autor: Raivo Sell

Käesolev õpiobjekt tutvustab Masinnägemise mooduli kasutamist Robootika Kodulaboriga.

Masinnägemine on tehnoloogia, mis kasutab kaamerat ja vastavat tarkvara, vahendades kontrollerile pilti või videot reaalsest maailmast. Sisendpilti või videot töötleb tarkvara, mis analüüsib kujutisi ja üritab tuvastada nende olemust, et selle põhjal saaks kontroller võtta vastu edasisi juhtimisotsuseid. Kaameramoodulit võib võrrelda ka keeruka anduriga, kus lihtsa sisendsignaali asemel on keerukas reaal-aja video, mille töötlemiseks on tavaliselt suuremat protsessorijõudlust ja keerukamaid algoritme vaja. Masinnägemist kasutatakse tööstuses automaatseks inspekteerimiseks ja kvaliteedikontrolliks ning robootikas robotile ümbritsevast keskkonnast adekvaatse ettekujutuse andmiseks. Viimastel aastatel on aktiivselt tegeletud mehitamate autode arendamisega, millede üheks oluliseks anduriks on samuti masinnägemise moodul.

Robootika Kodulaboris on Masinnägemise mooduliks CMUcam3 tüüpia kaamera, mis ühendatakse Kommunikatsioonimooduli RS232 pesasse. Andmevahetuseks mikrokontrolleriga kasutab Masinnägemise moodul UART jadaliidest.

ESF

Õpiobjekti nimi: Masinnägemine Robootika Kodulaboris

Õpiväljundid:

Pärast mooduli läbimist õpilane:

  • Kirjeldab masinnägemise olemust
  • Kirjeldab masinnägemise mooduli tööpõhimõtet
  • Ühendab vajalikud moodulid õigesti

Kasutusjuhend:

  • Teoreetilise taustamaterjaliga tutvumine
  • Õppevideo vaatamine
  • Enesekontrolli küsimustele vastamine

Õpetatav osa: Lugeda teoreetilist ülevaadet enne riistvara reaalset ühendamist ja pingestamist. Vaadata õpivideosid korrektse riistvara käsitlemise tagamiseks. Õpitu kinnistamiseks tuleb praktilised näited reaalselt läbi teha.

Seoste loomine: Läbi õppevideo ja sõnalise selgituse järgimise.

Kinnistav osa: Iseseisev praktika reaalse riistvarakomplekti baasil.

TEOREETILINE OSA

Masinnägemine

CMUcam3 kaamera tarkvara ei toeta lihtsat jadaliidse kaudu andmevahetust. Kuna see võimekus oli olemas CMUcam2 kaameral, siis on tehtud ka CMUcam3 jaoks tarkvara, mis emuleerib kaamera eelmist versiooni. Kasutada saab eelmise versiooni CMUcam2GUI liidest ja jadaliidese käsklusi.

Kaamera seadistamine

CMUcam3 kaamera eelmise versiooni emuleerimiseks tuleb alla laadida ja paigaldada flash utiliit, millega saab uuendada CMUcam3 püsivara. Peale püsivara uuendamist (hex faili laadimist kaamerasse) emuleeritaksegi seda kui CMUcam2-te ja edaspidi tuleb kasutada eelmise versiooni jaoks mõeldud kasutajaprogrammi pildi vaatamiseks. Lisaks on CMUcam2 andmelehel olemas jadaliidese käsustik kaameraga suhtlemiseks.

CMUcam2 GUI

Tegemist on arvutile mõeldud graafilise kasutajaliidesega, mis võimaldab kaamerast pilti vaadata ja erinevaid funktsioone testida. Tagemist on Java põhise programmiga, mille käivitamiseks tuleb enne paigaldade endale meelepärane JRE (Java Runtime Environment), mis võimaldab jar tüüpi faili käivitada. Programmi kasutamiseks tuleb kaamera ühendada võimaluse korral otse arvuti COM pordiga või kasutada selleks USB-Serial üleminekut. Programmi käivitamisel küsitakse COM pordi numbrit, kuhu kaamera on ühendatud. Peale seda avaneb programmi töökeskkond. Üleval ääres on menüü, kust saab erinevaid funktsioone valida, nagu näiteks servode liigutamine. Kaamera pildi vaatamiseks tuleb minna vahelehele „Camera View“ ja seejärel vajutada „Grab Frame“ nuppu. Nüüd laetakse kaamerast pilt, mida saab ka salvestada. Pildil soovitud värvil klikates saab teada selle koodi ning samal ajal tõstetakse teised sama värvi pikslid esile.

„Color“ vahekaardil saab eespool valitud värvi otsimist testida. Sinna genereeritakse automaatselt värvi minimaalsed ja maksimaalsed väärtused, mida saab soovi korral muuta. Värvi järgimiseks tuleb vajutada „Track Color“ nuppu. Ümber sama värvi alade joonistatakse ristkülik. Kaamera saadab välja selle ristküliku külgede kaks koordinaati ja lisaks ka selle keskpunkti koordinaadid.

Värvi järgimiseks Robootika Kodulaboriga on mõistlik antud programmiga sobiv värvivahemik määrata, mida otsida ja see reaalselt ära testida.

Funktsionaalsus

CMUcam3 omab mitmesugust tarkvaralist ja riistvaralist funktsionaalsust, mida saab rakendada läbi juhtkontrolleri või ka kaameramoodulil iseseisvalt. Järgnevalt on ära toodud kaameramooduli olulisemad omadused:

  • Avatud lähtekoodil põhinev püsivara
  • CIF resolutsioon (352x288) RGB värvituvastus
  • MMC/SD kaardi pesa
  • 4 kanaliga servo juhtkontroller
  • Pilditöötlusjõudlus 26 fps (frames per second)
  • Tarkvaraline JPG tihendamine
  • Pilditöötlusfunktsioonide baas teek
  • CMUcam2 emuleerimine
  • must-valge analoog video väljund (PAL või NTSC)

Kasutamine

Kaamera tüüpilised rakendusalad

  • Robootika (spioonirobotid)
  • Järelvalve
  • Andurite võrgustikus
  • Haridus ja õppeesmärgil
  • Objekti tuvastamine ja järgimine
  • Programmeeritava servo kontrollerina
  • MMC/SD kaardile andmete logimiseks

Robootika Kodulabori näidetes kasutatakse CMUcam3 kaamerat emuleeritud reziimis. See ei nõua kaamera enda programmeerimist ja saab keskenduda lihtsamate rakenduste arendamisele Robootika Kodulabori moodulitega. Kaameraga suhtlemisel, kasutatakse CMUcam2 juhendis toodud käsustikku.

Robootika Kodulabori näitekood on koostatud, kasutades nii palju kui võimalik Robootika Kodulabori standard teeki, kuid jadaliidesest andmete lugemine on kiiruse huvides muudetud katkestustepõhiseks. Tarkvara on jagatud eraldi failideks, millest main.c failis paikneb üldine funktsionaalsus, nagu ekraani ja nuppude juhtimine. Failis CMUCAM.c paiknevad kaameraspetsiifilised funktsioonid. Käesoleva näite puhul on sinna koondatud värvi otsimise ja andmete vastuvõtmiseks vajalik funktsionaalsus. Kuna erinevaid käskusi on küllaltki palju, siis on seda faili soovitav vastavalt projekti vajadustele täiendada. Fail USART.c on mõeldud ainult jadaühenduse teenindamiseks. Failis on funktsioon ühenduse seadistamiseks ja mõlema suuna andmevahetuseks. Kui saabuvad andmed, käivitatakse failis CMUCAM.c paiknev CMUPacketHandler, mis teeb kindlaks ja töötleb saabuva märgi ja koostab neist paketi. CMUPacketHandler on näites mõeldud kindlate pakettide töötlemiseks ja seda võib vajadusel täiendada, lisades uute pakettide tuge jne.

NÄITEKOOD

Vajutades nupule S2 hakkab kaamera eelseadistatud värvi otsima. Tulemus kuvatakse ekraanil formaadi Mx ja My, kus Mx ja My on ümber valitud värvi ala joonistatud ristküliku keskpunkti koordinaadid. Kui värvi ei leita, kuvatakse nullid. Näiteprogramm on seadistatud otsima oranzhi värvi.

Funktsioonid


//*****************************************************************************
// CMU CAM 3 juhtimisega seotud funktsioonid
// 2011
// Autor: Heiko Pikner   
//*****************************************************************************
 
#include "CMUCAM.h"
 
 
//
// Globaalsed muutujad
//
volatile char str_x[5];
volatile char str_y[5];
volatile int8_t packet_received = 0;
int8_t packet_t_typ=0;
int8_t pitcounter =0;
 
//
// Funktsiooni päised
//
void USART_Transmit(unsigned char);
 
//*****************************************************************************
//
// Pakettide tõlgendamine ja andmete töötlemine
//
//*****************************************************************************
void CMUPacketHandler(unsigned char c)
{
 
 
	// Paketi tähise järgi T paketi tuvastamine
	if(c==0x54)
	{
		packet_t_typ=1;					
 
	}
 
	// Paketist Mx ja My eraldamine. Kumbki võib olla 1-3 kohaline 
	// number. Numbrid on eraldatud tühikutega.	Mx talletatakse str_x massiivi
	// ja My str_y massivi. Iga massiivi element on üks number. 		
	if(packet_t_typ ==1)
	{
		pitcounter++;
 
 
		if(pitcounter==3)
		{
 
			str_x[0]=c;
		}
 
		if(pitcounter==4)
		{	
			if(c == 0x20)
			{
				pitcounter=6;
			}
			else
			{
 
				str_x[1]=c;
			}
		}
 
 
		if(pitcounter == 5)
		{
 
			if(c == 0x20)
			{
				pitcounter=6;
			}
			else
			{
				str_x[2]=c;
			}
 
		}
 
 
		if(pitcounter==7)
		{							
				str_y[0]=c;
 
		}
		if((pitcounter==8)&& (c != 0x0D))
		{
				if(c == 0x20)
			{
				pitcounter=6;
			}
			else
			{							
				str_y[1]=c;
			}
 
		}
		if((pitcounter==9)&& (c != 0x0D))
		{
			if(c == 0x20)
			{
				pitcounter=6;
			}
			else
			{
 
				str_y[2]=c;
			}
 
		}
 
 
		if(c == 0x0D)
		{
			packet_t_typ=0;
			pitcounter=0;
			packet_received = 1;
 
		}
 
	}	
 
}
 
//*****************************************************************************
//
//Funktsioon küsib kaamerast tarkvara numbri. Saada 'GV'
//
//*****************************************************************************
void GetVersion(void)
{ 
	USART_Transmit('g'); 
	USART_Transmit('v');
	USART_Transmit('\n'); 	
	USART_Transmit('\r');  
}
 
//*****************************************************************************
//
//Funktsioon kaamera resettimiseks. Saada 'RS'
//
//*****************************************************************************
void ResetCam(void)
{
	USART_Transmit('R'); 
	USART_Transmit('S');
	USART_Transmit('\n'); 	
	USART_Transmit('\r');
}
 
//*****************************************************************************
//
// Alusta valitud värvi trakkimist. Saada mask 'OM 0 3' ja seejärel 
// 'TC 184 234 4 54 0 41'
//
//*****************************************************************************
void StartTracking(void)
{   
	// Sea mask, et kaamera saadaks ainult Mx ja My koordinaadid
	USART_Transmit('O'); 
	USART_Transmit('M');
	USART_Transmit(' ');
	USART_Transmit('0');
	USART_Transmit(' ');
	USART_Transmit('3');
 
	USART_Transmit('\n'); 	
	USART_Transmit('\r'); 
 
 
 
	//Värvi valimiseks on formaat minRed maxRed minGreen maxGreen minBlue maxBlue 
	USART_Transmit('T');
	USART_Transmit('C');
 
	USART_Transmit(' ');	
	USART_Transmit('1');
	USART_Transmit('8');
	USART_Transmit('4');
 
	USART_Transmit(' ');
	USART_Transmit('2');
	USART_Transmit('3');
	USART_Transmit('4');
 
	USART_Transmit(' ');
	USART_Transmit('4');
 
	USART_Transmit(' ');
	USART_Transmit('5');
	USART_Transmit('4');
 
	USART_Transmit(' ');
	USART_Transmit('0');
 
	USART_Transmit(' ');
	USART_Transmit('4');
	USART_Transmit('1');
 
 
 
	USART_Transmit('\n'); 	
	USART_Transmit('\r');  
}

Peaprogramm


#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdlib.h>
#include <homelab/delay.h>
#include <homelab/pin.h>
#include <homelab/module/lcd_gfx.h>
 
#include "main.h"
 
//
//Muutujad, mis on defineeritud mujal
//
 
extern volatile int8_t packet_received;
 
extern volatile char str_x[5];
extern volatile char str_y[5];
 
 
//
//Nuppude viikude valik
//
pin button1 = PIN(C, 0);
pin button2 = PIN(C, 1);
pin button3 = PIN(C, 2);
 
 
//
// Seadista süsteem
//
static inline void init()
{
		// Seab nupud töökorda
		pin_setup_input_with_pullup(button1);
		pin_setup_input_with_pullup(button2);
		pin_setup_input_with_pullup(button3);
 
		// LCD ekraani algseadistamine
		lcd_gfx_init();
 
		// Ekraani puhastamine
		lcd_gfx_clear();
 
		// Taustavalgustuse tööle lülitamine
		lcd_gfx_backlight(true);	
 
		// Programmi nime kuvamine
		lcd_gfx_goto_char_xy(3, 1);
		lcd_gfx_write_string("CMU-CAM");
 
		// Kuva Mx
		lcd_gfx_goto_char_xy(0, 4);
		lcd_gfx_write_string("Mx");
 
		// Kuva My
		lcd_gfx_goto_char_xy(0, 5);
		lcd_gfx_write_string("My");
 
 
		DDRE = (1<<PE1);
 
		// Seriali seadistamine
		UsartInit();
 
		// Katkestuste lubamine
		sei();
}
 
//*****************************************************************************
//
//MAIN
//
//*****************************************************************************
int main(void)
{	
	unsigned char new_value1, old_value1 = 0, new_value2, 
		old_value2 = 0, new_value3, old_value3 = 0;
 
 
	// Seadista süsteem
	init();	
 
 
	while (1)
	{	 
 
			// Loeb nuppude väärtused
			new_value1 = pin_get_debounced_value(button1);
			new_value2 = pin_get_debounced_value(button2);
			new_value3 = pin_get_debounced_value(button3);
 
			// Nupp S1 alla vajutatud
			if((!new_value1) && (old_value1))
			{
 
				// Tee midagi
			}
 
			// Nupp S2 alla vajutatud
			if((!new_value2) && (old_value2))
			{
				// Alusta värvi otsimist
				StartTracking();				
 
			}
 
			// Nupp S3 alla vajutatud
			if((!new_value3) && (old_value3))
			{						
				// Tee midagi
 
			}
 
			// Jätab eelmised nupuväärtused meelde
			old_value1 = new_value1;
			old_value2 = new_value2;
			old_value3 = new_value3;
 
 
 
 
			// Kui pakett on saabunud, kuvab selle sisu ekraanile			
			if(packet_received == 1)
			{
				// Vii kursor algusesse
				lcd_gfx_goto_char_xy(6, 4);
 
				// Kuva klobaalsest muutujast pakett ja kuva see
				lcd_gfx_write_string((char*) &str_x);
 
				// Vii kursor algusesse
				lcd_gfx_goto_char_xy(6, 5);
 
				// Kuva klobaalsest muutujast pakett ja kuva see
				lcd_gfx_write_string((char*) &str_y);
 
 
 
				// Kustuta vana pakett, ehk täida see tühikutega
				memset((char*) &str_x, 0x20, 4);
				memset((char*) &str_y, 0x20, 4);
 
				// Nulli paketi saabumist märkiv lipp
				packet_received = 0;
			}						
 
	}
}

ENESEKONTROLL

Vastates alljärgnevatele küsimustele, saad proovida oma teadmisi antud teema kohta

Kas kaameramooduli CMUcam3 enda püsivara on võimalik uuendada?
Vali õige vastus

Jah
Ei

Millist ühendust saab kasutada CMUcam3 arvutiga ühendamisel?
Vali õiged vastused

USB
Jadaport (COM port Windowsis)
Ühendades USB-Serial adapteriga
Paralleelühendust (LPT port Windowsis)
VGA liides

Millist sideprotokolli CMUcam3 kasutab arvutiga suhtlemisel?
Vali õige vastus

UART
SPI
I2C

Millist funktsionaalsust võimaldab CMUcam3 kaameramoodul?
Vali õiged vastused

Värvituvastus
Näotuvastus
Servode juhtimine
Objekti kauguse määramine
Avade sügavuse määramine

LISAMATERJAL

  1. Robootika Kodulabor - Kommunikatsioonimoodul
  2. Robootika Kodulabor - Masinnägemine
  3. Carnegie Mellon University - CMUcam3

Teoreetilise osa ja näitekoodi algtekstide autor: Raivo Sell ja Heiko Pikner