Sie sind auf Seite 1von 20

Versuchsdokumentation

WS 14/15

Praktikumsversuch: SmartCam (leanXcam)

Gruppe - B5
Optoelektronik 2
LeanXCam

 Inhalt

Einführung .......................................................................................................................... 3
Erfassung vom Rot. Teil 1 ................................................................................................... 4
Erfassung von Farben. Teil 2............................................................................................... 7
Anhang.............................................................................................................................. 10
1. Erfassung vom Rot .......................................................................................................... 10
2. Erfassung von Farben ..................................................................................................... 14
Literaturverzeichnis .......................................................................................................... 20
Optoelektronik 3
LeanXCam

 Einführung

LeanXCam ist eine intelligente Farbkamera mit einem ganz grossen Satz von
Funktionen, möglich durch OpenCV in einem Computer (wir werden darüber später sprechen).
Diese Farbkamera hat eine hohe Leistung und ausβerdem niedrige Kosten.

Was macht LeanXcam zur besten Kamera sind : ein etablierter Sensor-Chip, ein
schneller digitaler Signalprozessor und ein System mit einem Linuxbasierten Betrieb.

Die Kamera wird in Anwendungen wie Vision von Maschinen verwendet. Die
Kommunikation ist durch Ethernet versichert.

Alle Features sind hier zusammengefasst:

Betriebssystem
µClinux – Microcontroller Linux
Programmierung
C/C++, Open CV Integration
Kommunikation Distanz Objekt
Ethernet 0.2 m 0.26 x 0.17 m
Auflösung 0.5 m 0.67 x 0.43 m
752 x 480; 8 bit / Pixel 1.0 m 1.33 x 0.85 m
Mehr Information
www.leanXcam.ch

OpenCV (Open Source Compurter Vision Library) ist eine Open-


Source (quelloffen) Bibliothek, die Hunderte Algorithmen der
Computervisionen aufnimmt, die eine BSD Lizenz hat; das heisst , man
kann die Befehle nutzen und ändern. Und es ist kostenlos.

(1) Buch mit allen Befehle dass wir genutz haben.


Optoelektronik 4
LeanXCam

 Erfassung vom Rot. Teil 1

Zuerst soll man einbischen von die Farben erklären. Man werde mit zwei verschiedene
Formate arbeiten: BGR und HSV. BGR-Format ist das Format mit dem LeanXCam arbeitet; aber
trotzdem ist unser Ziel nur einen Farbton (in die ganze Rangstufe) zeigen.

BGR bedeutet: Blue, Green, Red. Das heisst, dies Format arbeitet nur mit reinen
Farben. Das BGR-Format macht alles bei der Mischung dieser dreien Farben. Man kann nicht
das Rot (oder Blau, Gelb…) für die ganze Brillanz und Saturation (ganze Rangstufe) haben. Sieh
Bild (2).

HSV oder HSB bedeutet: Hue, Saturation, Value oder Hue, Saturation, Brightness
beziehungsweise. Wenn H (Farbton) in den richtigen Grenzen einer Farbe gewählt wird, und
werden nicht die Grenzen dieser Farbe von S und V genutzt, hat man was man will. Eine Farbe
für die ganzen Saturation und Brillanz. Sieh Bild (3).

(2) BGR-Format. (3) HSV-Format. Rot.

Deswegen muss man das BGR-Format zu HSV-Format wechseln.

Die Rangstufe vom Rot wird definiert, man kann sehen dass H von 0° bis 360° geht. Mit
Hilfe Paint (Microsoft tools) haben wir die Grenzen gewusst.

Rot geht von ca. 326° bis 360° und von 0° bis 20°.

(4) Hue.

Aber in OpenCV, H geht nicht von 0° bis 360°, sondern von 0° bis 180°. Wir haben H
durch zwei gemacht. Rangstufe vom roten Farbton: 163°-180° und 0°-10°.

Mit Hilfe ein binärer Befehl malt man Weiss diese zwei Rangstufe und den Rest
Schwarz. Das wird in zwei Teilen durchgeführt.

Auf dem Papier, das gegenüber von die Kamera steht, sind alle Farben. Sieh Bild (5)
und (6).

