五、数据的输入和输出 1. 将数据写入YAML(或XML)注意,在OpenCV中,无论读写,文件的格式均由指定的后缀名确定。示例: FileStorage fs("test.yml", FileStorage::WRITE); fs << "i"<< 5 <<"r" << 3.1<< "str"<< "ABCDEFGH"; fs << "mtx"<< Mat::eye(3,3,CV_32F); fs << "mylist"<< "["<< CV_PI<< "1+1"<< "{:"<< "month"<< 12<< "day"<< 31<< "year"<< 1969<< "}"<< "]"; fs << "mystruct"<< "{"<< "x"<< 1 <<"y" << 2<< "width"<< 100<< "height"<< 200<< "lbp"<< "[:"; const uchar arr[] = {0, 1, 1, 0, 1, 1, 0, 1}; fs.writeRaw("u", arr, (int)(sizeof(arr)/sizeof(arr[0]))); fs << "]"<< "}";读写方法基本和C++没什么两样,很简单哈。用记事本或IE就可以打开test.yml文件,可以很清楚的看到文件中的数据结构: %YAML:1.0 i: 5 r: 3.1000000000000001e+000 str: ABCDEFGH mtx: !!opencv-matrix rows: 3 cols: 3 dt: f data: [ 1.,0., 0., 0., 1., 0., 0., 0., 1. ] mylist: -3.1415926535897931e+000 - "1+1" - { month:12,day:31, year:1969 } mystruct: x: 1 y: 2 width:100 height:200 lbp: [ 0, 1,1, 0, 1, 1, 0, 1 ] 2. 将数据读回 FileStorage fs("test.yml", FileStorage::READ); int i1 = (int)fs["i"]; double r1 = (double)fs["r"]; string str1 = (string)fs["str"]; Mat M; fs["mtx"] >> M; FileNode tl = fs["mylist"]; CV_Assert(tl.type() == FileNode::SEQ&& tl.size() == 3); double tl0 = (double)tl[0]; string tl1 = (string)tl[1]; int m = (int)tl[2]["month"], d = (int)tl[2]["day"]; int year = (int)tl[2]["year"]; FileNode tm = fs["mystruct"]; Rect r; r.x = (int)tm["x"], r.y = (int)tm["y"]; r.width = (int)tm["width"], r.height = (int)tm["height"]; int lbp_val = 0; FileNodeIterator it = tm["lbp"].begin(); for(int k = 0; k < 8; k++, ++it) lbp_val |= ((int)*it)<< k;这段代码把上面写入文件的数据再读回来。 3. 读写图像,最常用的操作 imwrite("myimage.jpg", image); Mat imagecolorcopy = imread("myimage.jpg", 1); Mat imagegrayscalecopy = imread("myimage.jpg", 0);和MATLAB中的同名函数用法基本一样,很方便。文件格式由指定的后缀名确定。 imread可以指定读取图像的格式,参数0就是CV_LOAD_IMAGE_GRAYSCALE,即读取为灰度图;参数1就是CV_LOAD_IMAGE_COLOR,即读取为彩色图。可以支持如下文件格式: BMP (.bmp), JPEG (.jpg, .jpeg), TIFF (.tif, .tiff), PNG (.png), PBM/ PGM / PPM (.pbm, .pgm, .ppm), Sun Raster (.sr), JPEG 2000(.jp2).每种格式都支持8比特的单通道或3通道图像,PNG和JPEG2000格式支持16bit。 4. 从文件或相机中读取视频 VideoCapture cap; if(argc>1) cap.open(string(argv[1])); else cap.open(0); Mat frame; namedWindow("video", 1); for(;;) { cap>> frame; if(!frame.data) break; imshow("video", frame); if(waitKey(30)>= 0) break; }如果指定了相机名称则打开对应的相机,否则打开默认相机0。打开一个名叫video的窗口,以30ms为间隔显示视频,也就是约33.33fps。六、GUI(Graphical User Interface)组件 namedWindow(winname,flags)创建一个窗口,用于显示。 destroyWindow(winname)销毁一个窗口。 destroyAllWindows()销毁所有窗口。 imshow(winname, mtx)在指定的窗口中显示图像。 waitKey(delay)等待delay毫秒,如果delay为0则一直等待。返回值是按键值,常用于显示图像的刷新和对按键的处理。 createTrackbar(...)创建一个滑动条。 setMouseCallback(...)设置鼠标事件的回调函数。可以从camshiftdemo.cpp以及其他OpenCV示例工程中学习GUI的详细使用方法。七、相机校准、姿态估计、深度估计相机校准主要用到了张正友的棋盘格校准法,在OpenCV文件夹里可以找到棋盘格图像pattern.png,打印下来贴到一个硬板上就可以用以下函数对相机参数进行校准了。 calibrateCamera()利用对棋盘格的一系列抓拍图像对相机进行校准。 findChessboardCorners()寻找棋盘格的角点。剩下的我都没用过: solvePnP() stereoCalibrate() stereoRectify() initUndistortRectifyMap() StereoBM, StereoSGBM reprojectImageTo3D() findHomography()八、目标识别 matchTemplate CascadeClassifier HOGDescriptor sume 2013/1/5