Open Source Computer Vision Library条目讨论编辑history不转换搜索文档 搜索论坛简体繁体导航首页新闻动态最近更改编辑帮助关于本站OpenCV 编程简介(矩阵/图像/视频的基本读写操作)Introduction to programming with OpenCVOpenCV编程简介作者: Gady AgamDepartment of Computer ScienceJanuary 27, 2006Illinois Institute of TechnologyURL: http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv-intro.html#SECTION00040000000000000000翻译: chenyusiyuanPersonal tools用户登录January 26, 2010http://blog.csdn.net/chenyusiyuan/archive/2010/01/26/5259060.aspx摘要: 本文旨在帮助读者快速入门OpenCV,而无需阅读冗长的参考手册。掌握了OpenCV的以下基础知识后,有需要的话再查阅相关的参考手册。目录 [隐藏]1 一、简介1.1 1、OpenCV的特点1.1.1 (1) 总体描述1.1.2 (2) 功能1.1.3 (3) OpenCV模块1.2 2、有用的学习资源1.2.1 (1) 参考手册:1.2.2 (2) 网络资源:1.2.3 (3) 书籍:1.2.4 (4) 视频处理例程(在 OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision 2.2 2、输入处理 2.2.1 (1) 处理鼠标事件:2.2.2 (2) 处理键盘事件:2.2.3 (3) 处理滑动条事件: 3 三、OpenCV的基本数据结构 3.1 1、图像数据结构 3.1.1 (1) IPL 图像:3.2 2、矩阵与向量 3.2.1 (1) 矩阵: 3.2.2 (2) 一般矩阵:3.2.3 (3) 标量:3.3 3、其它结构类型 3.3.1 (1) 点: 3.3.2 (2) 矩形框大小(以像素为精度):3.3.3 (3) 矩形框的偏置和大小: 4 四、图像处理 4.1 1、图像的内存分配与释放 4.1.1 (1) 分配内存给一幅新图像:4.1.2 (2) 释放图像:4.1.3 (3) 复制图像: 4.1.4 (4) 设置/获取感兴趣区域ROI:4.1.5 (5) 设置/获取感兴趣通道COI:4.2 2、图像读写 4.2.1 (1) 从文件中读入图像:4.2.2 (2) 保存图像:4.3 3、访问图像像素 4.3.1 (1) 假设你要访问第k通道、第i行、第j列的像素。 4.3.2 (2) 间接访问: (通用,但效率低,可访问任意格式的图像)4.3.3 (3) 直接访问: (效率高,但容易出错)4.3.4 (4) 基于指针的直接访问: (简单高效) 4.3.5 (5) 基于 c++ wrapper 的直接访问: (更简单高效)4.4 4、图像转换 4.4.1 (1) 字节型图像的灰度-彩色转换:4.4.2 (2) 彩色图像->灰度图像:4.4.3 (3) 不同彩色空间之间的转换:4.5 5、绘图指令 4.5.1 (1) 绘制矩形:4.5.2 (2) 绘制圆形:4.5.3 (3) 绘制线段: 4.5.4 (4) 绘制一组线段: 4.5.5 (5) 绘制一组填充颜色的多边形:4.5.6 (6) 文本标注: 5 五、矩阵处理 5.1 1、矩阵的内存分配与释放 5.1.1 (1) 总体上: 5.1.2 (2) 为新矩阵分配内存:5.1.3 (3) 释放矩阵内存:5.1.4 (4) 复制矩阵:5.1.5 (5) 初始化矩阵: 5.1.6 (6) 初始化矩阵为单位矩阵:5.2 2、访问矩阵元素 5.2.1 (1) 假设需要访问一个2D浮点型矩阵的第(i, j)个单元.5.2.2 (2) 间接访问: 5.2.3 (3) 直接访问(假设矩阵数据按4字节行对齐): 5.2.4 (4) 直接访问(当数据的行对齐可能存在间隙时 possible alignment gaps):5.2.5 (5) 对于初始化后的矩阵进行直接访问:5.3 3、矩阵/向量运算 http://www.opencv.org.cn/index.php/OpenCV_编程简介(矩阵/图像/视频的基本读写操作)#1.E3.80.81OpenCV.E7.9A.84.E7..B9.E7.82.B9[2013/3/12 15:49:47] OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision 5.3.1 (1) 矩阵之间的运算: 5.3.2 (2) 矩阵之间的元素级运算:5.3.3 (3) 向量乘积: 5.3.4 (4) 单一矩阵的运算: 5.3.5 (5) 非齐次线性方程求解: 5.3.6 (6) 特征值与特征向量 (矩阵为方阵): 6 六、视频处理 6.1 1、从视频流中捕捉一帧画面 6.1.1 (1) OpenCV 支持从摄像头或视频文件(AVI格式)中捕捉帧画面.6.1.2 (2) 初始化一个摄像头捕捉器:6.1.3 (3) 初始化一个视频文件捕捉器:6.1.4 (4) 捕捉一帧画面: 6.1.5 (5) 释放视频流捕捉器:6.2 2、获取/设置视频流信息 6.2.1 (1) 获取视频流设备信息:6.2.2 (2) 获取帧图信息: 6.2.3 (3) 设置从视频文件抓取的第一帧画面的位置:6.3 3、保存视频文件 6.3.1 (1) 初始化视频编写器:6.3.2 (2) 保持视频文件:6.3.3 (3) 释放视频编写器: [编辑] 一、简介 [编辑] 1、OpenCV的特点 [编辑] (1) 总体描述 OpenCV是一个基于C/C++语言的开源图像处理函数库其代码都经过优化,可用于实时处理图像具有良好的可移植性 可以进行图像/视频载入、保存和采集的常规操作具有低级和高级的应用程序接口(API) 提供了面向Intel IPP高效多媒体函数库的接口,可针对你使用的Intel CPU优化代码,提高程序性能(译注:OpenCV2.0版的代码已显著优化,无需IPP来提升性能,故2.0版不再提供IPP接口) [编辑] (2) 功能 图像数据操作(内存分配与释放,图像复制、设定和转换) Image data manipulation (allocation, release, copying, setting, conversion).图像/视频的输入输出(支持文件或摄像头的输入,图像/视频文件的输出)Image and video I/O (file and camera based input, image/video file output).矩阵/向量数据操作及线性代数运算(矩阵乘积、矩阵方程求解、特征值、奇异值分解) Matrix and vector manipulation and linear algebra routines (products, solvers, eigenvalues, SVD).支持多种动态数据结构(链表、队列、数据集、树、图) Various dynamic data structures (lists, queues, sets, trees, graphs). 基本图像处理(去噪、边缘检测、角点检测、采样与插值、色彩变换、形态学处理、直方图、图像金字塔结构)Basic image processing (filtering, edge detection, corner detection, sampling and interpolation, color conversion,morphological operations, histograms, image pyramids). 结构分析(连通域/分支、轮廓处理、距离转换、图像矩、模板匹配、霍夫变换、多项式逼近、曲线拟合、椭圆拟 http://www.opencv.org.cn/index.php/OpenCV_编程简介(矩阵/图像/视频的基本读写操作)#1.E3.80.81OpenCV.E7.9A.84.E7..B9.E7.82.B9[2013/3/12 15:49:47] OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision 合、狄劳尼三角化) Structural analysis (connected components, contour processing, distance transform, various moments, templatematching, Hough transform, polygonal approximation, line fitting, ellipse fitting, Delaunay triangulation).摄像头定标(寻找和跟踪定标模式、参数定标、基本矩阵估计、单应矩阵估计、立体视觉匹配) Camera calibration (finding and tracking calibration patterns, calibration, fundamental matrix estimation,homography estimation, stereo correspondence).运动分析(光流、动作分割、目标跟踪) Motion analysis (optical flow, motion segmentation, tracking).目标识别(特征方法、HMM模型) Object recognition (eigen-methods, HMM). 基本的GUI(显示图像/视频、键盘/鼠标操作、滑动条) Basic GUI (display image/video, keyboard and mouse handling, scroll-bars).图像标注(直线、曲线、多边形、文本标注)Image labeling (line, conic, polygon, text drawing) [编辑] (3) OpenCV模块 cv – 核心函数库cvaux – 辅助函数库 cxcore – 数据结构与线性代数库highgui – GUI函数库ml – 机器学习函数库 [编辑] 2、有用的学习资源 [编辑] (1) 参考手册: [编辑] (2) 网络资源: 官方网站: http://www.intel.com/technology/computing/opencv/软件下载: http://sourceforge.net/projects/opencvlibrary/ [编辑] (3) 书籍: Open Source Computer Vision Library by Gary R. Bradski, Vadim Pisarevsky, and Jean-Yves Bouguet, Springer, 1st ed. (June, 2006). chenyusiyuan: 补充以下书籍 Learning OpenCV - Computer Vision with the OpenCV Library by Gary Bradski & Adrian Kaehler, O'Reilly Media, 1 st ed. (September, 2008).OpenCV教程——基础篇 作者:刘瑞祯 于仕琪,北京航空航天大学出版社,出版日期:200706 [编辑] (4) 视频处理例程(在 颜色跟踪: camshiftdemo点跟踪: lkdemo动作分割: motempl http://www.opencv.org.cn/index.php/OpenCV_编程简介(矩阵/图像/视频的基本读写操作)#1.E3.80.81OpenCV.E7.9A.84.E7..B9.E7.82.B9[2013/3/12 15:49:47] OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision 边缘检测: laplace[编辑](5) 图像处理例程 (在 OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision #include 点型图像像素值范围为[0-1]。彩色图像的三色元素按BGR(蓝-绿-红)顺序存储。[编辑](4) 关闭窗口:cvDestroyWindow(\"win1\");[编辑](5) 改变窗口大小:cvResizeWindow(\"win1\",100,100); // new width/heigh in pixels[编辑]2、输入处理[编辑](1) 处理鼠标事件:定义一个鼠标处理程序:void mouseHandler(int event, int x, int y, int flags, void* param) { switch(event){ case CV_EVENT_LBUTTONDOWN: if(flags & CV_EVENT_FLAG_CTRLKEY) printf(\"Left button down with CTRL pressed\\n\"); break; case CV_EVENT_LBUTTONUP: printf(\"Left button up\\n\"); break; } } x,y: 相对于左上角的像素坐标 event: CV_EVENT_LBUTTONDOWN, CV_EVENT_RBUTTONDOWN, CV_EVENT_MBUTTONDOWN, CV_EVENT_LBUTTONUP, CV_EVENT_RBUTTONUP, CV_EVENT_MBUTTONUP, CV_EVENT_LBUTTONDBLCLK, CV_EVENT_RBUTTONDBLCLK, CV_EVENT_MBUTTONDBLCLK, CV_EVENT_MOUSEMOVE: flags: CV_EVENT_FLAG_CTRLKEY, CV_EVENT_FLAG_SHIFTKEY, CV_EVENT_FLAG_ALTKEY, CV_EVENT_FLAG_LBUTTON, CV_EVENT_FLAG_RBUTTON, CV_EVENT_FLAG_MBUTTON注册该事件处理程序:mouseParam=5; cvSetMouseCallback(\"win1\",mouseHandler,&mouseParam); //第三个参数可以设置为NULL[编辑](2) 处理键盘事件:实际上对于键盘输入并没有专门的事件处理程序.按一定间隔检测键盘输入(适用于循环体中):http://www.opencv.org.cn/index.php/OpenCV_编程简介(矩阵/图像/视频的基本读写操作)#1.E3.80.81OpenCV.E7.9A.84.E7..B9.E7.82.B9[2013/3/12 15:49:47] OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision int key; key=cvWaitKey(10); // wait 10ms for input中止程序等待键盘输入:int key; key=cvWaitKey(0); // wait indefinitely for input键盘输入的循环处理程序:while(1){ key=cvWaitKey(10); if(key==27) break; switch(key){ case 'h': ... break; case 'i': ... break; } }[编辑](3) 处理滑动条事件:定义一个滑动条处理程序:void trackbarHandler(int pos) { printf(\"Trackbar position: %d\\n\",pos); }注册该事件处理程序:int trackbarVal=25; int maxVal=100; cvCreateTrackbar(\"bar1\", \"win1\", &trackbarVal ,maxVal , trackbarHandler);获取当前的滑动条位置:int pos = cvGetTrackbarPos(\"bar1\",\"win1\");设置滑动条位置:cvSetTrackbarPos(\"bar1\", \"win1\", 25);[编辑]三、OpenCV的基本数据结构(译注:OpenCV 1.1、1.2或2.0版本中各数据结构的结构体元素有所调整,以下仅作参考)[编辑]1、图像数据结构http://www.opencv.org.cn/index.php/OpenCV_编程简介(矩阵/图像/视频的基本读写操作)#1.E3.80.81OpenCV.E7.9A.84.E7..B9.E7.82.B9[2013/3/12 15:49:47] OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision [编辑](1) IPL 图像:IplImage |-- int nChannels; // 颜色通道数目 (1,2,3,4) |-- int depth; // 像素的位深: | // IPL_DEPTH_8U, IPL_DEPTH_8S, | // IPL_DEPTH_16U,IPL_DEPTH_16S, | // IPL_DEPTH_32S,IPL_DEPTH_32F, | // IPL_DEPTH_F |-- int width; // 图像宽度(像素为单位) |-- int height; // 图像高度 |-- char* imageData; // 图像数据指针 | // 注意彩色图像按BGR顺序存储数据 |-- int dataOrder; // 0 - 将像素点不同通道的值交错排在一起,形成单一像素平面 | // 1 - 把所有像素同通道值排在一起,形成若干个通道平面,再把平面排列起来 | // cvCreateImage 只能创建像素交错排列式的图像 |-- int origin; // 0 – 像素原点为左上角, | // 1 – 像素原点为左下角 (Windows bitmaps style) |-- int widthStep; // 相邻行的同列点之间的字节数 width * nChannels * depth / 8 |-- int imageSize; // 图像的大小(字节为单位) = height*widthStep |-- struct _IplROI *roi;// 图像的感兴趣区域(ROI). ROI非空时对图像的 | // 处理仅限于ROI区域. |-- char *imageDataOrigin; // 图像数据未对齐时的数据原点指针 | // (需要正确地重新分配图像内存 ) | // (needed for correct image deallocation) |-- int align; // 图像数据的行对齐: 4 or 8 byte alignment | // OpenCV 中无此项,采用widthStep代替 |-- char colorModel[4]; // 颜色模型 – OpenCV中忽略此项[编辑]2、矩阵与向量[编辑](1) 矩阵:CvMat // 2D 矩阵 |-- int type; // 元素类型 (uchar,short,int,float,double) 与标志 |-- int step; // 整行长度字节数 |-- int rows, cols; // 行、列数 |-- int height, width; // 矩阵高度、宽度,与rows、cols对应 |-- union data; |-- uchar* ptr; // data pointer for an unsigned char matrix |-- short* s; // data pointer for a short matrix |-- int* i; // data pointer for an integer matrix |-- float* fl; // data pointer for a float matrix |-- double* db; // data pointer for a double matrixCvMatND // N-维矩阵 |-- int type; // 元素类型 (uchar,short,int,float,double) 与标志 |-- int dims; // 矩阵维数 |-- union data; | |-- uchar* ptr; // data pointer for an unsigned char 矩阵 | |-- short* s; // data pointer for a short matrix | |-- int* i; // data pointer for an integer matrix | |-- float* fl; // data pointer for a float matrix | |-- double* db; // data pointer for a double matrix | |-- struct dim[]; // 各维信息 |-- size; // 元素数目 |-- step; // 元素间距(字节为单位)http://www.opencv.org.cn/index.php/OpenCV_编程简介(矩阵/图像/视频的基本读写操作)#1.E3.80.81OpenCV.E7.9A.84.E7..B9.E7.82.B9[2013/3/12 15:49:47] OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision CvSparseMat // N-维稀疏矩阵[编辑](2) 一般矩阵:CvArr* // 仅作为函数定义的参数使用, // 表明函数可以接受不同类型的矩阵作为参数, // 例如:IplImage*, CvMat* 甚至是 CvSeq*. // 矩阵的类型通过矩阵头的前4个字节信息来确定[编辑](3) 标量:CvScalar |-- double val[4]; //4D 向量初始化函数:CvScalar s = cvScalar(double val0, double val1=0, double val2=0, double val3=0);// Example: CvScalar s = cvScalar(20.0);s.val[0]=20.0;注意该初始化函数的函数名与对应的结构体名称几乎同名,差别仅在于函数名第一个字母是小写的,而结构体名第一个字母是大写的。它并不是一个 C++ 构造函数。(译注:类似的还有 cvMat 与 CvMat、cvPoint 与 CvPoint 等等)[编辑]3、其它结构类型[编辑](1) 点:CvPoint p = cvPoint(int x, int y);CvPoint2D32f p = cvPoint2D32f(float x, float y);CvPoint3D32f p = cvPoint3D32f(float x, float y, float z);//E.g.:p.x=5.0;p.y=5.0;[编辑](2) 矩形框大小(以像素为精度):CvSize r = cvSize(int width, int height);CvSize2D32f r = cvSize2D32f(float width, float height);[编辑](3) 矩形框的偏置和大小:CvRect r = cvRect(int x, int y, int width, int height);[编辑]http://www.opencv.org.cn/index.php/OpenCV_编程简介(矩阵/图像/视频的基本读写操作)#1.E3.80.81OpenCV.E7.9A.84.E7..B9.E7.82.B9[2013/3/12 15:49:47] OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision 四、图像处理[编辑]1、图像的内存分配与释放[编辑](1) 分配内存给一幅新图像:IplImage* cvCreateImage(CvSize size, int depth, int channels);size: cvSize(width,height);depth: 像素深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F, IPL_DEPTH_F channels: 像素通道数. Can be 1, 2, 3 or 4.各通道是交错排列的. 一幅彩色图像的数据排列格式如下:b0 g0 r0 b1 g1 r1 ...示例:// Allocate a 1-channel byte imageIplImage* img1=cvCreateImage(cvSize(0,480),IPL_DEPTH_8U,1); // Allocate a 3-channel float imageIplImage* img2=cvCreateImage(cvSize(0,480),IPL_DEPTH_32F,3);[编辑](2) 释放图像:IplImage* img=cvCreateImage(cvSize(0,480),IPL_DEPTH_8U,1); cvReleaseImage(&img);[编辑](3) 复制图像:IplImage* img1=cvCreateImage(cvSize(0,480),IPL_DEPTH_8U,1); IplImage* img2;img2=cvCloneImage(img1); // 注意通过cvCloneImage得到的图像 // 也要用 cvReleaseImage 释放,否则容易产生内存泄漏[编辑](4) 设置/获取感兴趣区域ROI:void cvSetImageROI(IplImage* image, CvRect rect);void cvResetImageROI(IplImage* image);CvRect cvGetImageROI(const IplImage* image);大多数OpenCV函数都支持 ROI, region of interests,设置了ROI之后,函数对图片的处理只会应用到ROI区域上.[编辑](5) 设置/获取感兴趣通道COI:http://www.opencv.org.cn/index.php/OpenCV_编程简介(矩阵/图像/视频的基本读写操作)#1.E3.80.81OpenCV.E7.9A.84.E7..B9.E7.82.B9[2013/3/12 15:49:47] OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision void cvSetImageCOI(IplImage* image, int coi); // 0=allint cvGetImageCOI(const IplImage* image);大多数OpenCV函数不支持 COI.[编辑]2、图像读写[编辑](1) 从文件中读入图像:IplImage* img=0; img=cvLoadImage(fileName); if(!img) printf(\"Could not load image file: %s\\n\",fileName); 支持的图像格式: BMP, DIB, JPEG, JPG, JPE, PNG, PBM, PGM, PPM, SR, RAS, TIFF, TIFOpenCV默认将读入的图像强制转换为一幅三通道彩色图像. 不过可以按以下方法修改读入方式:img=cvLoadImage(fileName,flag); flag: >0 将读入的图像强制转换为一幅三通道彩色图像 =0 将读入的图像强制转换为一幅单通道灰度图像 <0 读入的图像通道数与所读入的文件相同.[编辑](2) 保存图像:if(!cvSaveImage(outFileName,img)) printf(\"Could not save: %s\\n\", outFileName);保存的图像格式由 outFileName 中的扩展名确定.[编辑]3、访问图像像素[编辑](1) 假设你要访问第k通道、第i行、第j列的像素。[编辑](2) 间接访问: (通用,但效率低,可访问任意格式的图像)对于单通道字节型图像:IplImage* img=cvCreateImage(cvSize(0,480),IPL_DEPTH_8U,1);CvScalar s;s=cvGet2D(img,i,j); // get the (j,i) pixel value, 注意cvGet2D与cvSet2D中坐标参数的顺序与其它opencv函数坐标参数顺序恰好相反.本函数中i代表y轴,即height;j代表x轴,即width.printf(\"intensity=%f\\n\",s.val[0]);s.val[0]=111;cvSet2D(img,i,j,s); // set the (j,i) pixel value对于多通道字节型/浮点型图像:http://www.opencv.org.cn/index.php/OpenCV_编程简介(矩阵/图像/视频的基本读写操作)#1.E3.80.81OpenCV.E7.9A.84.E7..B9.E7.82.B9[2013/3/12 15:49:47] OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision IplImage* img=cvCreateImage(cvSize(0,480),IPL_DEPTH_32F,3);CvScalar s;s=cvGet2D(img,i,j); // get the (j,i) pixel valueprintf(\"B=%f, G=%f, R=%f\\n\",s.val[0],s.val[1],s.val[2]);s.val[0]=111;s.val[1]=111;s.val[2]=111;cvSet2D(img,i,j,s); // set the (j,i) pixel value[编辑](3) 直接访问: (效率高,但容易出错)对于单通道字节型图像:IplImage* img=cvCreateImage(cvSize(0,480),IPL_DEPTH_8U,1);((uchar *)(img->imageData + i*img->widthStep))[j]=111;对于多通道字节型图像:IplImage* img=cvCreateImage(cvSize(0,480),IPL_DEPTH_8U,3);((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R对于多通道浮点型图像:IplImage* img=cvCreateImage(cvSize(0,480),IPL_DEPTH_32F,3);((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R[编辑](4) 基于指针的直接访问: (简单高效)对于单通道字节型图像:IplImage* img = cvCreateImage(cvSize(0,480),IPL_DEPTH_8U,1);int height = img->height;int width = img->width;int step = img->widthStep;uchar* data = (uchar *)img->imageData;data[i*step+j] = 111;对于多通道字节型图像:IplImage* img = cvCreateImage(cvSize(0,480),IPL_DEPTH_8U,3);int height = img->height;int width = img->width;int step = img->widthStep;int channels = img->nChannels;uchar* data = (uchar *)img->imageData;data[i*step+j*channels+k] = 111;对于多通道浮点型图像(假设图像数据采用4字节(32位)行对齐方式):IplImage* img = cvCreateImage(cvSize(0,480),IPL_DEPTH_32F,3);int height = img->height;int width = img->width;http://www.opencv.org.cn/index.php/OpenCV_编程简介(矩阵/图像/视频的基本读写操作)#1.E3.80.81OpenCV.E7.9A.84.E7..B9.E7.82.B9[2013/3/12 15:49:47]OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Visionint step = img->widthStep;int channels = img->nChannels;float * data = (float *)img->imageData;data[i*step+j*channels+k] = 111;[编辑](5) 基于 c++ wrapper 的直接访问: (更简单高效)首先定义一个 c++ wrapper ‘Image’,然后基于Image定义不同类型的图像:template OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision cvConvertImage(src, dst, flags=0); src = float/byte grayscale/color image dst = byte grayscale/color image flags = CV_CVTIMG_FLIP (垂直翻转图像) CV_CVTIMG_SWAP_RB (置换 R 和 B 通道)[编辑](2) 彩色图像->灰度图像:// Using the OpenCV conversion: cvCvtColor(cimg,gimg,CV_BGR2GRAY); // cimg -> gimg // Using a direct conversion: for(i=0;i OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision [编辑](4) 绘制一组线段:CvPoint curve1[]={10,10, 10,100, 100,100, 100,10};CvPoint curve2[]={30,30, 30,130, 130,130, 130,30, 150,10};CvPoint* curveArr[2]={curve1, curve2};int nCurvePts[2]={4,5};int nCurves=2;int isCurveClosed=1;int lineWidth=1; cvPolyLine(img,curveArr,nCurvePts,nCurves,isCurveClosed,cvScalar(0,255,255),lineWidth) void cvPolyLine( CvArr* img, CvPoint** pts, int* npts, int contours, int is_closed, CvScalar color, int thickness=1, int line_type=8, int shift=0 );img 图像。 pts 折线的顶点指针数组。 npts 折线的定点个数数组。也可以认为是pts指针数组的大小 contours 折线的线段数量。 is_closed 指出多边形是否封闭。如果封闭,函数将起始点和结束点连线。 color 折线的颜色。 thickness 线条的粗细程度。 line_type 线段的类型。参见cvLine。 shift 顶点的小数点位数[编辑](5) 绘制一组填充颜色的多边形:cvFillPoly(img,curveArr,nCurvePts,nCurves,cvScalar(0,255,255)); cvFillPoly用于一个单独被多边形轮廓所限定的区域内进行填充。函数可以填充复杂的区域,例如,有漏洞的区域和有交叉点的区域等等。void cvFillPoly( CvArr* img, CvPoint** pts, int* npts, int contours,CvScalar color, int line_type=8, int shift=0 );img 图像。 pts 指向多边形的数组指针。 npts 多边形的顶点个数的数组。 contours 组成填充区域的线段的数量。 color 多边形的颜色。 line_type 组成多边形的线条的类型。 shift 顶点坐标的小数点位数。[编辑](6) 文本标注:CvFont font;double hScale=1.0;double vScale=1.0;int lineWidth=1;cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, hScale,vScale,0,lineWidth); cvPutText (img,\"My comment\",cvPoint(200,400), &font, cvScalar(255,255,0));其它可用的字体类型有: CV_FONT_HERSHEY_SIMPLEX, CV_FONT_HERSHEY_PLAIN, CV_FONT_HERSHEY_DUPLEX,CV_FONT_HERSHEY_COMPLEX, CV_FONT_HERSHEY_TRIPLEX, CV_FONT_HERSHEY_COMPLEX_SMALL,CV_FONT_HERSHEY_SCRIPT_SIMPLEX, CV_FONT_HERSHEY_SCRIPT_COMPLEX,[编辑]五、矩阵处理http://www.opencv.org.cn/index.php/OpenCV_编程简介(矩阵/图像/视频的基本读写操作)#1.E3.80.81OpenCV.E7.9A.84.E7..B9.E7.82.B9[2013/3/12 15:49:47] OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision [编辑]1、矩阵的内存分配与释放[编辑](1) 总体上:OpenCV 使用C语言来进行矩阵操作。不过实际上有很多C++语言的替代方案可以更高效地完成。在OpenCV中向量被当做是有一个维数为1的N维矩阵.矩阵按行-行方式存储,每行以4字节(32位)对齐.[编辑](2) 为新矩阵分配内存:CvMat* cvCreateMat(int rows, int cols, int type); type: 矩阵元素类型. 按CV_ OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision[编辑]2、访问矩阵元素[编辑](1) 假设需要访问一个2D浮点型矩阵的第(i, j)个单元.[编辑](2) 间接访问:cvmSet(M,i,j,2.0); // Set M(i,j)t = cvmGet(M,i,j); // Get M(i,j)[编辑](3) 直接访问(假设矩阵数据按4字节行对齐):CvMat* M = cvCreateMat(4,4,CV_32FC1);int n = M->cols;float *data = M->data.fl; data[i*n+j] = 3.0;[编辑](4) 直接访问(当数据的行对齐可能存在间隙时 possible alignment gaps):CvMat* M = cvCreateMat(4,4,CV_32FC1);int step = M->step/sizeof(float);float *data = M->data.fl; (data+i*step)[j] = 3.0;[编辑](5) 对于初始化后的矩阵进行直接访问:double a[16];CvMat Ma = cvMat(3, 4, CV_FC1, a);a[i*4+j] = 2.0; // Ma(i,j)=2.0;[编辑]3、矩阵/向量运算[编辑](1) 矩阵之间的运算:CvMat *Ma, *Mb, *Mc;cvAdd(Ma, Mb, Mc); // Ma+Mb -> MccvSub(Ma, Mb, Mc); // Ma-Mb -> MccvMatMul(Ma, Mb, Mc); // Ma*Mb -> Mc[编辑](2) 矩阵之间的元素级运算:CvMat *Ma, *Mb, *Mc;cvMul(Ma, Mb, Mc); // Ma.*Mb -> Mchttp://www.opencv.org.cn/index.php/OpenCV_编程简介(矩阵/图像/视频的基本读写操作)#1.E3.80.81OpenCV.E7.9A.84.E7..B9.E7.82.B9[2013/3/12 15:49:47]OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer VisioncvDiv(Ma, Mb, Mc); // Ma./Mb -> MccvAddS(Ma, cvScalar(-10.0), Mc); // Ma.-10 -> Mc[编辑](3) 向量乘积:double va[] = {1, 2, 3};double vb[] = {0, 0, 1};double vc[3]; CvMat Va=cvMat(3, 1, CV_FC1, va);CvMat Vb=cvMat(3, 1, CV_FC1, vb);CvMat Vc=cvMat(3, 1, CV_FC1, vc); double res=cvDotProduct(&Va,&Vb); // 向量点乘: Va . Vb -> rescvCrossProduct(&Va, &Vb, &Vc); // 向量叉乘: Va x Vb -> Vc注意在进行叉乘运算时,Va, Vb, Vc 必须是仅有3个元素的向量.[编辑](4) 单一矩阵的运算:CvMat *Ma, *Mb;cvTranspose(Ma, Mb); // 转置:transpose(Ma) -> Mb (注意转置阵不能返回给Ma本身)CvScalar t = cvTrace(Ma); // 迹:trace(Ma) -> t.val[0] double d = cvDet(Ma); // 行列式:det(Ma) -> dcvInvert(Ma, Mb); // 逆矩阵:inv(Ma) -> Mb[编辑](5) 非齐次线性方程求解:CvMat* A = cvCreateMat(3,3,CV_32FC1);CvMat* x = cvCreateMat(3,1,CV_32FC1);CvMat* b = cvCreateMat(3,1,CV_32FC1);cvSolve(&A, &b, &x); // solve (Ax=b) for x[编辑](6) 特征值与特征向量 (矩阵为方阵):CvMat* A = cvCreateMat(3,3,CV_32FC1);CvMat* E = cvCreateMat(3,3,CV_32FC1);CvMat* l = cvCreateMat(3,1,CV_32FC1);cvEigenVV(A, E, l); // l = A 的特征值(递减顺序) // E = 对应的特征向量 (行向量)(7) 奇异值分解(SVD):====CvMat* A = cvCreateMat(3,3,CV_32FC1);CvMat* U = cvCreateMat(3,3,CV_32FC1);CvMat* D = cvCreateMat(3,3,CV_32FC1);CvMat* V = cvCreateMat(3,3,CV_32FC1);cvSVD(A, D, U, V, CV_SVD_U_T|CV_SVD_V_T); // A = U D V^T标志位使矩阵U或V按转置形式返回 (若不转置可能运算出错).[编辑]六、视频处理http://www.opencv.org.cn/index.php/OpenCV_编程简介(矩阵/图像/视频的基本读写操作)#1.E3.80.81OpenCV.E7.9A.84.E7..B9.E7.82.B9[2013/3/12 15:49:47] OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision [编辑]1、从视频流中捕捉一帧画面[编辑](1) OpenCV 支持从摄像头或视频文件(AVI格式)中捕捉帧画面.[编辑](2) 初始化一个摄像头捕捉器:CvCapture* capture = cvCaptureFromCAM(0); // capture from video device #0[编辑](3) 初始化一个视频文件捕捉器:CvCapture* capture = cvCaptureFromAVI(\"infile.avi\");[编辑](4) 捕捉一帧画面:IplImage* img = 0; if(!cvGrabFrame(capture)){ // capture a frame printf(\"Could not grab a frame\\n\\7\"); exit(0);}img=cvRetrieveFrame(capture); // retrieve the captured frame若要从多个摄像头中同步捕捉画面,则须首先从每个摄像头中抓取一帧,紧接着要将被捕捉的帧画面恢复到一个IplImage*型图像中。(译注:这一过程其实可以用 cvQueryFrame() 函数一步完成)[编辑](5) 释放视频流捕捉器:cvReleaseCapture(&capture);注意由视频流捕捉器得到的图像是由捕捉器分配和释放内存的,不需要单独对图像进行释放内存的操作。[编辑]2、获取/设置视频流信息[编辑](1) 获取视频流设备信息:cvQueryFrame(capture); // 在读取视频流信息前,要先执行此操作int frameH = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);int frameW = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);int fps = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);int numFrames = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);统计总帧数仅对视频文件有效,但似乎不太准确(译注:也许OpenCV2.0中此问题已解决)[编辑](2) 获取帧图信息:http://www.opencv.org.cn/index.php/OpenCV_编程简介(矩阵/图像/视频的基本读写操作)#1.E3.80.81OpenCV.E7.9A.84.E7..B9.E7.82.B9[2013/3/12 15:49:47] OpenCV 编程简介(矩阵/图像/视频的基本读写操作) - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision float posMsec = cvGetCaptureProperty(capture, CV_CAP_PROP_POS_MSEC);int posFrames = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES);float posRatio = cvGetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO);所抓取的帧的位置有三种表达方式:距离第一帧画面的时间间隔(毫秒为单位), 或者距离第一帧画面(序列号为0)的序列数. 第三种方式是按相对比率,第一帧的相对比率为0,最后一帧的相对比率为1. 此方式仅对读取视频文件时有效.[编辑](3) 设置从视频文件抓取的第一帧画面的位置:// start capturing from a relative position of 0.9 of a video filecvSetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO, (double)0.9);注意此方法定位并不准确。[编辑]3、保存视频文件[编辑](1) 初始化视频编写器:CvVideoWriter *writer = 0;int isColor = 1;int fps = 25; // or 30int frameW = 0; // 744 for firewire camerasint frameH = 480; // 480 for firewire cameraswriter=cvCreateVideoWriter(\"out.avi\",CV_FOURCC('P','I','M','1'), fps,cvSize(frameW,frameH),isColor);其它的编码器代号包括: CV_FOURCC('P','I','M','1') = MPEG-1 codec CV_FOURCC('M','J','P','G') = motion-jpeg codec(does not work well) CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 codec CV_FOURCC('D', 'I', 'V', '3') = MPEG-4.3 codecCV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec CV_FOURCC('U', '2', '6', '3') = H263 codec CV_FOURCC('I', '2', '6', '3')= H263I codec CV_FOURCC('F', 'L', 'V', '1') = FLV1 codec 若编码器代号为 -1,则运行时会弹出一个编码器选择框.[编辑](2) 保持视频文件:IplImage* img = 0; int nFrames = 50;for(i=0;i
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- huatuo6.cn 版权所有 赣ICP备2024042791号-9
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务