Kann man erklären dass man in 8-bit arbeitet, deswegen schreiben wir 255 (acht 1) um
Weiss zu haben. Sieh Anhang. Teil 1.
Optoelektronik 5
LeanXCam

(5) Oberes Rot.Von 163° zu 180°.

Wir wissen nicht das Warum, aber das Rot ist nur in der zweiten Rangstufe.

(6) Unteres Rot.Von 0° zu 10°.


Optoelektronik 6
LeanXCam

Jetzt haben wir zwei Bilder, die miteinander verbinden werden sollen. Deswegen
macht man die Summe.

(7) Zusammens Rot.

Weiterhin säubern wir das Bild mit


der Hilfe vom Filter. Wo nicht zu viel eins
es gibt, mach den Filter null.

Achtung: Am Anfang haben wir nur


ein Kanal, H, genutzt (in HSV, S und V
haben wir nicht gebraucht), aber um ein
bild zu schauen muss man drei Kanäle
haben, die H könnten sein.

(8) Rot nach “Erode”, den Filter.


Optoelektronik 7
LeanXCam

 Erfassung von Farben. Teil 2.

Hier muss man mit drei Farben arbeiten, statt eins. Die sind Rot, Blau und Gelb.

Man machen das Gleiche dass wir mit dem Rot durchgeführt haben. Jetz auch mit dem
Blau und Gelb. Sieh Bild (9) und (10). Sieh Anhang für die Code.Teil 2.

(9) Blau. Ohne “Erode”. (10) Gelb.Ohne “Erode”.

Danach mussen sich die Bilder gesäubert.

Das Ziel dieses Teils ist einbischen schwiriger.

Man muss der Name der Farben in ein Bild schreiben. Dafür, wenn die dreien Farben
genau erfasst werden, schreiben wir auf der Position jeder Farbe seinen Name.

Um jede Objekt mit Farbe zu sehen, haben wir die Kontur gezeigt. Sieh Bild (11). Da die
Namen auf einem Bild wie das Bild (10), aber auch mit Blau und Rot… nicht klar sehen würden.
Optoelektronik 8
LeanXCam

(11) “Canny” Befehl.

Achtung: Um das Bild zu zeigen, wende man „Canny“ an. Diese Gleichung funktioniert
mit grauer Skala. Sieh Anhang. Teil 2.

Die erfassung von Farben und die Kontur sind schon gemacht.

Die Schwierigkeit kommt, wenn man die Position von den Blauen, Gelben und Roten
Objekten bzw. erfassen will. Die OpenCV-Bibliothek gibt uns die Gelegenheit diesen Prozess zu
vereinfachen. Mit Hilfe einen konkreten Befehl.

Wenn wir die notwendige Koordinaten haben, kann man die Farbnamen darauf
schreiben.

Vorsicht mit dem „Aus-Bild“, man muss die Grenzen mit die Namen zeigen (grauer
Skala), nicht die H Bilden mit die Namen (das war nur um die Farben zu finden). Folglich
machen wir die dreien Kanälen des „Aus-Bilds“, dreimal grau Skala. Wie wir im Teil eins
gemacht haben. Um das korrektes Bild zu schauen.

Zuerst, zum Beispiel, mit dem Blau, danach die anderen. Sieh Bild (12).
Optoelektronik 9
LeanXCam

(12) Name des Blauen Objektes.

Und zum schluss die Ergebnisse. Sieh Bilder (13).

(13)
Optoelektronik 10
LeanXCam

 Anhang

1. Erfassung vom Rot

/* opencv */

#include <cv.h>

#include <leancv.h>

#include <stdio.h>

#include "image_processing.h"

//#include "highgui.h"

//Grenzen

int max=163;

int min=10;

