首页 OpenCV 编程入门

OpenCV 编程入门

举报
开通vip

OpenCV 编程入门 OpenCV 编程入门 美国伊力诺理工学院计算机科学系 Gady Adam 翻译:Mensch 2006年 11月 22日 内容 简介 OpenCV概述 资料链接 OpenCV 命名约定 编译命令 C程序实例 GUI 命令 窗口管理 输入设备 OpenCV 基础数据结构 图像数据结构 矩阵与向量 其他数据结构 图像处理 创建与释放图像结构空间 读入与存储图像 读取图像元素 图像转换 绘图命令 ...

OpenCV 编程入门
OpenCV 编程入门 美国伊力诺理工学院计算机科学系 Gady Adam 翻译:Mensch 2006年 11月 22日 内容 简介 OpenCV概述 资料链接 OpenCV 命名约定 编译命令 C程序实例 GUI 命令 窗口管理 输入设备 OpenCV 基础数据结构 图像数据结构 矩阵与向量 其他数据结构 图像处理 创建与释放图像结构空间 读入与存储图像 读取图像元素 图像转换 绘图命令 矩阵操作 创建与释放矩阵结构空间 读取矩阵元素 矩阵/向量操作 视频序列处理 从视频序列中抓取一帧 获取/设定帧信息 存储视频文件 简介 OpenCV概述 什么是 OpenCV 开源 C/C++计算机视觉库. 面向实时应用进行优化. 跨操作系统/硬件/窗口管理器. 通用图像/视频载入、存储和获取. 由中、高层 API构成. 为 Intel®公司的 Integrated Performance Primitives (IPP) 提供了透明接口. 特性: 图像数据操作 (分配,释放, 复制, 设定, 转换). 图像与视频 I/O (基于文件/摄像头输入, 图像/视频文件输出). 矩阵与向量操作与线性代数计算(相乘, 求解, 特征值, 奇异值分解 SVD). 各种动态数据结构(列 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf , 队列, 集, 树, 图). 基本图像处理(滤波, 边缘检测, 角点检测, 采样与插值, 色彩转换, 形态操作, 直方图, 图 像金字塔). 结构分析(连接成分, 轮廓处理, 距离转换, 模板匹配, Hough 转换, 多边形近似, 线性拟合, 椭圆拟合, Delaunay三角化). 摄像头标定 (寻找并跟踪标定模板, 标定, 基础矩阵估计, homography估计, 立体匹配). 动作分析(光流, 动作分割, 跟踪). 对象辨识 (特征方法, 隐马可夫链模型 HMM). 基本 GUI(显示图像/视频, 键盘鼠标操作, 滚动条). 图 像 标 识 ( 直 线 , 辅 助 opencv-root>/docs/index.htmopencv-root>/samples/c/ 目 录 中):opencv-root>/samples/c/目录中):fitellipse OpenCV 命名约定 函数命名: cvActionTarget[Mod](...) Action = 核心功能(例如 设定 set, 创建 create) Target = 操作目标 (例如 轮廓 contour, 多边形 polygon) [Mod] =bit_depth>(S|U|F)C S = 带符号整数 U = 无符号整数 F =bit_depth>(S|U|F) cv.h> #include #include #include // 不必要 - 该头文件已在 cv.h 文件中包含 编译命令 Linux系统: g++ hello-world.cpp -o hello-world \ -I /usr/local/include/opencv -L /usr/local/lib \ -lm -lcv -lhighgui -lcvaux Windows系统: 注意在项目属性中设好 OpenCV头文件以及库文件的路径. C程序实例 //////////////////////////////////////////////////////////////////////// // // hello-world.cpp // // 一个简单的 OpenCV程序 // 它从一个文件中读取图像,将色彩值颠倒,并显示结果. // //////////////////////////////////////////////////////////////////////// #include #include #include #include #include int main(int argc, char *argv[]) { IplImage* img = 0; int height,width,step,channels; uchar *data; int i,j,k; if(argc<2){ printf("Usage: main \n\7"); exit(0); } // 载入图像 img=cvLoadImage(argv[1]); if(!img){ printf("Could not load image file: %s\n",argv[1]); exit(0); } // 获取图像数据 height = img->height; width = img->width; step = img->widthStep; channels = img->nChannels; data = (uchar *)img->imageData; printf("Processing a %dx%d image with %d channels\n",height,width,channels); // 创建窗口 cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE); cvMoveWindow("mainWin", 100, 100); // 反色图像 for(i=0;iimageData + i*img->widthStep))[j]=111; 对多通道字节图像: IplImage* img=cvCreateImage(cvSize(640,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(640,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 用指针直接存取 : (在某些情况下简单高效) 对单通道字节图像: IplImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); int height = img->height; int width = img->width; int step = img->widthStep/sizeof(uchar); uchar* data = (uchar *)img->imageData; data[i*step+j] = 111; 对多通道字节图像: IplImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3); int height = img->height; int width = img->width; int step = img->widthStep/sizeof(uchar); int channels = img->nChannels; uchar* data = (uchar *)img->imageData; data[i*step+j*channels+k] = 111; 对单通道浮点图像(假设用 4字节调整): IplImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3); int height = img->height; int width = img->width; int step = img->widthStep/sizeof(float); int channels = img->nChannels; float * data = (float *)img->imageData; data[i*step+j*channels+k] = 111; c++class T> public: Image(IplImage* img=0) {imgp=img;} ~Image(){imgp=0;} void operator=(IplImage* img) {imgp=img;} inline T* operator[](const int rowIndx) { return ((T *)(imgp->imageData + rowIndx*imgp->widthStep));} }; typedef struct{ unsigned char b,g,r; } RgbPixel; typedef struct{ float b,g,r; } RgbPixelFloat; typedef Image RgbImage; typedef Image RgbImageFloat; typedef Image BwImage; typedef Image BwImageFloat; 单通道字节图像: IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); BwImage imgA(img); imgA[i][j] = 111; 多通道字节图像: IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3); RgbImage imgA(img); imgA[i][j].b = 111; imgA[i][j].g = 111; imgA[i][j].r = 111; 多通道浮点图像: IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3); RgbImageFloat imgA(img); imgA[i][j].b = 111; imgA[i][j].g = 111; imgA[i][j].r = 111; 图像转换 转为灰度或彩色字节图像: cvConvertImage(src, dst, flags=0); src = float/byte grayscale/color image dst = byte grayscale/color image flags = CV_CVTIMG_FLIP (flip vertically) CV_CVTIMG_SWAP_RB (swap the R and B channels) 转换彩色图像为灰度图像: 使用 OpenCV转换函数: cvCvtColor(cimg,gimg,CV_BGR2GRAY); // cimg -> gimg 直接转换: for(i=0;iheight;i++) for(j=0;jwidth;j++) gimgA[i][j]= (uchar)(cimgA[i][j].b*0.114 + cimgA[i][j].g*0.587 + cimgA[i][j].r*0.299); 颜色空间转换: cvCvtColor(src,dst,code); // src -> dst code = CV_2 / = 画一组线段: 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); 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)); bit_depth>(S|U|F)C. 例如: CV_8UC1 表示 8位无符号单通道矩阵, CV_32SC2表示 32位有符号双通道矩阵. 例程: CvMat* M = cvCreateMat(4,4,CV_32FC1);   释放矩阵空间: CvMat* M = cvCreateMat(4,4,CV_32FC1); cvReleaseMat(&M);   复制矩阵: CvMat* M1 = cvCreateMat(4,4,CV_32FC1); CvMat* M2; M2=cvCloneMat(M1);   初始化矩阵: double a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; CvMat Ma=cvMat(3, 4, CV_64FC1, a); cvInitMatHeader(&Ma, 3, 4, CV_64FC1, a);   初始化矩阵为单位阵: CvMat* M = cvCreateMat(4,4,CV_32FC1); cvSetIdentity(M); // Set M(i,j) t = cvmGet(M,i,j); // Get M(i,j)   直接存取,假设使用 4-字节校正: CvMat* M = cvCreateMat(4,4,CV_32FC1); int n = M->cols; float *data = M->data.fl; data[i*n+j] = 3.0;   直接存取,校正字节任意: CvMat* M = cvCreateMat(4,4,CV_32FC1); int step = M->step/sizeof(float); float *data = M->data.fl; (data+i*step)[j] = 3.0; CvMat Ma = cvMat(3, 4, CV_64FC1, a); a[i*4+j] = 2.0; // Ma(i,j)=2.0; cvAdd(Ma, Mb, Mc); // Ma+Mb -> Mc cvSub(Ma, Mb, Mc); // Ma-Mb -> Mc cvMatMul(Ma, Mb, Mc); // Ma*Mb -> cvMul(Ma, Mb, Mc); // Ma.*Mb -> Mc cvDiv(Ma, Mb, Mc); // Ma./Mb -> Mc cvAddS(Ma, cvScalar(-10.0), Mc); // Ma.-10 -> Mc   向量乘积: double va[] = {1, 2, 3}; double vb[] = {0, 0, 1}; double vc[3]; CvMat Va=cvMat(3, 1, CV_64FC1, va); CvMat Vb=cvMat(3, 1, CV_64FC1, vb); CvMat Vc=cvMat(3, 1, CV_64FC1, vc); double res=cvDotProduct(&Va,&Vb); res cvCrossProduct(&Va, &Vb, &Vc); cvTranspose(Ma, Mb); // transpose(Ma) -> Mb (不能对自身进行转置) CvScalar t = cvTrace(Ma); // trace(Ma) -> t.val[0] double d = cvDet(Ma); // det(Ma) -> d cvInvert(Ma, Mb); // inv(Ma) -> Mb   非齐次线性系统求解: 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   特征值分析(针对对称矩阵): 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 = 对应的特征向量 (每行)   奇异值分解 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 返回时被转置(若没有转置标号,则有问题不成功!!!). 视频序列操作 从视频序列中抓取一帧 OpenCV支持从摄像头或视频文件(AVI)中抓取图像. 从摄像头获取初始化: CvCapture* capture = cvCaptureFromCAM(0); // capture from video device #0 从视频文件获取初始化: CvCapture* capture = cvCaptureFromAVI("infile.avi"); 抓取帧: IplImage* img = 0; if(!cvGrabFrame(capture)){ // 抓取一帧 printf("Could not grab a frame\n\7"); exit(0); } img=cvRetrieveFrame(capture); // 恢复获取的帧图像 要从多个摄像头同时获取图像, 首先从每个摄像头抓取一帧. 在抓取动作都结束后再恢复帧 图像. capture); // this call is necessary to get correct // capture properties 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); 所有帧数似乎只与视频文件有关. 用摄像头时不对,奇怪!!!. 获取帧信息: 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); 只对从视频文件抓取有效. 不过似乎也不成功!!! 存储视频文件 初始化视频存储器: CvVideoWriter *writer = 0; int isColor = 1; int fps = 25; // or 30 int frameW = 640; // 744 for firewire cameras int frameH = 480; // 480 for firewire cameras writer=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 codec CV_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则将打开一个编码选择窗口(windows系统下). 存储视频文件: IplImage* img = 0; int nFrames = 50; for(i=0;i
本文档为【OpenCV 编程入门】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_055286
暂无简介~
格式:pdf
大小:154KB
软件:PDF阅读器
页数:14
分类:互联网
上传时间:2014-01-16
浏览量:100