Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1609255
  • 博文数量: 245
  • 博客积分: 10378
  • 博客等级: 上将
  • 技术积分: 2571
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-27 08:19
文章分类

全部博文(245)

文章存档

2013年(4)

2012年(8)

2011年(13)

2010年(68)

2009年(152)

分类:

2010-06-22 23:05:27

  最近看美剧 《TELL LIE TO ME》,对里边的一些东西非常感兴趣,具体就是摄像头目录然后会自动截取眼睛的图像到另外一个屏幕,想用OPENCV实现下。
  自己开始使用OPENCV对很多东西都不怎么熟悉,可以使用OPENCV既有的算法检测到眼睛,然后就差截取眼睛部分的图像了,在网络上找了很多,大概只有一种可用的方法,具体如下:
  使用的函数只有两个:
 
 //

CvMat* cvGetSubRect(const CvArr* arr, CvMat* submat, CvRect rect);
/* arr Input array
submat Pointer to the resultant sub-array header
rect Zero-based coordinates of the rectangle of interest
The function returns header, corresponding to a specified rectangle of the input array. In other
words, it allows the user to treat a rectangular part of input array as a stand-alone array. ROI is
taken into account by the function so the sub-array of ROI is actually extracted. */


 从结构arr中获取rect指向的内容,然后将这些内容复制到submat结构中,表达式采用链式表达,把内容复制到submat后,并返回submat的地址,使用过opencv的人都知道, CvArr不是一种具体的结构,可以使图像、矩阵等,具体图像位置有CvRect结构决定。

typedef struct CvRect
{
int x; //矩形的起始点X坐标
int y; //矩形的起始点Y坐标
int width; //矩形的宽
int height; //矩形的高
}
CvRect;


使用完cvGetSubRect()函数后,截取的图像就被复制到submat结构中了,下一步需要做的是从CvMat结构中转换数据到IPlImage类型。使用如下函数:

IplImage* cvGetImage(const CvArr* arr, IplImage* imageHeader);

/*
arr Input array
imageHeader Pointer to IplImage structure used as a temporary buffer
*/


这同样是一个链式表达,arr参数就是使用cvGetSubRect()函数中的submat参数对应的参数,IplImage*参数就对应实际图像结构的指针,同样链式表达也会返回这个结构的指针。

使用如上的函数就可以完成图像的截取。

基于上述的链式表达,可以使用一条语句完成,如:

 cvGetImage(cvGetSubRect(frame_copy,&test,Rect_eys),eye_img);

具体参数不做详细解释了。

这里需要注意一些常犯的错误:

1.CvMat* cvGetSubRect(const CvArr* arr, CvMat* submat, CvRect rect);
这个函数中的 submat,一定要申请相应的空间在传递参数,实际的数据会复制到相应指针指向的空间,这里我犯了错误。

2. CvMat* cvGetSubRect(const CvArr* arr, CvMat* submat, CvRect rect);
函数中的参数rect需要注意,它制定的复制数据的位置的大小,可能会发生数据越界,需要额外注意。比如实际图像是400x300,而你制定的起点是(350,250),而宽是100,高是100,这时候,矩形的另外一个顶点就是(450,350),实际图像数据结构中并没有这些空间,就造成越界,我这样的初学者就犯了这样的错误。

 

阅读(8395) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~