CImageProcessor::CImageProcessor() {

m_tmp_img_data=new
char[3*OSC_CAM_MAX_IMAGE_HEIGHT*OSC_CAM_MAX_IMAGE_WIDTH

+ PICTURE_ALIGNMENT];

m_tmp_img=(char*)CCamera::AlignPicture((uint8*)m_tmp_img_data);

#if defined(OSC_HOST) || defined(OSC_SIM)

fileOrg = "../org";

fileProc = "../proc";

fileRaw = "../test";

#else

fileOrg = "/home/httpd/org";

fileProc = "/home/httpd/proc";

fileRaw = "/home/httpd/test";

#endif

printf("CImageProcessor::CImageProcessor() --> %s\n", fileProc);


Optoelektronik 11
LeanXCam

CImageProcessor::CImageProcessor(CMisc *misc) {

m_tmp_img_data=new

char[3*OSC_CAM_MAX_IMAGE_HEIGHT*OSC_CAM_MAX_IMAGE_WIDTH

+ PICTURE_ALIGNMENT];

m_tmp_img=(char*)CCamera::AlignPicture((uint8*)m_tmp_img_data);

#if defined(OSC_HOST) || defined(OSC_SIM)

fileOrg = "../org";

fileProc = "../proc";

fileRaw = "../test";

#else

fileOrg = "/home/httpd/org";

fileProc = "/home/httpd/proc";

fileRaw = "/home/httpd/test";

#endif

printf("CImageProcessor::CImageProcessor() --> %s\n", fileProc);

this->misc = misc;

CImageProcessor::~CImageProcessor() {

delete[](m_tmp_img_data);

int CImageProcessor::DoProcess(IplImage** image) {

if(!image || !*image) return(EINVALID_PARAMETER);

//CV-Formated Picture Data

IplImage* cvSrc=*image;

IplImage* cvDst = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U, 3);

IplImage* cvHSV = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U, 3);


Optoelektronik 12
LeanXCam

//Man speichert das Bild in HSV Format

IplImage* cvH = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U, 1);

// H Kanal

// Farben - Oben

IplImage* cvHhigh = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U, 1);

//Farben - Unten

IplImage* cvHlow = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U, 1);

// OSC-Formated Picture Data --> for OscVisDebayer !!!

struct OSC_PICTURE oscSrc = {cvSrc->imageData, cvSrc->width, cvSrc->height, (enum


EnOscPictureType)0};

struct OSC_PICTURE oscDst = {cvDst->imageData, cvSrc->width, cvSrc->height, (enum


EnOscPictureType)0};

strcpy(strTemp, fileRaw);

strcat(strTemp, ".bmp");

lcvBmpWrite(cvSrc ,strTemp);

printf("test");

// Debayer Raw Picture to BGR

OscVisDebayer((const uint8*)oscSrc.data, cvSrc->width, cvSrc->height, (EnBayerOrder)0,


(uint8*)oscDst.data);

//do something with img

printf("Width = %d Height = %d imageSize = %d Number of Channels = %d\n", cvSrc->width,


cvSrc->height, cvSrc->imageSize, cvSrc->nChannels);

strcpy(strTemp, fileOrg);

strcat(strTemp, ".bmp");

lcvBmpWrite(cvDst ,strTemp);

// Exposure Time (ms) 0 --> Autoexposure

misc->setExposureTime(30);

/************************* Image Processing **********************************/

// BGR to HSV
Optoelektronik 13
LeanXCam

cvCvtColor(cvDst,cvHSV, CV_BGR2HSV);

// Man braucht nur die Farbe

cvSplit(cvHSV,cvH,NULL,NULL,NULL);

// Rangstufe

cvThreshold(cvH,cvHhigh,max,255,CV_THRESH_BINARY);

// 1 von das max., 0 den Rest

cvThreshold(cvH,cvHlow,min,255,CV_THRESH_BINARY_INV);

// Unten von das min. 1, 0 den Rest

// Bilder zusammenfügen

cvOr(cvHhigh,cvHlow,cvH,NULL);

// Bild zu säubern

cvErode(cvH,cvH,NULL,1);

//1 zu 3 Kanäle

cvMerge(cvH,cvH,cvH,NULL,cvDst);

strcpy(strTemp, fileProc);

strcat(strTemp, ".bmp");

lcvBmpWrite(cvDst, strTemp);

// /lcvReleaseImage(&cvGrey);

lcvReleaseImage(&cvH);

lcvReleaseImage(&cvHhigh);

lcvReleaseImage(&cvHlow);

lcvReleaseImage(&cvDst);

