OpenCV
学习笔记
March 12, 2010
1.
关于数据基本类型的学习
参见代码:
//2010
年
3
月
12
日,
Demo 1 OpenCV
的第一个例子
//author
:
liuchang
#include <cv.h>
#include <iostream>
using namespace std;
int main()
{
CvPoint p = cvPoint(1,3);//
针对整型的类型
CvPoint
,对应有构造函数
cvPoint
,注意大小写
cout << p.x << " " << p.y << endl;
CvPoint2D32f p2 = cvPoint2D32f(12.34,43.45);
cout << p2.x << " " << p2.y <<endl;
CvPoint3D32f p3 = cvPoint3D32f(12.34,23.45,56.43);
cout << p3.x << " " << p3.y << " " << p3.z << endl;
//=============================================================================
CvSize r = cvSize(3,4); //
长方形维数类型
cout << r.width << " " <<r.height << endl;
CvSize2D32f r2 = cvSize2D32f(23.45,34.56);
cout << r2.width << " " << r2.height << endl;
//=============================================================================
CvRect x = cvRect(3,4,12.34,45.56);
cout << x.x << " " << x.y << " " << x.width << " " << x.height << endl;
return 0;
}
|
总结:学习到集中基本的数据类型
1.
点的类型。包括二维和三维,而每一个坐标又可以分为整型和浮点型。其中对于二维,用
2D
来表示,对于三维,用
3D
来表示。具体的见代码上,默认的
CvPoint
类型是一个二维的,整型参数的点。其他的见上。
2.
长方形维数类型。长方形已经固定时二维的类型,于是,形参就只用两个,但是类型可以是整型和浮点型,于是又多了
CvSize2D32f
这种类型了。
3.
有偏移量的长方形维数类型。此时前面两个形参就是偏移量的坐标,分别为
x
和
y
。后面的就是宽和高了。注意,形参的类型都是整型,所以,如果像上面的代码那样,就会发生截断处理,取整数部分,于是输出结果就会有所不同。
4.
注意类型和构造函数的区别。看看,定义一个变量的时候,用的是类型,即:
CvPoint,CvSize,CvRect
等等,而对这个类型的变量初始化的时候用的是对应的构造函数,于是是
cvPoint,cvSize,cvRect,
看到规律了吗?类型的第一个首字母大写,而构造函数则是对应的类型名的第一个字母小写就可以了。因此,
OpneCV
的这种命名方法还是很科学易记的。
附注:
OpenCV
的安装过程以及
Visual C++
的配置方法:
1.
下载
OpenCV
并安装。由于之前已经下载了
1.0
的版本,所以这里安装的是
1.0
,默认路径安装,并选择注册环境变量。
2.
检查系统变量是否更改,尽管上面的选项可能会起作用,不过在我的系统中(
Windows 7
),环境变量还是没有更改,于是,选择高级系统设置
---
环境变量
—
系统变量
—path—
编辑,就是在最后添加路径
”; C:\Program Files\OpenCV\bin”,
然后点击确定退出。
3.
安装完成后,并不意味着工作就结束了,还需要设定我们的编程环境。具体来说就是
Visual C++ 6.0
的设置。
Visual C++ 6.0
中设置
OpenCV
的步骤:
1.
选择
tools---option,
在弹出的对话框中点击
Directories
标签,在
Show directories for
下拉选择
Include files
,在
Directories
中添加路径:
C:\Program Files\OpenCV\cxcore\include
C:\Program Files\OpenCV\cv\include
C:\Program Files\OpnCV\cvaux\include
C:\Program Files\OpenCV\otherlibs\highgui
C:\Program Files\OpenCV\otherlibs\cvcam\include
2.
在
Show directories for
下拉列表框中选择
Libarary files
,在
Directories
中添加路径:
C:\Program Files\OpenCV\lib
3.
在
Show directories for
下拉列表框中选择
Executable files
,在
Directories
中添加路径:
C:\Program Files\OpenCV\bin
4.
配置完毕,退出。
配置完毕之后的测试程序(
Demo1
),就是前面的测试程序,编译,运行,
OK
,完全没有问题,证明配置完毕!
GUI
命令
1.
使用到图片处理,显示,创建窗口等命令的时候,必须要在
Project—Setting
选项中设定相应的参数,否则可能会发生连接错误!这个不同于上面的
Demo1
,因为
1
中仅仅是用到了一个数据类型,而没有使用
CV
库函数的功能,比如显示,打开一个图片,运用到第三方库的话,肯定要调用
API
来实现功能,所以,链接库的话,必须要加入,为此,可根据提示信息设置,一般的,进行图像处理,都需要使用到这个。
2.
路径的问题。先看看
Demo2
程序
:
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
int main()
{
IplImage* image = cvLoadImage("C:\\Users\\liuchang\\test1.bmp");
if(!image){ //
如果加载失败
printf("error:
导入图片出错,很可能是路径出错
!\n");
return 0;
}
cvNamedWindow("win1",CV_WINDOW_AUTOSIZE); //
创建一个窗口
cvMoveWindow("win1",100,100); //
定位一个窗口
cvShowImage("win1",image); //
在创建的窗口中显示一个图片
// cvWaitKey(0); //
等待用户输入,否则一闪而过
,
看不到图片
cvReleaseImage(&image); //
注意使用完后一定要释放
return 0;
}
|
此段程序中,功能很简单,就是帮助用户显示一副图片,运行程序,可以显示出来一幅已经存在的图片,而不需要任何的其他
API
来实现。在
OpenCV
中,处理图像的函数很多,此处只是简单的图像显示命令!
另外,上面的注释很清楚的显示了程序的各段代码的功能,这里不再说明。对于具体的说明,后面还会继续!需要注意的一点就是,路径,需要两个斜线,此处很重要,因为对于一个字符串,在作为路径打开的时候,需要
”\\”
才能够被解释为一个斜线,所以如果像上面直接给出路径的话,需要指定是两个斜线,否则会出错!
OK
,下面试试从客户端来输入数据,即利用
main
函数可以从用户输入数据来编写:
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char num[20];
char getup[20];
int i ;
itoa(argc,num,10);
puts(num);
puts(argv[0]);
puts(argv[1]);
strcpy(getup,argv[1]);
for(i = 0; i < strlen(getup); i++)
putchar(getup[i]);
putchar('\\'); //
输出时一个斜线,而如果仅仅一个斜线的话,会报错!
IplImage* image = cvLoadImage(argv[1]);
if(!image){ //
如果加载失败
printf("error:
导入图片出错,很可能是路径出错
!\n");
return 0;
}
cvNamedWindow("win1",CV_WINDOW_AUTOSIZE); //
创建一个窗口
cvMoveWindow("win1",100,100); //
定位一个窗口
cvShowImage("win1",image); //
在创建的窗口中显示一个图片
cvWaitKey(0); //
等待用户输入,否则一闪而过
,
看不到图片
cvReleaseImage(&image); //
注意使用完后一定要释放
return 0;
}
|
关于
main
函数参数的问题,在前面的说明中很清楚,不过这里需要再次说明:
首先,
argc
读入的是输入参数的个数,比如这里输入:
test2 H:\ray.jpg
,那么读取的
argc
的个数就是
2
,而
argv
是一个数组,用来存放你输入的参数,既然参数为
2
,那么该数组就有两个参数,一个
argv[0]
,即前面的那个程序名
test2
,而后面的那个参数就是你读入的那个路径。注意的一点是:读取后存放的路径和你输入的数据可能不同,具体来说就是,你输入的是
:H:\ray.jpg
,而在机内存储的这个字符串的内容是:
H:\\ray.jpg
,也就是说,这个字符串是按照能够正常显示那个斜线符来设计的,也就是转义字符设计的,读入的数据将被转换成正确的能够表示的数据。从上面的验证代码中可以看到。
同时,计算
strlen(argv[1])
也会发现,两个斜线
’\\’
被解释成一个字符!
对于,
putchar(‘\\’)
,如果仅仅是一个斜线的话,会报错误,但是两个的话就正常显示一个
’\’
了。注意是表示的字符,用的单引号,所以,两个斜线被解释为一个字符。
Tips
:如果输入参数是:
test2 H:\\ray.jpg
,还是可以正常运行的。
注记:和
C
库函数不同,例如
open
函数,路径是
open(“C:\test.c”,O_RDONLY);
这样的话,里面就是一个斜线哦。所以
OpenCV
是不同的路径写法,一定要注意,还有上面解释的那个输入参数的问题,就
OK
了。
如果路径不对,则会有下面提示信息:
H:\OPENCV\test4\test4.cpp(15) : warning C4129: 'O' : unrecognized character escape sequence
H:\OPENCV\test4\test4.cpp(15) : warning C4129: 'l' : unrecognized character escape sequence
所以,一定要加双下划线!
3.
输入处理:
OpenCV
中如何响应鼠标事件呢?比如,如何响应点击鼠标,如何响应鼠标被按下呢?
其实,只需要你实现下面
mouseHandler
这个方法就可以了:
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;
}
}
|
那么,如何注册鼠标监听呢?看下面这段代码:
int mouserParam = 5;
cvSetMouseCallback("win1",mouseHandler,&mouserParam);
也就是说,具体的实现监听函数由
mouseHandler
来完成,而要注册,也就是让它何时监听,监听哪一个窗口,则需要用
cvSetMouseCallback
函数来实现,具体的参数,可查阅
API
文档,当然,也可以由上面应用猜测出来。
上面的代码很容易就实现了鼠标被点击并且同时按下
CTRL
键的监听动作和鼠标释放的动作,当然,你还可以实现更多的功能,具体的就是使用
event
的判断,以及和
flags
联合实现的复合键判断!
4.
前面讲到了如何实现监听鼠标事件,那么这里讲下如何监听键盘事件:
看看下面的代码:
int key ;
key = cvWaitKey(0);
if(key == 'q'){
printf("quit\n");
return 0;
}
上面这段代码的意思就是不断的等待输入,如果输入时
q
的话就退出程序,实验之,发现有用。从这里引申下几点:
(1)
对于
cvWaitKey
函数的参数,就是等待的毫秒数,如果是
0
,则表示不断的等待输入,进入一个循环。而它的返回值,就是你按下的按钮的键值。当然,如果要等待一定的时间,如果没有输入还是退出的话,可以采用
cvWaitKey(1000)
这样的具体参数,这样在等待的过程没有输入的话,还是可以正常退出,而不是想前面的循环在那里。
(2)
如果要实现不断循环的话,可以采用下面的这个形式:
while(1){
key = cvWaitKey(10);
if(key == 27)
break;
switch(key){
case 'h':
break;
case 'i':
break;
}
}
这种方式也很好的实现了循环等待多重输入的形式。
5.
如何处理拖动条事件:
上图即拖动条,如何创建并响应该事件呢?
1.
创建:
int trackbarVal = 25;
int maxVal = 100;
cvCreateTrackbar("bar1","win1",&trackbarVal,maxVal,trackbarHandler);
这样就设置了一个名称为
bar1
的拖动条。
2.
响应事件:利用函数
trackbarHandler
来实现
void trackbarHandler(int pos)
{
printf("Trackbar position: %d\n",pos);
}
注意这个监听是自动的。也就是说不需要自己进行任何的注册,只要创建了,并且写了这个函数,就可以实现自动的监听,因为,在创建的函数中,最后的一个参数就是一个监听的函数。
附记:完整的代码如下:
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <string.h>
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;
}
}
void trackbarHandler(int pos)
{
printf("Trackbar position: %d\n",pos);
}
int main(int argc, char **argv)
{
// char num[20];
// char getup[20];
// int i ;
// itoa(argc,num,10);
// puts(num);
// puts(argv[0]);
// puts(argv[1]);
// strcpy(getup,argv[1]);
// for(i = 0; i < strlen(getup); i++)
// putchar(getup[i]);
// putchar('\\');
IplImage* image = cvLoadImage(argv[1]);
if(!image){ //
如果加载失败
printf("error:
导入图片出错,很可能是路径出错
!\n");
return 0;
}
cvNamedWindow("win1",CV_WINDOW_AUTOSIZE); //
创建一个窗口
cvMoveWindow("win1",100,100); //
定位一个窗口
cvShowImage("win1",image); //
在创建的窗口中显示一个图片
// int mouserParam = 5;
// cvSetMouseCallback("win1",mouseHandler,&mouserParam);
// int key ;
// key = cvWaitKey(0); //
等待输入,等待时间为
1000ms
// if(key == 'q'){
// printf("quit\n");
// return 0;
// }
int trackbarVal = 25;
int maxVal = 100;
cvCreateTrackbar("bar1","win1",&trackbarVal,maxVal,trackbarHandler);
// int pos = cvGetTrackbarPos("bar1","win1");
// int pos = cvGetTrackbarPos("bar1","win1");
// cvSetTrackbarPos("bar1","win1",25);
cvWaitKey(0); //
等待用户输入,否则一闪而过
,
看不到图片
cvReleaseImage(&image); //
注意使用完后一定要释放
return 0;
}
|
posted on 2010-03-16 13:21
deercoder 阅读(10793)
评论(7) 编辑 收藏 引用 所属分类:
OpenCV