在pcDuino上学习OpenCV系列教程(二)显示图像

雨后的彩虹桥 发布于 2014/03/01 17:13
阅读 741
收藏 0

OpenCV开发包提供了读取各种类型的图像文件、视频内容以及摄像机输入的功能。这些功能是OpenCV开发包中所包含的HighGUI工具集的一部分。我们将使用其中的一些功能编写一段简单的程序,用以读取并在屏幕上显示一张图像。

说明:

硬件平台:pcDuino V2

操作系统:ubuntu 12.07

编译器:gcc 4.6.3

OpenCV版本:2.4.8.2

10134644-c0813b299c634ca195466e5649315924

编辑程序

1,编写主程序

$vim test.c

?
1
2
3
4
5
6
7
8
9
10
11
12
#include"highgui.h"
#include<stdio.h>
intmain(intargc,char* argv[])
{
    IplImage* img = cvLoadImage( argv[1],1); 
    cvNamedWindow("Example1",CV_WINDOW_AUTOSIZE );
    cvShowImage("Example1", img );
    cvWaitKey(0);
    cvReleaseImage( &img );
    cvDestroyWindow("Example1");
    return0;
}

2,编写编译脚本

$vim build.sh

?
1
2
#!/bin/sh
gcc `pkg-config --cflags opencv` -o test test.c `pkg-config --libs opencv
测试

这里是显示图片的例子,需要拷贝一个图片到pcDuino里面。

$./test opencv.png

1

代码分析

当以上程序编译后,我们就可以在命令行模式下通过输入一个参数执行它。执行时,该程序将向内存加载一幅图像,并将该图像显示于屏幕上,直至按下键盘的任意一个键后它才关闭窗口并退出程序。下面我们将对以上代码做逐行分析,并仔细讲解每个函数的用法以帮助读者理解这段程序。

IplImage* img = cvLoadImage( argv[1],1 );

该行程序的功能是将图像文件[1]加载至内存。cvLoadImage()函数是一个高层调用接口,它通过文件名确定被加载文件的格式;并且该函数将自动分配图像数据结构所需的内存。需要指出的是,cvLoadImage()函数可读取绝大多数格式类型的图像文件,这些类型包括BMP, DIB, JPEG, JPE, PNG, PBM, PGM, PPM, SR, RAS和TIFF。该函数执行完后将返回一个指针,此指针指向一块为描述该图像文件的数据结构(IplImage)而分配的内存块。IplImage结构体将是我们在使用OpenCV时会最常用到的数据结构。OpenCV使用IplImage结构体处理诸如单通道(single-channel)、多通道(multichannel)、整型的(integer-valued)、浮点型的(floating-point-valued)等所有类型的图像文件。其中

cvLoadImage( filename, -1 ); 默认读取图像的原通道数

cvLoadImage( filename, 0 ); 强制转化读取图像为灰度图

cvLoadImage( filename, 1 ); 读取彩色图

cvNamedWindow( “Example1″, CV_WINDOW_AUTOSIZE );

cvNamedWindow()函数也是一个高层调用接口,该函数由HighGUI库提供。cvNamedWindow()函数用于在屏幕上创建一个窗口,将被显示的图像包含于该窗口中。函数的第一个参数指定了该窗口的窗口标题(本例中为”Example1″),如果要使用HighGUI库所提供的其他函数与该窗口进行交互时,我们将通过该参数值引用这个窗口。

cvNamedWindow()函数的第二个参数定义了窗口的属性。该参数可被设置为0(默认值)或CV_WINDOW_AUTOSIZE,设置为0时,窗口的大小不会因图像的大小而改变,图像只能在窗口中根据窗口的大小进行拉伸或缩放;而设置为CV_WINDOW_AUTOSIZE时,窗口则会根据图像的实际大小自动进行拉伸或缩放,以容纳图像。

cvShowImage( “Example1″, img );

只要有一个与某个图像文件相对应的IplImage*类型的指针,我们就可以在一个已创建好的窗口(使用cvNamedWindow()函数创建)中使用cvShowImage()函数显示该图像。cvShowImage()函数通过设置其第一个参数确定在哪个已存在的窗口中显示图像。cvShowImage()函数被调用时,该窗口将被重新绘制,并且图像也会显示在窗口中。如果该窗口在创建时被指定CV_WINDOW_AUTOSIZE标志作为cvNamedWindow()函数的第二个参数,该窗口将根据图像的大小自动调整为与图像一致。

cvWaitKey(0);

cvWaitKey()函数的功能是使程序暂停,等待用户触发一个按键操作。但如果将该函数参数设为一个正数,则程序将暂停一段时间,时间长为该整数值个毫秒单位,然后继续执行程序,即使用户没有按下任何键。当设置该函数参数为0或负数时,程序将一直等待用户触发按键操作。

cvReleaseImage( &img );

一旦用完加载到内存的图像文件,我们就可以释放为该图像文件所分配的内存。我们通过为cvReleaseImage()函数传递一个类型为IplImage*的指针参数调用该函数,用以执行内存释放操作。对cvReleaseImage()函数的调用执行完毕后,img指针将被设置为NULL。

cvDestroyWindow( “Example1″ );

最后,可以销毁显示图像文件的窗口。cvDestroyWindow()函数将关闭窗口,并同时释放为该窗口所分配的所有内存(包括窗口内部的图像内存缓冲区,该缓冲区中保存了与img指针相关的图像文件像素信息的一个副本)。因为当应用程序的窗口被关闭时,该应用程序窗口所占用的一切资源都会由操作系统自动释放,所以对一些简单程序,不必调用cvDestroyWindow()或cvReleaseImage()函数显式释放资源。但是,养成习惯每次都调用这些函数显式释放资源总是有好处的。

尽管现在已经有了这个可供我们随意把玩的简单程序,但我们并不能就此停滞不前。我们的下一个任务将要去创建一个几乎与一样非常简单的程序—— 编写程序读取并播放AVI视频文件。完成这个新任务后,需要开始深入思考一些问题了。

linksprite学习中心

加载中
返回顶部
顶部