return(SUCCESS);

}
Optoelektronik 14
LeanXCam

2. Erfassung von Farben

/* opencv */

#include <cv.h>

#include <leancv.h>

#include <stdio.h>

#include "image_processing.h"

// #include "highgui.h"

CImageProcessor::CImageProcessor() {

m_tmp_img_data=new

char[3*OSC_CAM_MAX_IMAGE_HEIGHT*OSC_CAM_MAX_IMAGE_WIDTH

+ PICTURE_ALIGNMENT];

m_tmp_img=(char*)CCamera::AlignPicture((uint8*)m_tmp_img_data);

#if defined(OSC_HOST) || defined(OSC_SIM)

fileOrg = "../org";

fileProc = "../proc";

fileRaw = "../test";

#else

fileOrg = "/home/httpd/org";

fileProc = "/home/httpd/proc";

fileRaw = "/home/httpd/test";

#endif

printf("CImageProcessor::CImageProcessor() --> %s\n", fileProc);

CImageProcessor::CImageProcessor(CMisc *misc) {

m_tmp_img_data=new
char[3*OSC_CAM_MAX_IMAGE_HEIGHT*OSC_CAM_MAX_IMAGE_WIDTH

+ PICTURE_ALIGNMENT];
Optoelektronik 15
LeanXCam

m_tmp_img=(char*)CCamera::AlignPicture((uint8*)m_tmp_img_data);

#if defined(OSC_HOST) || defined(OSC_SIM)

fileOrg = "../org";

fileProc = "../proc";

fileRaw = "../test";

#else

fileOrg = "/home/httpd/org";

fileProc = "/home/httpd/proc";

fileRaw = "/home/httpd/test";

#endif

printf("CImageProcessor::CImageProcessor() --> %s\n", fileProc);

this->misc = misc;

CImageProcessor::~CImageProcessor() {

delete[](m_tmp_img_data);

int CImageProcessor::DoProcess(IplImage** image) {

if(!image || !*image) return(EINVALID_PARAMETER);

//CV-Formated Picture Data

IplImage* cvSrc=*image;

IplImage* cvDst = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U, 3);

// Man speichert das Bild in HSV Format

IplImage* cvHSV = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U, 3);

// H Kanal

// Rot - Oben

IplImage* cvH = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U, 1);

IplImage* cvRedhigh = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U,


1);
Optoelektronik 16
LeanXCam

// Rot - Unten

IplImage* cvRedlow = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U,


1);

// Rot

IplImage* cvRed = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U, 1);

// Blau - Oben

IplImage* cvBluehigh = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U,


1);

// Blau - Unten

IplImage* cvBluelow = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U,


1);

// Blau

IplImage* cvBlue = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U, 1);

// Gelb - Oben

IplImage* cvYellowhigh = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height),


IPL_DEPTH_8U, 1);

// Gelb - Unten

IplImage* cvYellowlow = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height),


IPL_DEPTH_8U, 1);

// Gelb

IplImage* cvYellow = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U,


1);

IplImage* cvGrey = lcvCreateImage(cvSize(cvSrc->width, cvSrc->height), IPL_DEPTH_8U, 1);

// OSC-Formated Picture Data --> for OscVisDebayer !!!

struct OSC_PICTURE oscSrc = {cvSrc->imageData, cvSrc->width, cvSrc->height, (enum


EnOscPictureType)0};

struct OSC_PICTURE oscDst = {cvDst->imageData, cvSrc->width, cvSrc->height, (enum


EnOscPictureType)0};

strcpy(strTemp, fileRaw);

strcat(strTemp, ".bmp");
Optoelektronik 17
LeanXCam

lcvBmpWrite(cvSrc ,strTemp);

printf("test");

// Debayer Raw Picture to BGR

OscVisDebayer((const uint8*)oscSrc.data, cvSrc->width, cvSrc->height, (EnBayerOrder)0,


(uint8*)oscDst.data);

//do something with img

printf("Width = %d Height = %d imageSize = %d Number of Channels = %d\n", cvSrc->width,


cvSrc->height, cvSrc->imageSize, cvSrc->nChannels);

strcpy(strTemp, fileOrg);

strcat(strTemp, ".bmp");

