基于OpenCV库的C语言编程学习方法
2012-06-21汪沛
汪 沛
(北京林业大学电子信息科学与技术系,北京 100083)
0 引言
传统的C语言教学偏重于让学生从熟悉基本概念和规则开始,逐渐过渡到简单算法的编程实现和程序设计开发,最终熟悉和掌握C语言程序设计的技巧。这种教学方法从基础的知识元素开始学习,然后将这些元素组合开发出具有特定功能的程序。其特点是由点及面,但由于最初较长时间的基础规则学习,学生会感觉比较枯燥。
由于图像处理具有直观、形象和生动的特点,因此笔者提出在“高级语言程序设计”的授课中基于OpenCV库开发程序,先让学生感受C语言编程的强大功能,以提高学生的兴趣,然后再剖析程序,向学生解释讲授各个知识点。OpenCV是Intel公司开发的开源计算机视觉库,包含了大量的图像处理、结构分析、运动分析和目标跟踪等相关函数[1]。学生能够基于OpenCV库中的函数,较快进行相关领域的二次开发。
1 教学方案设计
为增强教学过程中学生的兴趣,笔者选取一张功夫熊猫的图片作为实验中所用的处理图像。为了方便后续处理,利用OpenCV库中的cvCvtColor函数将彩色图像转换为灰度图像。
在本次教学中,拟基于OpenCV库中的函数实现两类图像处理操作:图像翻转操作和图像边缘检测操作。通过向学生展示两类操作所得到的处理结果,进一步提高学习兴趣,同时向学生强调C语言中如下一些关键概念并深化理解:①数组的操作;②函数的操作;③指针作为函数参量的应用;④结构体变量的使用及成员访问。
在C语言中,图像大多用数组来表示,灰度图像是用二维数组表示,彩色图像是用三维数组来表示。图像的翻转则可以看成是数组元素的位置调换;而图像边缘检测则是依照一定的规律寻找数组元素中的特定信息。
由于采用了OpenCV库,因此图像处理的整个过程中更是贯穿函数的概念。彩色图像至灰度图像的转换、图像垂直或者水平翻转、以及图像边缘检测都是用函数来完成。函数的调用使主函数的结构清晰,各个部分一目了然。
在C语言中,有多种方法可以在主函数和图像操作函数之间传递数组元素信息,OpenCV库函数中采用的是指针的方式。指针的访问方式具有形式灵活和效率高的特点。
在OpenCV中最重要的结构体是IplImage结构,主要用于图像处理方面。IplImage结构来自于Intel Image Processing Library,OpenCV只支持其中的一个子集[2]。IplImage结构中包含了图像大小、宽度、高度和像素位深度等信息,这些成员信息都可以在程序中进行访问和输出。
由上述分析不难发现,这些C语言中的关键概念在本次教学方案中都有所涉及。通过上述形象生动的图像变换操作,学生会对这些概念有非常深的印象,这时辅以说明和引导可以使学生加深理解。
2 教学实践
利用OpenCV库中的cvFlip函数,图像可以非常容易实现垂直翻转、水平翻转和垂直又水平翻转。cvFlip函数的具体说明如下:
其中,src代表原数组;dst是目标数组,如果dst=NULL表示翻转是在内部替换;flip_mode是指定如何翻转数组,flip_mode=0表示沿X轴翻转,flip_mode>0表示沿Y轴翻转,flip_mode<0表示沿X轴后沿Y轴翻转。
利用cvFlip函数实现图像垂直翻转结果见图1,其中(a)为原始图像,(b)为垂直翻转后的图像。
图1 原始图像和翻转图像
同样,我们利用OpenCV库中的cvSobel函数、cvCanny函数和cvLaplace函数,可以在图像中分别实现Sobel、Canny和Laplacian三种算子的边缘检测,三个函数说明如下:
图2是三种不同算子的边缘检测结果。由结果可以很容易知道,当采用不同的边缘检测方法时,所得到的结果是迥然不同的。而OpenCV的辅助文档中有对这三个函数的具体使用说明和三种算子的具体描述。三种边缘检测方法都不复杂,因此可以引导学生自己查询文档和研究算法,并尝试让学生自己编写三种边缘检测方法的函数。
图2 边缘检测结果
通过对指向原始图像和各处理结果的IplImage结构体指针变量中的各成员变量进行访问,可以在程序中实时获取各个图像的相关信息[3]。如通过下述语句输出原图像的几个重要信息:
在上述这段程序中,首先通过cvLoadImage函数打开名为gongfupanda的jpg格式彩色图片。随后通过IplImage结构体中的成员变量输出相关信息。在程序中,对成员变量的访问采用了两种形式,需要让学生注意两种形式的差异和特点。
除了前文中所谈及的函数,程序中还使用cvCreateImage函数创建头并分配数据;使用cvN-amedWindow函数创建显示窗口;使用cvShowImage函数在指定窗口中显示图像;使用cvReleaseImage函数释放头和图像数据。此处,举例显示原始图像的相关代码如下:
其中,CV_WINDOW_AUTOSIZE表示用户不能手动改变窗口大小,窗口大小会自动调整以适合要显示的图像。显然,基于OpenCV库函数的程序结构非常简洁。针对程序特点可以推荐学生采用函数完成特定功能,实现模块化设计的编程思维。
由于OpenCV的开源特性,学生可以查询到其中很多库函数的实现算法甚至源码,比较适合学生在课程结束之后进一步自学。OpenCV的开源特性也使得其在工业界得到了广泛的青睐,因此学生对OpenCV的学习也可以直接提高实战能力、缩短与企业用人需求的对接时间。
3 结语
本文通过采用开源的OpenCV库函数来实现对图像的翻转以及边缘检测操作,能够增加学生对学习C语言的兴趣,同时又将C语言的多种关键知识点融入其中,从而达到寓教于乐的目的。此外,OpenCV具有非常强的实用性,能够提升学生解决实际问题的能力,有效增强编程实力,为以后的继续学习深造和就业夯实C语言编程基础。
[1]Gary Bradski,Adrian Kaebler.Learning OpenCV[M].南京:东南大学出版社,2009年
[2]刘瑞祯,于仕琪.OpenCV教程[M].北京:北京航空航天大学出版社,2007年
[3]陈胜勇,刘盛.基于OpenCV的计算机视觉技术实现[M].北京:科学出版社,2008年.