学习OPENCV笔记1

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/

posted @ 2010-09-29 15:13  筱夏  阅读(5343)  评论(0编辑  收藏  举报