lcvBmpWrite(cvDst ,strTemp);

// Exposure Time (ms) 0 --> Autoexposure

misc->setExposureTime(30);

/************************* Image Processing **********************************/

// BGR to HSV

cvCvtColor(cvDst,cvHSV, CV_BGR2HSV);

cvCvtColor(cvDst,cvGrey, CV_BGR2GRAY);

cvCanny(cvGrey, cvGrey, 20, 30, 3);

// Man braucht nur die Farbe

cvSplit(cvHSV,cvH,NULL,NULL,NULL);

// Rangstufe

// Rot

cvThreshold(cvH,cvRedhigh,163,255,CV_THRESH_BINARY;

cvThreshold(cvH,cvRedlow,10,255,CV_THRESH_BINARY_INV

// Blau

cvThreshold(cvH,cvBluehigh,84,255,CV_THRESH_BINARY);

cvThreshold(cvH,cvBluelow,126,255,CV_THRESH_BINARY_INV);
Optoelektronik 18
LeanXCam

// Gelb

cvThreshold(cvH,cvYellowhigh,22,255,CV_THRESH_BINARY);

cvThreshold(cvH,cvYellowlow,35,255,CV_THRESH_BINARY_INV);

// Bilder zusammenfügen

cvOr(cvRedhigh,cvRedlow,cvRed,NULL);

cvAnd(cvBluehigh,cvBluelow,cvBlue,NULL);

cvAnd(cvYellowhigh,cvYellowlow,cvYellow,NULL);

// Bild zu säubern

cvErode(cvRed,cvRed,NULL,1);

cvErode(cvBlue,cvBlue,NULL,1);

cvErode(cvYellow,cvYellow,NULL,1);

// Erfassen der Position des Objekts

CvMoments mR,mB,mY;

cvMoments(cvRed,&mR,true);

cvMoments(cvBlue,&mB,true);

cvMoments(cvYellow,&mY,true);

int posXR=(int)(mR.m10/mR.m00);

int posYR=(int)(mR.m01/mR.m00);

int posXB=(int)(mB.m10/mB.m00);

int posYB=(int)(mB.m01/mB.m00);

int posXY=(int)(mY.m10/mY.m00);

int posYY=(int)(mY.m01/mY.m00);

// 1 zu 3 Kanälen

cvMerge(cvGrey,cvGrey,cvGrey, NULL, cvDst);

// Name den Farben

CvFont font1;

cvInitFont(&font1,CV_FONT_HERSHEY_SCRIPT_SIMPLEX,1.0,0.8,0,1,8);
Optoelektronik 19
LeanXCam

cvPutText(cvDst,"Red",cvPoint(posXR,posYR),&font1,CV_RGB(255,0,0));

cvPutText(cvDst,"Blue",cvPoint(posXB,posYB),&font1,CV_RGB(0,255,255));

cvPutText(cvDst,"Yellow",cvPoint(posXY,posYY),&font1,CV_RGB(255,255,0));

strcpy(strTemp, fileProc);

strcat(strTemp, ".bmp");

lcvBmpWrite(cvDst, strTemp);

lcvReleaseImage(&cvH);

lcvReleaseImage(&cvRedhigh);

lcvReleaseImage(&cvRedlow);

lcvReleaseImage(&cvRed);

lcvReleaseImage(&cvBluehigh);

lcvReleaseImage(&cvBluelow);

lcvReleaseImage(&cvBlue);

lcvReleaseImage(&cvYellowhigh);

lcvReleaseImage(&cvYellowlow);

lcvReleaseImage(&cvYellow);

lcvReleaseImage(&cvDst);

lcvReleaseImage(&cvGrey);

return(SUCCESS);

}
Optoelektronik 20
LeanXCam

 Literaturverzeichnis

https://unpocodejava.wordpress.com/2013/10/09/que-es-opencv/

http://es.wikipedia.org/wiki/OpenCV

http://opencv.org/

http://es.wikipedia.org/wiki/Modelo_de_color_HSV

http://support.robotis.com/en/product/darwinop/operating/color_and_white_balanc
e_calibration.htm

Das Buch: Computer Vision with the OpenCV library.