分类: C/C++
2010-02-02 17:50:59
翻译:Mensch
简介
OpenCV概述
什么是OpenCV
开源C/C++计算机视觉库.
面向实时应用进行优化.
跨操作系统/硬件/窗口管理器.
通用图像/视频载入、存储和获取.
由中、高层API构成.
为Intel®公司的 Integrated Performance Primitives (IPP) 提供了透明接口.
特性:
图像数据操作 (分配,释放, 复制, 设定, 转换).
图像与视频 I/O (基于文件/摄像头输入, 图像/视频文件输出).
矩阵与向量操作与线性代数计算(相乘, 求解, 特征值, 奇异值分解SVD).
各种动态数据结构(列表, 队列, 集, 树, 图).
基本图像处理(滤波, 边缘检测, 角点检测, 采样与插值, 色彩转换, 形态操作, 直方图, 图像金字塔).
结构分析(连接成分, 轮廓处理, 距离转换, 模板匹配, Hough转换, 多边形近似, 线性拟合, 椭圆拟合, Delaunay三角化).
摄像头标定 (寻找并跟踪标定模板, 标定, 基础矩阵估计, homography估计, 立体匹配).
动作分析(光流, 动作分割, 跟踪).
对象辨识 (特征方法, 隐马可夫链模型HMM).
基本GUI(显示图像/视频, 键盘鼠标操作, 滚动条).
图像标识 (直线, 圆锥, 多边形, 文本绘图)
OpenCV 模块:
cv - OpenCV 主要函数.
cvaux - 辅助 (实验性) OpenCV 函数.
cxcore - 数据结构与线性代数算法.
highgui - GUI函数.
资料链接
参考手册:
网络资源:
官方网页:
软件下载:
书籍:
Open Source Computer Vision Library by Gary R. Bradski, Vadim Pisarevsky, and Jean-Yves Bouguet, Springer, 1st ed. (June, 2006).
视频处理例程 (位于
色彩跟踪: camshiftdemo
点跟踪: lkdemo
动作分割: motempl
边缘检测: laplace
图像处理例程(位于
边缘检测: edge
分割: pyramid_segmentation
形态: morphology
直方图: demhist
距离转换: distrans
椭圆拟合 fitellipse
OpenCV 命名约定
函数命名:
cvActionTarget[Mod](...)
Action = 核心功能(例如 设定set, 创建create)
Target = 操作目标 (例如 轮廓contour, 多边形polygon)
[Mod] = 可选修饰词 (例如说明参数类型)
矩阵数据类型:
CV_
S = 带符号整数
U = 无符号整数
F = 浮点数
例:CV_8UC1 表示一个8位无符号单通道矩阵,
CV_32FC2 表示一个32位浮点双通道矩阵.
图像数据类型:
IPL_DEPTH_
头文件:
#include
#include
#include
#include
编译命令
Linux系统:
g++ hello-world.cpp -o hello-world \
-I /usr/local/include/opencv -L /usr/local/lib \
-lm -lcv -lhighgui -lcvaux
Windows系统:
//////////////////////////////////////////////////////////////////////////
// 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
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;i
// 显示图像
cvShowImage("mainWin", img );
// wait for a key
cvWaitKey(0);
// release the image
cvReleaseImage(&img );
return 0;
}
GUI命令
窗口管理
创建并放置一个窗口:
cvNamedWindow("win1", CV_WINDOW_AUTOSIZE);
cvMoveWindow("win1", 100, 100); // 以屏幕左上角为起点的偏移量
读入图像:
IplImage* img=0;
img=cvLoadImage(fileName);
if(!img) printf("Could not load image file: %s\n",fileName);
显示图像:
cvShowImage("win1",img);
可显示彩色或灰度的字节/浮点图像。 彩色图像数据认定为BGR顺序.
关闭窗口:
cvDestroyWindow("win1");
改变窗口尺寸:
cvResizeWindow("win1",100,100); // 新的宽/高值(象素点)
输入设备
响应鼠标事件:
定义鼠标handler:
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
注册handler:
mouseParam=5; cvSetMouseCallback("win1",mouseHandler,&mouseParam);
响应键盘事件:
键盘没有事件handler.
直接获取键盘操作:
int key; key=cvWaitKey(10); // 输入等待10ms
等待按键并获取键盘操作:
int key; key=cvWaitKey(0); // 无限等待键盘输入
键盘输入循环:
while(1){
key=cvWaitKey(10);
if(key==27) break;
switch(key){
case 'h':
...
break;
case 'i':
...
break;
}
}
处理滚动条事件:
定义滚动条handler:
void trackbarHandler(int pos) { printf("Trackbar position: %d\n",pos); }
注册handler:
int trackbarVal=25; int maxVal=100; cvCreateTrackbar("bar1", "win1", &trackbarVal ,maxVal , trackbarHandler);
获取滚动条当前位置:
int pos = cvGetTrackbarPos("bar1","win1");
设定滚动条位置:
cvSetTrackbarPos("bar1", "win1", 25);
OpenCV基础数据结构
图像数据结构
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_64F
|-- int width; // 图像宽度(象素点数)
|-- int height; // 图像高度(象素点数)
|-- char* imageData; // 指针指向成一列排列的图像数据
| // 注意色彩顺序为BGR
|-- int dataOrder; // 0 - 彩色通道交叉存取 BGRBGRBGR,
| // 1 - 彩色通道分隔存取 BBBGGGRRR
| // 函数cvCreateImage只能创建交叉存取的图像
|-- int origin; // 0 - 起点为左上角,
| // 1 - 起点为右下角(Windows位图bitmap格式)
|-- int widthStep; // 每行图像数据所占字节大小
|-- int imageSize; // 图像数据所占字节大小 = 高度*每行图像数据字节大小
|-- struct _IplROI *roi;// 图像ROI. 若不为NULL则表示需要处理的图像
| // 区域.
|-- char *imageDataOrigin; // 指针指向图像数据原点
| // (用来校准图像存储单元的重新分配)
|
|-- int align; // 图像行校准: 4或8字节校准
| // OpenCV不采用它而使用widthStep
|-- char colorModel[4]; // 图像色彩模型 - 被OpenCV忽略
矩阵与向量
矩阵:
CvMat // 2维数组
|-- int type;// 元素类型(uchar,short,int,float,double)
|-- int step;// 一行所占字节长度
|-- int rows, cols;// 尺寸大小
|-- int height, width; // 备用尺寸参照
|-- union data;
|-- uchar* ptr; // 针对unsigned char矩阵的数据指针
|-- short* s; // 针对short矩阵的数据指针
|-- int* i; // 针对integer矩阵的数据指针
|-- float* fl; // 针对float矩阵的数据指针
|-- double* db; // 针对double矩阵的数据指针
CvMatND // N-维数组
|-- int type; // 元素类型(uchar,short,int,float,double)
|-- int dims; // 数组维数
|-- union data;
|
|-- uchar* ptr; // 针对unsigned char矩阵的数据指针
|
|-- short* s; // 针对short矩阵的数据指针
|
|-- int* i; // 针对integer矩阵的数据指针
|
|-- float* fl; // 针对float矩阵的数据指针
|
|-- double* db; // 针对double矩阵的数据指针
|
|-- struct dim[]; // 每个维的信息
|-- size; // 该维内元素个数
|-- step; // 该维内元素之间偏移量
CvSparseMat // 稀疏N维数组
通用数组:
CvArr* // 仅作为函数参数,说明函数接受多种类型的数组,例如: //
IplImage*, CvMat* 或者 CvSeq*. // 只需通过分析数组头部的前4字节便可确定数组类型
标量:
CvScalar |-- double val[4]; //4D向量
初始化函数:
CvScalar s = cvScalar(double val0, double val1=0, double val2=0, double val3=0);
举例:
CvScalar s = cvScalar(20.0);s.val[0]=10.0;
注意:初始化函数与数据结构同名,只是首字母小写. 它不是C++的构造函数.
其他数据结构
点:
CvPoint p = cvPoint(int x, int y);
CvPoint2D32f p = cvPoint2D32f(float x, float y);
CvPoint3D32f p = cvPoint3D32f(float x, float y, float z);
例如:p.x=5.0;p.y=5.0;
长方形尺寸:
CvSize r = cvSize(int width, int height);
CvSize2D32f r = cvSize2D32f(float width, float height);
带偏移量的长方形尺寸:
CvRect r = cvRect(int x, int y, int width, int height);