您的位置:首页 > 运维架构

学习OPENCV笔记1

2010-09-29 15:13 513 查看
OpenCV开发包分五个模块,其中,HighGUI包含图像和视频的输入输出函数。接下来主要讲这部分内容。

首先,图像和视频的现实需要创建一个窗口

cvNamedWindow(“Window Title”, WINDOW_SIZE);

第一个参数是窗口的标题,第二个参数是窗口的属性,可以被设置为0或者CV_WINDOW_AUTOSIZE,前者是说窗口固定大小,而后者窗口会根据图像的实际大小自动拉伸和缩放。

当然,既然有创建,就要有销毁

cvDestroyWindow(“Window Title”);

关闭窗口并释放所有的相关内存。

OpenCV中有一个结构体IplImage,用于存储图片的相关信息。通过IplImage* img = cvLoadImage(“File Name”),将图片的信息读取到IplImage中,然后调用cvShowImage(“Window Title”, img),显示图像。

最后当然也需要释放图像信息:

cvReleaseImage(&img);

源程序的代码如下:

#include "highgui.h"

int main()
{
IplImage* img = cvLoadImage("test.jpg");
cvNamedWindow("TestImage",CV_WINDOW_AUTOSIZE);
cvShowImage("TestImage", img);
cvWaitKey(0);
cvReleaseImage(&img);
cvDestroyWindow("TestImage");
return 0;
}




cvWaitKey(time)是暂停程序,等待用户触发一个按键操作。time是整数值,以毫秒为单位。

与图片类似,OpenCV将视频读取到CvCapture结构体中。

CvCaptuer* capture = cvCreateFileCapture(“File Name”);

值得注意的是,该函数只能读取固定格式的AVI文件,起初我选择的一些AVI格式并不能被OpenCV解码,于是返回的指针都是NULL。网上说下载VitualDub,我下载后发现我的AVI格式不对无法转换。

在电脑里翻翻找找半天,总算找到一个能转换的AVI文件,不过转换成未压缩的AVI文件是非常占空间的,我转了一会儿就提示空间不足了。现在重新转了个3分半的,3G多。

然后需要从capture中读取每一帧的图像信息,分别显示出来。使用这个函数img = cvQueryFrame(capture),然后用上面的显示图像的方法。

源代码如下:

#include "highgui.h"

int main()
{
cvNamedWindow("Test Vedio",CV_WINDOW_AUTOSIZE);
CvCapture* capture = cvCreateFileCapture("test.avi");
IplImage* frame;
while(1)
{
frame = cvQueryFrame(capture);
if(!frame)
break;
cvShowImage("Test Vedio", frame);
char c = cvWaitKey(33);
if(c == 27)
break;
}
cvReleaseCapture(&capture);
cvDestroyWindow("Test Vedio");
}

这里并不需要释放图像信息,因为会在视频信息释放的时候自动进行。这里固定了帧率是33,实际上,更好的方法是从CvCapture中读取。

接下来加入OPENCV的滚动条,使之能够通过拖动来控制视频播放。原本书上的代码并没有加入播放时自动调整滚动条的功能,并且使用的是硬编码的帧率,我在这里做了点修改。

#include "highgui.h"

int g_slider_position = 0;
CvCapture* g_capture = NULL;

void onTrackbarSlide(int pos)
{
cvSetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES,pos);
}

int main()
{
cvNamedWindow("Test Vedio Slide",CV_WINDOW_AUTOSIZE);
g_capture = cvCreateFileCapture("test.avi");
int frames = (int)cvGetCaptureProperty(g_capture,CV_CAP_PROP_FRAME_COUNT);
int frameRate = (int)cvGetCaptureProperty(g_capture,CV_CAP_PROP_FPS);

if(frames!=0)
{
cvCreateTrackbar("position","Test Vedio Slide", &g_slider_position, frames, onTrackbarSlide);
}
IplImage* frame;
for(g_slider_position = 0;g_slider_position<frames;g_slider_position++)
{
frame = cvQueryFrame(g_capture);
if(!frame)
break;
cvShowImage("Test Vedio Slide", frame);
char c = cvWaitKey(frameRate);
cvSetTrackbarPos("position","Test Vedio Slide", g_slider_position);
onTrackbarSlide(g_slider_position);
if(c == 27)
break;
}
cvReleaseCapture(&g_capture);
cvDestroyWindow("Test Vedio Slide");
}




首先注册一个回调函数,表示当拖动滚动条时会发生什么行为,在void onTrackbarSlide(int pos)中可以看到,是设置视频当前播放帧为pos。

然后通过读取视频属性,获取帧数量和FPS,创建一个滚动条cvCreateTrackbar("position","Test Vedio Slide", &g_slider_position, frames, onTrackbarSlide);其中position是滚动条的名字,这个函数顺便捆绑了回调函数onTrackbarSlide与函数参数g_slider_position。

在循环里,我添加了一句cvSetTrackbarPos("position","Test Vedio Slide", g_slider_position); 就可以自动设置滚动条的位置了。

但感觉还是不好用,毕竟OPENCV的重点不是图形控件。。。

接下来是平滑图像,其实只有一句话的内容,那就是cvSmooth(in,out,CV_GAUSSIAN,3,3);基本相当于PS里面的高斯模糊吧,技术点说,就是用一个3*3大小的区域对图像像素进行卷积操作。。。。

int main()
{

IplImage* img = cvLoadImage("test.jpg");
cvNamedWindow("TestImage-in",CV_WINDOW_AUTOSIZE);
cvNamedWindow("TestImage-out",CV_WINDOW_AUTOSIZE);
cvShowImage("TestImage-in", img);
IplImage* out = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3);
cvSmooth(img, out, CV_GAUSSIAN,3,3);
cvShowImage("TestImage-out",out);
cvWaitKey(0);
cvReleaseImage(&img);
cvReleaseImage(&out);
cvDestroyWindow("TestImage-in");
cvDestroyWindow("TestImage-out");
return 0;
}

基本到这里吧,复杂点的变换下次再看。。。

本文原创,转载请注明出处

http://www.cnblogs.com/luluathena/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: