240 likes | 248 Views
Understand CvPoint, CvSize, CvRect, and CvScalar in OpenCV. Explore CvMat data structure, matrix operations, and image drawing with examples.
E N D
Chapter3 Getting to Know OpenCV OpenCV Primitive Data Types CvMat Matrix Structure IplImage Data Structure Matrix and Image Operators Drawing Things Data Persistence 1/37
Example OpenCV Primitive Data Types • OpenCV has several primitive data types : CvPoint, CvSize, CvRect, CvScalar. • CvPoint : a simple structure with two integer num. x and y. CvPoint has two siblings:CvPoint2D32f and CvPoint3D32f • CvSize : its member are width and height, which are both integers. If want floating-point numbers, use CvSize’s cousin CvSize2D32f. • CvRect : another child of CvPoint and CvSize(x,y,width,height). • CvScalar : a set of four double-precision numbers. void CVisionTestDlg::OnCh301() { CvSize initSize = cvSize(600,400); IplImage *img = cvCreateImage( initSize, IPL_DEPTH_8U, 3); cvNamedWindow("Rectangle", CV_WINDOW_AUTOSIZE); cvRectangle(img, cvPoint(100,100), cvPoint(300,200), cvScalar(255,0,0)); cvShowImage("Rectangle", img); cvWaitKey(0); //대기 cvReleaseImage(&img); //메모리 해제 cvDestroyWindow("Rectangle"); }
Structure Function Example void CVisionTestDlg::OnCh302() { CvMat* rot_mat = cvCreateMat(2,3,CV_32FC1); IplImage *src, *dst; char *dstWin = "Rotate Image"; //표시할 창의 이름 지정 char *readFileName =getFileDialog(); //파일을 읽어서 src로 할당 if(!readFileName) return; src = cvLoadImage(readFileName, CV_LOAD_IMAGE_UNCHANGED); dst = cvCloneImage(src); //dst image 생성 dst->origin = src->origin; //원점 복사 cvZero(dst); CvPoint2D32f center = cvPoint2D32f(src->width/2, src->height/2); //회전 중심 double angle = 0.0 , scale = 1.0; //회전각도, 스케일 지정 for(;;){ cv2DRotationMatrix(center, angle, scale, rot_mat); //Rotation Matrix를 정의 cvWarpAffine(src, dst, rot_mat); //Do the transformation angle += 10.0; char c = cvWaitKey(100); if(c==27) break; cvNamedWindow(dstWin, 0); //실행 결과 창에 표시 cvShowImage(dstWin, dst); } cvReleaseImage(&dst); //메모리 해제 cvReleaseMat(&rot_mat); cvDestroyWindow(dstWin); } CvMat Matrix Structure • There is no “vector” construct in OpenCV. Use a matrix with one column. • The concept of a matrix in OpenCV is somewhat more abstract than the concept you learned in your linear algebra class. • the routine that create a new two-dimensional matix cvMat* cvCreateMat ( int rows, int cols, int type ); • type can be any of a long list of predefined types of the form : CV_<bit_depth>(S|U|F)C<number_of_channels> ex) 32-bit floats : CV_32FC1. unsigned integer 8-bit triplets : CV_8UC3. • the structure of CvMat CvArr CvMat IplImage typedef struct CvMat { int type; int step; int* refcount; //for internal use only union { uchar* ptr; short* s; int* i; float* fl; double* db; } data; union { int rows; int height; }; union { int cols; int width; }; } CvMat; CvCreateMat() cvCreateMatHeader() and cvCreateData() cvCloneMat(cvMat*) cvInitMatHeader(cvMat*,rows, cols, type, data, step) cvReleaseMat(CvMat**)
Example Example Example CvMat* mat = cvCreateMat( 5, 5, CV_32FC1 ); float element_3_2 = CV_MAT_ELEM( *mat, float, 3, 2 ); CvMat* mat = cvCreateMat( 5, 5, CV_32FC1 ); float element_3_2 = 7.7; *( (float*)CV_MAT_ELEM_PTR( *mat, 3, 2 ) ) = element_3_2; uchar* cvPtr1D( const CvArr* arr, int idx0, int* type = NULL ); uchar* cvPtr2D( const CvArr* arr, int idx0, int idx1, int* type = NULL ); : uchar* cvPtrND( const CvArr* arr, int* idx, int* type = NULL int create_node = 1, unsigned* precalc_hashval =NULL ); float sum( const CvMat* mat ) { float s = 0.0f; for(int row=0; row<mat->rows, row++) { const float* ptr = (const float*)(mat->data.ptr + row * mat->step); for(col=0; col<mat->cols; col++) { s += *ptr++; } } return(s); } double cvGetReal1D( const CvArr* arr, int idx0 ); double cvGetReal2D( const CvArr* arr, int idx0, int idx1 ); double cvGetReal3D( const CvArr* arr, int idx0, idx1, idx2 ); double cvGetRealND( const CvArr* arr, int* idx ); CvScalar cvGet1D( const CvArr* arr, int idx0 ); CvScalar cvGet2D( const CvArr* arr, int idx0, idx1 ); CvScalar cvGet3D( const CvArr* arr, int idx0, idx1, idx2 ); CvScalar cvGetND( const CvArr* arr, int* idx ); void cvSetReal1D( CvArr* arr, int idx0, double value ); void cvSetReal1D( CvArr* arr, int idx0, CvScalar value ); : void cvSetRealND( CvArr* arr, int* idx, double value ); void cvSetRealND( CvArr* arr, int* idx, CvScalar value ); Accessing Data in Your Matrix • The three way to access the data in the matrix :easy, hard, right way. • The easy way : are suitable only for accessing one- and two-dim. arrays. CV_MAT_ELEM( ), CV_MAT_ELEM_PTR( ). • The hard way : for accessing data in a general N-dim. matrix. cvPtr*D, cvGet*D… • The right way
void CVisionTestDlg::OnCh303() { IplImage *src1, *src2; //Create IPLImage Structure CvRect int_rect; //ROI에 필요한 사각형 크기 정의 int_rect = cvRect(100,100,400,300); src1 = cvLoadImage("testImg.jpg"); //이미지 불러오기 src2 = cvLoadImage("image01.jpg"); if(!src1) return; //이미지가 없으면 종료 cvNamedWindow("Source1", 1); //불러온 이미지 보여주기 cvShowImage("Source1", src1); cvNamedWindow("Source2", 1); cvShowImage("Source2", src2); cvSetImageROI(src1, cvRect(100,100,400,300)); //첫번째 이미지의 ROI 지정 cvSetImageROI(src2, int_rect); //두번째 이미지의 ROI 지정 cvAdd(src1, src2, src1); //두 이미지를 Add하여 첫째 이미지에 저장 cvResetImageROI(src1); //ROI 해제 cvResetImageROI(src2); cvNamedWindow("Result", 1); //결과 표시 cvShowImage("Result", src1); cvWaitKey(0); cvReleaseImage(&src1); //메모리 해제 & 윈도우 제거 cvReleaseImage(&src2); cvDestroyWindow("Source1"); cvDestroyWindow("Source2"); cvDestroyWindow("Result"); } Structure Example IplImage Data Structure • Originally defined as part of Intel’s Image Processing Library(IPL) • Definition of the IplImage structure typedef struct_IplImage { int nSize;int ID; int nChannels; int alphaChannel; int depth; char colorModel[4]; char channelSeq[4]; int dataOrder; int origin; int align; int width; int height; struct _IplROI* roi; struct _IplImage* maskROI; void* imageId; struct _IplTileInfo* tileInfo; int imageSize; char* imageData; int widthStep; int BorderMode[4]; int BorderConst[4]; char* ImageDataOrigin; } IplImage; • 1(gray),2,3(RGB),4(RGBA) • IPL_DATA_ORDER_PIXEL or IPL_DATA_ORDER_PLANE • IPL_ORIGIN_TL or IPL_ORIGIN_BL • region of interest(ROI), IplROI contains xoffset, yoffset, height, width, coi • a pointer to the first row of image data • the number of bypes between points in the same column and successive rows
Drawing Things • To draw some kind of picture on top of an image, OpenCV provides functions that will allow us to make lines, squares, circles, and the like. • Lines : cvLine() • Circle and Ellipses : cvCircle(), cvEllipse(), cvEllipseBox() • Polygons : cvFillPoly(), cvFillConvexPoly() • Fonts and Text : cvPutText(), cvInitFont()
Function Example void cvLine( CvArr* array, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness = 1, int connectivity = 8 ); void draw_line( IplImage* img, CvPoint a, CvPoint b ) { cvLine ( img, pt1, pt2, cvScalar(255,0,0), 2 ); } void CVisionTestDlg::OnCh304() { IplImage* image = cvCreateImage( cvSize(500,500),IPL_DEPTH_8U,3); cvZero( image ); IplImage* temp = cvCloneImage( image ); g_mode = 1; cvNamedWindow( "Drawing Example" ); cvSetMouseCallback("Drawing Example", my_mouse_callback, (void*) image); while( 1 ) { cvCopyImage( image, temp ); if( drawing_thing ) draw_line( temp, pt1, pt2 ); cvShowImage( "Drawing Example", temp ); if( cvWaitKey( 15 )==27 ) break; } cvReleaseImage( &image ); cvReleaseImage( &temp ); cvDestroyWindow( "Drawing Example" ); } Lines • The simplest of these routines just draw a line by the Bresenham algorithm. • IplImage* image pointer • CvPoint(int x, int y) 좌표 • Optional. • Connectivity sets the anti-aliasing mode • 8 : nice, smooth, anti-aliasing • 4 : be blocky and chunky.
Function void cvCircle ( CvArr* array, CvPoint center, int radius, CvScalar color, int thickness = 1, int connectivity = 8 ); void cvEllipse( void cvEllipseBox( CvArr* array, CvArr* array, CvPoint center, CvBox2D box, CvSize axes, CvScalar color, double angle, int thickness = 1, double end_angle, int line_type = 8, CvScalar color, int shift = 0 int thickness = 1, ); int line_type = 8 ); Circles and Ellipses • cvCircle(), cvEllipse(), cvEllipseBox() • IplImage* image pointer • CV_FILL : 내부 Fill
Function void cvFillPoly( CvArr* img, CvPoint** pts, int* npts, int contours, CvScalar color, int line_type = 8 ); void cvFillConvexPoly( CvArr* img, CvPoint** pts, int npts, CvScalar color, int line_type = 8 ); void cvPolyLine( CvArr* img, CvPoint** pts, int* npts, int contours, int is_closed, CvScalar color, int thickness = 1, int line_type = 8 ); Polygons • cvFillPoly(), cvFillConvexPoly(), cvPolyLine() • The points are provided as an array of CvPoint structures. • to draw many polygons in a single call. • npts is an array of point counts, one for each polygon to be drawn • cvFillConvexPoly() works like cvFillPoly() except it draws only one polygon at a time and can draw only convex polygons. • This takes the same arguments as cvFillPoly() • This function that only the polygon edges are drawn. • this function is much faster than cvFillPoly().
Function Example void cvPutText( CvArr* img, const char* text, CvPoint origin, const CvFont* font, CvScalar color ); void cvInitFont( CvFont* font, int font_face, double hscale, double vscale, double shear = 0, int thickness = 1, int line_type = 8 ); void CVisionTestDlg::OnCh306() { g_mode = 6; IplImage* image = cvCreateImage( cvSize(500,500),IPL_DEPTH_8U,3); cvZero( image ); IplImage* temp = cvCloneImage( image ); CvFont* font=new CvFont; // font 구조체를 새로 만들어 정의 cvInitFont(font, CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0); //font 초기화 cvNamedWindow( "Drawing Example" ); CString sampleText = "Welcome to OpenCV World!!!"; cvSetMouseCallback("Drawing Example", my_mouse_callback, (void*) image); while( 1 ) { cvCopyImage( image, temp ); if( drawing_thing ) cvPutText(temp, sampleText, pt1, font, CV_RGB(255,255,0)); //화면에 문장을 씀 cvShowImage( "Drawing Example", temp ); if( cvWaitKey( 15 )==27 ) break; } cvReleaseImage( &image ); cvReleaseImage( &temp ); cvDestroyWindow( "Drawing Example" ); } Fonts and Text • OpenCV has one main routine, called cvPutText() that just throws some text onto an image. • The text indicated by text is printed with its lower-left corner of the text box at origin and in the color indicated by color.
Chapter4 HighGUI A Portable Graphics Toolkit Creating a Window Loading an Image Diplaying Images Mouse Events Drawing Things Sliders, Trackbars, and Switches Working with Video Reading Video Writing Video Convert Image 12/37
A Portable Graphics Toolkit • HighGUI allows us to open windows, to display images, to read and write graphic-related files, and handle simple mouse, pointer, and keyboard events. • HighGUI Lib. divided into 3 parts : hardware, file system, GUI. • Hardware : concerned with the operation of cameras. • File system : loading and saving images. • GUI : to open a window and throw an image into that window. And to register and respond to mouse and keyboard events on that window
Example Function Creating a Window • Show an image on the screen using HighGUI. int cvNamedWindow( const char* name, int flags = CV_WINDOW_AUTOSIZE ); cvDestroyWindow(name); void cvResizeWindow( const char* name, int width, int height ); • resizes the window to fit the image • if flags=0, user can resize the window as they wish. • to resize a window, call cvResizeWindow(); void CVisionTestDlg::OnCh201() { char *readFileName =getFileDialog(); //파일을 읽어서 src로 할당 if(!readFileName) return; IplImage *img = cvLoadImage(readFileName); //이미지를 저장할 배열 생성 cvNamedWindow( "Example1", CV_WINDOW_AUTOSIZE );//창 생성(이름, 옵션) cvShowImage( "Example1", img ); //창에 이미지를 표시 cvWaitKey(0); //버튼을 누를 때까지 대기 cvReleaseImage( &img ); //메모리 해제 cvDestroyWindow("Example1"); //창 제거 }
Example Function Loading an Image • The function for loading an image is cvLoadImage( ). • When opening an image, cvLoadImage() does not look at the file extension. Instead, it analyzes the first few bypes of the file and determines the appropriate codec using that. IplImage* cvLoadImage( const char* filename, int iscolor = CV_LOAD_IMAGE_COLOR ); int cvSaveImage( const char* filename, const CvArr* image ); • CV_LOAD_IMAGE_COLOR • CV_LOAD_IMAGE_ANYDEPTH • CV_LOAD_IMAGE_GRAYSCALE • CV_LOAD_IMAGE_UNCHANGED void CVisionTestDlg::OnCh201() { char *readFileName =getFileDialog(); //파일을 읽어서 src로 할당 if(!readFileName) return; IplImage *img = cvLoadImage(readFileName); //이미지를 저장할 배열 생성 cvNamedWindow( "Example1", 1 ); //창 생성(이름, 옵션) cvShowImage( "Example1", img ); //창에 이미지를 표시 cvWaitKey(0); cvSaveImage(“test.jpg”, img); //img를 파일로 저장 cvReleaseImage( &img ); //메모리 해제 cvDestroyWindow("Example1"); //창 제거 }
Example Function Displaying Images • The function for displaying images is cvShowImage( ). void cvShowImage( const char* filename, const CvArr* image ); void cvMoveWindow(const char* name, int x, int y); void cvDestroyAllWindows(void); int cvStartWindowThread(void); • move a window on the screen so that its upper left corner is positioned at x,y • close all of the windows and de-allocates the associated memory. • On Linux and MacOS, this function tried to start a thread that updates the window automatically and handles resizing and so forth. void CVisionTestDlg::OnCh201() { char *readFileName =getFileDialog(); //파일을 읽어서 src로 할당 if(!readFileName) return; IplImage *img = cvLoadImage(readFileName); //이미지를 저장할 배열 생성 cvNamedWindow( "Example1", 1 ); //창 생성(이름, 옵션) cvShowImage( "Example1", img ); //창에 이미지를 표시 cvWaitKey(0); cvSaveImage(“test.jpg”, img); //img를 파일로 저장 cvReleaseImage( &img ); //메모리 해제 cvDestroyWindow("Example1"); //창 제거 }
Function Mouse Events • Mouse events are handled by a more typical callback mechanism. • To response to mouse click, first write a callback routine that OpenCV can call whenever a mouse event occurs. • Functions : cvMouseCallback(), cvSetMouseCallback() • callback function • void cvMouseCallback( • int event, • int x, • int y, • int flags, • void* param • ); • function that registers the callback • void cvSetMouseCallback( • const char* window_name, • CvMouseCallback on_mouse, • void* param = NULL • );
void my_mouse_callback( int event, int x, int y, int flags, void* param ); CvRect box; bool drawing_box = false; void CVisionTestDlg::OnCh401() { box = cvRect(-1,-1,0,0); // box변수에 초기값 지정 IplImage* image = cvCreateImage( // 500x400 크기의 윈도우생성 cvSize(500,400), IPL_DEPTH_8U, 3 ); //depth=8bit, 3채널(color) cvZero( image ); // image에 0값을 대입=검정색으로 처리 IplImage* temp = cvCloneImage( image ); // temp 복사 cvNamedWindow( "Box Example" ); // 창 생성 cvSetMouseCallback( "Box Example", // Mouse Callback 함수 등록 my_mouse_callback, (void*) image ); while( 1 ) { //image를 temp로 복사하고, box를 그린후 cvCopyImage( image, temp ); if( drawing_box ) draw_box( temp, box ); //temp에 사각형을 그린 후 cvShowImage( "Box Example", temp ); // 창에 보여주기 if( cvWaitKey( 15 )==27 ) break; //ESC를 누르면 종료 } cvReleaseImage( &image ); // 메모리 할당 해제, 창 제거 cvReleaseImage( &temp ); cvDestroyWindow( "Box Example" ); } Example Mouse Events • Functions : cvMouseCallback(), cvSetMouseCallback() void my_mouse_callback( int event, int x, int y, int flags, void* param ) { IplImage* image = (IplImage*) param; switch( event ) { case CV_EVENT_MOUSEMOVE: { if( drawing_box ) { box.width = x-box.x; box.height = y-box.y; } } break; case CV_EVENT_LBUTTONDOWN: { drawing_box = true; box = cvRect( x, y, 0, 0 ); } break; case CV_EVENT_LBUTTONUP: { drawing_box = false; if( box.width<0 ) { box.x+=box.width; box.width *=-1; } if( box.height<0 ) { box.y+=box.height; box.height*=-1; } draw_box( image, box ); } break; } }
Function Sliders, Trackbars, and Switches • In HighGUI, sliders are called tackbars. • The HighGUI routine for creating a trackbar is cvCreateTrackbar(). • A callback function is automatically called whenever the slider is moved. And the callback is not actually required, so if you don’t want a callback, you cal set the cvTrackbarCallback value to NULL. int cvCreateTrackbar( const char* trackbar_name, const char* window_name, int* value, int count, cvTrackbarCallback on_change ); int cvGetTrackbarPos( const char* trackbar_name, const char* window_name, ); int cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos );
Example No Buttons • HighGUI does not provide any explicit support for buttons. • Switches are just sliders(trackbars) that have only two positions, “on”(1) and “off”(0). void CVisionTestDlg::OnCh402() { IplImage *frame; //To hold movie images int switch_value = 1; CvCapture* capture = NULL; capture = cvCreateFileCapture("example2.avi"); cvNamedWindow( "Example4_2", 1 ); // Name the main window // Create the trackbar. We give it a name, and tell it the name of the parent window. cvCreateTrackbar("Switch", "Example4_2", &switch_value, 1, NULL ); // This will just cause OpenCV to idle until someone hits the "Escape" key. while( 1 ) { if(switch_value){ frame = cvQueryFrame( capture ); if( !frame ) break; } cvShowImage( "Example4_2", frame); if(cvWaitKey(100)==27 ) break; } cvReleaseCapture( &capture ); //CLEAN UP cvDestroyWindow( "Example4_2" ); }
Function Working with Video • CvCapture contains the information needed for reading frames from a camera or video file CvCapture* cvCreateFileCapture( const char* filename ); CvCapture* cvCreateCameraCapture( int index ); ex) CvCapture* cvCreateCameraCapture( CV_CAP_FIREWIRE );
Function Example Reading Video • cvGrabFrame(), cvRetrieveFrame(), cvQueryFrame(), cvGetCaptureProperty(), cvSetCaptureProperty() int cvGrabFrame( CvCapture* capture ); IplImage* cvRetrieveFrame( CvCapture* capture ); IplImage* cvQueryFrame( CvCapture* capture ); void cvReleaseCapture( CvCapture** capture ); double cvGetCaptureProperty( CvCapture* capture, int property_id ); int cvSetCaptureProperty( CvCapture* capture, int property_id, double value ); while(1) { int gF = cvGrabFrame(capture); if(!gF) break; frame = cvRetrieveFrame(capture); cvShowImage("Video Property", frame); char c = cvWaitKey(100); if(c==27) break; }
Function Example Writing Video • cvCreateVideoWriter(), cvWriteFrame(), cvReleaseVideoWriter() CvVideoWriter* cvCreateVideoWriter( int cvWriteFrame( const char* filename, CvVideoWriter* writer, int fourcc, const IplImage* image double fps, ); CvSize frame_size, int is_color = 1 void cvReleaseVideoWriter( ); CvVideoWriter** writer ); void CVisionTestDlg::OnCh403() { cvNamedWindow("Convert a video", CV_WINDOW_AUTOSIZE); CvCapture* capture = cvCreateFileCapture("example2.avi"); IplImage* bgr_frame=cvQueryFrame(capture); //init the video read double fps = cvGetCaptureProperty( capture, CV_CAP_PROP_FPS ); CvSize size = cvSize( (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH), (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT) ); CvVideoWriter *videoWriter = cvCreateVideoWriter("logPolar.avi", -1, fps, size ); IplImage* logpolar_frame = cvCreateImage(size, IPL_DEPTH_8U, 3); while(1) { bgr_frame = cvQueryFrame(capture); cvLogPolar( bgr_frame, logpolar_frame, cvPoint2D32f(bgr_frame->width/2, bgr_frame->height/2), 40, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS ); cvWriteFrame(videoWriter, logpolar_frame); cvShowImage("Convert a video", logpolar_frame); char c = cvWaitKey(100); if(c==27) break; } cvReleaseVideoWriter( &videoWriter ); cvReleaseCapture(&capture); cvReleaseImage(&logpolar_frame); cvDestroyWindow("Convert a video"); }
Function ConvertImage • cvConvertImage() is used to perform common conversions between image formats. • The source image may be one, three, or four channels with either 8-bit or floating-point pixels. The destination must be 8-bit with one or three channels. void cvConvertImage( const CvArr* src, CvArr* dst, int flags = 0 );