550 likes | 786 Views
OpenCV alapok. Vámossy Zoltán 2004. Technikai elemek. Software feltételek OpenCV felépítés Adatok Hibakezelés I/O könyvtárak (HighGUI, CvCAM) OpenCV minta programok. Segédletek. Manuál pdf formátumban Help html formátumban
E N D
OpenCV alapok Vámossy Zoltán 2004
Technikai elemek • Software feltételek • OpenCV felépítés • Adatok • Hibakezelés • I/O könyvtárak (HighGUI, CvCAM) • OpenCV minta programok
Segédletek • Manuál pdf formátumban • Help html formátumban • OpenCV archívum és mintaprogramok: http://groups.yahoo.com/group/OpenCV • Hibakezelés • I/O könyvtárak (HighGUI, CvCAM) • OpenCV mintaprogramok
Software feltételek • Win32 platforms: • Win9x/WinNT/Win2000/WinXP/… • C++ Compiler • Visual C++ lehetőleg • DirectX 9.x SDK directshow szűrők esetén • IPL 2.2+ hatékonyabb működés (IPL 2.5, IPP) • Linux/*NIX
OpenCV felépítése OpenCV Open source Open source DShow filters, Demo apps, Scripting Environment Intel Image Processing Library OpenCV(C++ classes, High-level C functions) Switcher Low level C-functions Open source Open source IPP (Optimized low level functions)
OpenCV adatok • Image (IplImage); • Mátrix (CvMat); • Hisztogram (CvHistogram); • Tetszőleges tömb (CvArr) • Fgv. paraméter, futási időben dől el a tömb header első 4 bájtjából, hogy milyen típus valójában • Dinamikus struktúrák (CvSeq, CvSet, CvGraph); • Nyomatékok (CvMoments); • Segéd adattípusok (CvPoint, CvSize, CvTermCriteria, IplConvKernel és mások). Több dimenzióstömb
Hibakezelés • Nincs visszatérő hibakód • Globális hibastruktúra van, amelyet speciális függvényekkel lehet beállítani és ellenőrizni • Alapértelmezésként egy hibaüzenet jelenik meg, ha hiba lépett fel
Portable GUI library (HighGUI) • Képek írása/olvasása (BMP, JPEG, TIFF, PxM, Sun Raster) • Ablakok készítése és azokban képek megjelenítése. HighGUI ablakok emlékeznek a tartalmukra: nem kell nekünk újrarajzolnunk • Egyszerű interaktivitás: trackbar, billentyűzet és egér input kezelése
Portable Video Capture Library (CvCAM) • Videóképek vételezése és visszajátszása Linux és Windows alatt • A kamera, vagy AVI képek feldolgozásához függvényt biztosít • Sztereo képfeldolgozási lehetőséget biztosít 2 USB kamerához
IplImage struktúra typedef struct _IplImage { int nSize; /* sizeof(IplImage) */ int ID; /* version (=0)*/ int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */ int alphaChannel; /* ignored by OpenCV */ int depth; /* pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported */ char colorModel[4]; /* ignored by OpenCV */ char channelSeq[4]; /* ditto */ int dataOrder; /* 0 - interleaved color channels, 1 - separate color channels. cvCreateImage can only create interleaved images */ int origin; /* 0 - top-left origin, 1 - bottom-left origin (Windows bitmaps style) */ int align; /* Alignment of image rows (4 or 8). OpenCV ignores it and uses widthStep instead */ int width; /* image width in pixels */ int height; /* image height in pixels */ struct _IplROI *roi;/* image ROI. when it is not NULL, this specifies image region to process */ struct _IplImage *maskROI; /* must be NULL in OpenCV */ void *imageId; /* ditto */ struct _IplTileInfo *tileInfo; /* ditto */ int imageSize; /* image data size in bytes (=image->height*image->widthStep in case of interleaved data)*/ char *imageData; /* pointer to aligned image data */ int widthStep; /* size of aligned image row in bytes */ int BorderMode[4]; /* border completion mode, ignored by OpenCV */ int BorderConst[4]; /* ditto */ char *imageDataOrigin; /* pointer to a very origin of image data (not necessarily aligned) - it is needed for correct image deallocation */ } IplImage;
OpenCV függvények használata • CvSize Size = cvSize(640, 480); • IplImage *Image1 = cvCreateImage( Size, Depth, Channels); • cvFill(Image1, 0.0); • ... • IplImage *Image2 = cvLoadImage(InFileName, -1); • ... • float mean = cvMean(Image2, NULL); • CvScalar MyScalar = cvScalar(mean); • cvSubS(Image2, MyScalar, Image1); • ... • cvSaveImage(OutFileName, Image1);
cvCreateImage IplImage* cvCreateImage( CvSize size, int depth, int channels ); size - Image szélesség és magasság depth - Bitmélység. Alábbiak egyike: IPL_DEPTH_8U - unsigned 8-bit integers IPL_DEPTH_8S - signed 8-bit integers IPL_DEPTH_16S - signed 16-bit integers IPL_DEPTH_32S - signed 32-bit integers IPL_DEPTH_32F - single precision floating-point numbers IPL_DEPTH_64F - double precision floating-point numbers channels – Pixelenkénti csatornák száma: 1, 2, 3 vagy 4. Színes kép formátuma:b0 g0 r0 b1 g1 r1 ... A cvCreateImage létrehozza a header struktúrát és allokál adatot: header = cvCreateImageHeader(size,depth,channels); cvCreateData(header);
cvReleaseImage Felszabadítja a headertés a kép-adatot void cvReleaseImage( IplImage** image ); image – Dupla pointer a megszüntetendő kép headerjére. A cvReleaseImagea következőt hajtja végre: if( *image ) { cvReleaseData( *image ); cvReleaseImageHeader( image ); }
cvCloneImage A képről másolatot készít IplImage* cvCloneImage( const IplImage* image ); image – Eredeti kép A cvCloneImage a képről teljes másolatot készít, beleértve a header-t, a ROI-tés az adatokat
cvSetImageCOI Beállítja valamelyik csatornát void cvSetImageCOI( IplImage* image, int coi ); image – Kép header coi – A csatorna A cvSetImageCOI beállítja a paraméterként megadott csatornát. 0 esetén minden csatorna kiválasztott, 1 esetében az első csatorna kiválasztott, stb.Ha ROI NULL és coi != 0, akkor ROI allokálásra kerül. Sok OpenCV függvény nem veszi figyelembe ezt a beállítást. Ha külön csatornákat akarunk feldolgozni, akkor másoljuk a csatornát (cvCopy vagy cvCvtPixToPlane) külön képbe, ott dolgozzuk fel, majd másoljuk vissza az eredményt (cvCopy vagy cvCvtPlaneToPix).
cvGetImageCOI A kiválasztott csatorna számát adja int cvGetImageCOI( const IplImage* image ); image - Image header A cvGetImageCOI ha 0-val tér vissza, akkor minden csatorna kiválasztott.
cvSetImageROI Beállítja a ROI-t (Region Of Interest)az adott téglalapra void cvSetImageROI( IplImage* image, CvRect rect ); image - Image header rect - ROI téglalap A cvSetImageROI beállítja a kép ROI-t az adott téglalapra. Ha ROI NULL és a rect paraméter nem egyenlő az egész képpel, akkor allokálódik ROI. Szemben a COI-val, a legtöbb OpenCV függvény valóban használja a ROI-tés mint elkülönített képet kezeli (A ROI sarkától számolja pl. a koordinátákat.)
cvResetImageROI Felszabadítja a kép ROI-t void cvResetImageROI( IplImage* image, CvRect rect ); image - Image header rect - ROI téglalap A cvResetImageROI hívása után a teljes kép a kiválasztott Hasonlót eredményez: cvSetImageROI( image, cvRect( 0, 0, image->width, image->height )); cvSetImageCOI( image, 0 ); De ez utóbbi nem szabadítja fel az image->roi - t.
cvGetImageROI Visszatér a ROI koordinátáival CvRect cvGetImageROI( const IplImage* image ); image - Image header. A cvGetImageROI visszatér a cvRect(0,0,image->width,image->height) téglalappal, ha nincs ROI.
Pixel elérés (Get Pixel) • 0 bázisú koordináták kép origótól: img->origin=IPL_ORIGIN_TL vagy img->origin=IPL_ORIGIN_BL • // pixel (X, Y) szürke kép unsigned char P; P =((uchar*)(Im->imageData + Im- >widthStep*Y))[X]; • // pixel (X, Y) színes kép unsigned char B, G, R; B=((uchar*)(Im->imageData + Im->widthStep*Y))[X*3 ]; G=((uchar*)(Im->imageData + Im-widthStep*Y))[X*3+1]; R=((uchar*)(Im->imageData + Im->widthStep*Y))[X*3+2];
Pixel elérés (Set Pixel) • // pixel (X, Y) gray Image unsigned char P; … ((uchar*)(Im->imageData + Im->widthStep*Y))[X] = P; • // pixel (X, Y) color Image unsigned char B, G, R; … ((uchar*)(Im->imageData + Im->widthStep*Y))[X*3 ] = B; ((uchar*)(Im->imageData + Im->widthStep*Y))[X*3 + 1] = G; ((uchar*)(Im->imageData + Im->widthStep*Y))[X*3 + 2] = R;
Pixel elérés (példa) • A (100,100) pont intenzitásának növelése 30-cal: CvPoint pt = {100,100}; ((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3] += 30; ((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3+1] += 30; ((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3+2] += 30;
Pixel elérés (példa) • Előző hatékonyabban: CvPoint pt = {100,100}; uchar* temp_ptr = &((uchar*)(img->imageData + img->widthStep*pt.y))[x*3]; temp_ptr[0] += 30; temp_ptr[1] += 30; temp_ptr[2] += 30;
Pixel elérés • 32-bit floating point, 1-channel image I (IplImage* img): I(x,y) ~ ((float*)(img->imageData + img->widthStep*y))[x]
HighGUI használat Képkezelés függvényei
cvLoadImage Betölt fájlból egy képet IplImage* cvLoadImage( const char* filename, int iscolor CV_DEFAULT(1)); filename – Betöltendő fájl iscolor Ha >0, a betöltött kép 3 csatornás lesz; Ha 0, a betöltött kép 1 csatornás lesz; Ha <0, a betöltött kép csatornái megmaradnak eredetinek. A cvLoadImage betöltés után a képre mutató pointert ad vissza. Lehetséges formátumok: Windows bitmaps - BMP, DIB; JPEG files - JPEG, JPG, JPE; Portable Network Graphics - PNG; Portable image format - PBM, PGM, PPM; Sun rasters - SR, RAS; TIFF files - TIFF, TIF. Ha a "filename" nem tartalmaz elérési utat, akkor az aktuális könyvtárban, vagy a cvAddSearchPath által meghatározott könyvtárban keres.
cvSaveImage Kép fájlba mentése int cvSaveImage( const char* filename, const CvArr* image ); filename - fájlnév image - Kép
cvConvertImage Képet konvertál és ha kell tükröz void cvConvertImage( const CvArr* src, CvArr* dst, int flip CV_DEFAULT(0)); src - Forrás dst - Cél flip 1 – függőleges tükrözés, 0 - nincs. A cvConvertImage ugyanazt a konverziót hajtja végre – esetleges tükrözésen kívül, mint a cvCvtColor,de automatikusan figyelembe veszi a formátumokat.
HighGUI használat Ablak függvények
cvNamedWindow Ablak létrehozása int cvNamedWindow( const char* name, unsigned long flags); name – Ablak neve, amely azonosít és megjelenik. flags – Ablak tulajdonságok. A CV_WINDOW_AUTOSIZE használatával az automatikus méretezés beállítható, egyébként 0. A cvNamedWindow létrehoz egy ablakot, amiben a kép és trackbar megjelenhet, a nevével tudunk rá hivatkozni.
cvDestroyWindow Ablak megszüntetése void cvDestroyWindow( const char* name ); name – Ablak neve.
cvResizeWindow Ablak méreteket állít void cvResizeWindow( const char* name, int width, int height); name – Méretezendő ablak. width – Új szélesség height – Új magasság
cvGetWindowHandle Az adott nevű ablaknak a window handle-jét adja vissza. void* cvGetWindowHandle( const char* name ); name - ablaknév A cvGetWindowHandle visszatér a window handle-lel (HWND Win32 esetén és Widget, ha X Window).
cvGetWindowName Handle alapján nevet szolgáltat const char* cvGetWindowName( void* window_handle ); window_handle – Handle.
cvShowImage Kép megjelenítése ablakban. void cvShowImage( const char* name, const CvArr* image ); name – Ablak neve image – A megjelenítendő kép A cvShowImage megjeleníti a képet, ha CV_WINDOW_AUTOSIZE flag be volt állítva, akkor átméretezi az ablakot, egyébként skáláz.
Kép betöltés és megjelenítés /* használat: prog <image_name> */ #include "cv.h" #include "highgui.h" int main( int argc, char** argv ) { IplImage* img; if( argc == 2 && (img = cvLoadImage( argv[1], 1)) != 0 ) { cvNamedWindow( "Image view", 1 ); cvShowImage( "Image view", img ); cvWaitKey(0); // fontos cvDestroyWindow( "Image view" ); cvReleaseImage( &img ); return 0; } return -1; }
OpenCV installálás • http://sourceforge.net/projects/opencvlibrary • View all project Files – on tovább: • opencv-win: OpenCV 1.0.exe • Exe futtatása
Környezeti változók beállítása • Start | Beállítások | Vezérlő pult | Rendszer | Speciális | Környezeti változók • Új változó: OPENCV érték: ahova installáltuk, pl: C:\Program Files\OpenCv • Path kiegészítése: C:\Program Files\Microsoft Visual Studio 8\Vc\bin, valamint C:\Program Files\OpenCv\bin • Újraindítás
Fejlesztés környezeten kívül • Start | Programok | Microsoft Visual Studio 2005 | Visual Studio Tools | Visual Studio 2005 Command Prompt • Javasolt külön könyvtárba helyezni minden feladatot • A programunkat írjuk meg a szövegszerkesztőben • Készítsünk make fájlt (pl. Xfeladat.vc) • nmake –f makefile (nmake –f Xfeladat.vc) • Futtatás • Az OpenCV-s dll-ek a path-ban legyenek, vagy az aktuális könyvtárban • Preferált módszer a jelenlegi fejlesztésekhez
Make (példa VC) CXX = cl LINK = link OPENCV=c:\Program Files\OpenCV VS=C:\Program Files\Microsoft Visual Studio 8\VC INC=/I LIB=/L CXXFLAGS0= LINK1= LINK2=/link "/libpath:$(OPENCV)\lib" cv.lib cvaux.lib highgui.lib cxcore.lib ml.lib cvcam.lib LIBS = "/libpath:$(VS)\lib" kernel32.lib OUT=/Fe PRFILE=elso CXXFLAGS = $(CXXFLAGS0) $(INC)"$(OPENCV)\cv\include" $(INC)"$(OPENCV)\otherlibs\highgui" $(INC)"$(OPENCV)\cvaux\include" $(INC)"$(OPENCV)\cxcore\include" all: $(PRFILE).exe clean: del $(PRFILE).exe *.tds $(PRFILE).obj *.o *.out $(PRFILE).exe: $(PRFILE).cpp $(PRFILE).vc $(CXX) $(CXXFLAGS) $(LINK1) $(OUT)$(PRFILE).exe $(PRFILE).cpp $(LINK2) $(LINK3) $(LIBS)
Make (Borland) – más lib és obj!!! CXX=bcc32 INC=-I LIB=-L CXXFLAGS0= -w-par- LINK1=-L"..\..\lib" LINK2=cv.lib cvaux.lib highgui.lib OUT=-e CXXFLAGS = $(CXXFLAGS0) $(INC)"..\..\cv\include" $(INC)"..\..\otherlibs\highgui" $(INC)"..\..\cvaux\include" SFILE = elso all: $(SFILE).exe clean: del $(SFILE).exe *.tds $(SFILE).obj *.o *.out $(SFILE).exe: $(SFILE).cpp $(CXX) $(CXXFLAGS) $(LINK1) $(OUT)$(SFILE).exe $(SFILE).cpp $(LINK2)
Példaprogram 1. #include "cv.h" // includes OpenCV definitions #include "highgui.h" // includes highGUI definitions #include <stdio.h>// includes C standard input/output definitions int main() { IplImage *cvImg; // image used for visualisation CvSize imgSize; // size of visualisation image int i = 0, j = 0; imgSize.width = 640; // visualisation image is imgSize.height = 480; // 640x480 pixels cvImg = cvCreateImage( imgSize, 8, 1 ); // creation of a 8 bits depth gray image // image is filled with gray values corresponding to the 256 modulus of their position in it for ( i = 0; i < imgSize.width; i++ ) for ( j = 0; j < imgSize.height; j++ ) ((uchar*)(cvImg->imageData + cvImg->widthStep*j))[i] = ( char ) ( ( i * j ) % 256 ); cvNamedWindow( "Testing OpenCV...", 1 ); // creation of a visualisation window cvShowImage( "Testing OpenCV...", cvImg ); // image visualisation cvWaitKey( 0 ); // wait for key cvDestroyWindow( "image" ); // close window cvReleaseImage( &cvImg ); // memory release before exit return( 0 ); }
Make használat • Borland • make –f “makefile” • Visual Studio • nmake –f “makefile” • Futatáshoz a dll-ek elérhetőek legyenek!
Példaprogram 2. #include "cv.h" #include "highgui.h" #include <stdio.h> char name0[] = "test2004.bmp"; char name1[] = "test2004.jpg"; int main() { IplImage* img0 = NULL; IplImage* img1 = NULL; img0 = cvLoadImage( name0, -1 ); img1 = cvLoadImage( name1, -1 ); cvNamedWindow( "image0", 1 ); cvNamedWindow( "image1", 1 ); cvShowImage( "image0", img0 ); cvShowImage( "image1", img1 ); cvWaitKey(0); cvReleaseImage( &img0 ); cvReleaseImage( &img1 ); return(0); }
Példaprogram 3. int main() { IplImage* img0 = NULL; IplImage* img1 = NULL; IplImage* res = NULL; CvSize imgSize; img0 = cvLoadImage( name0, -1 ); img1 = cvLoadImage( name1, -1 ); imgSize.width = img0->width; imgSize.height = img0->height; res = cvCreateImage( imgSize, 8, 3 ); cvSub( img0, img1, res, 0 );// substract img0 from img1 and store the result in res cvConvertScale( res, res, 30, 0 ); // scale result cvNamedWindow( "image", 1 ); cvShowImage( "image", res ); cvWaitKey(0); cvReleaseImage( &img0 ); cvReleaseImage( &img1 ); cvReleaseImage( &res ); return(0); }
Példaprogram 4. int main() { IplImage* img = NULL; IplImage* res = NULL; CvSize imgSize; img = cvLoadImage( name, -1 ); imgSize.width = img->width; imgSize.height = img->height; res = cvCreateImage( imgSize, img->depth, img->nChannels ); cvCvtColor( img, res, CV_RGB2HSV ); // color conversion RGB to HSV cvNamedWindow( "image", 1 ); cvShowImage( "image", res ); cvWaitKey(0); cvReleaseImage( &img ); cvReleaseImage( &res ); return(0); }
Visual Studio 2005 beállítás • Néhány célszerű alapbeállítás a környezetben Tools | Options | Projects and Solutions | VC++ Directories | Show directories for: Include files: ELSŐ LEGYEN!: …\DXSDK\Samples\C++\DirectShow\Baseclasses $(OPENCV)\cv\include $(OPENCV)\cvaux\include $(OPENCV)\ml\include $(OPENCV)\cxcore\include és $(OPENCV)\otherlibs\highgui, (esetleg cvcam) valamint …\Intel\Iplsuite\include, ha az ipl-t telepítettük, vagy …\ipp\include
Visual Studio .NET 2003 beállítás • Néhány célszerű alapbeállítás a környezetben Tools | Options | Projects | VC++ Directories | Show directories for: Library files: …\DXSDK\Samples\C++\DirectShow\Baseclasses\Debug – ha újrafordítjuk majd!!! $(OPENCV)\lib valamint …\Intel\Iplsuite\lib\msvc, ha az ipl-t telepítettük, vagy …\IPP\lib