Cinder创意编程指南(txt+pdf+epub+mobi电子书下载)


发布时间:2020-06-11 08:36:36

点击下载

作者:(波兰)高尔尼(Gorny,D.),(葡)马德拉(Madeira,R.)

出版社:电子工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Cinder创意编程指南

Cinder创意编程指南试读:

前言

对于创意编程来说,Cinder是最令人兴奋的框架之一。它是由C++开发而成,性能倍增,可用来快速创建具有复杂交互性的可视化应用程序。Cinder最大优势是它能以完全相同的代码在Mac、Windows和iOS等平台上得以呈现。《Cinder创意编程指南》将教会你如何使用简单的步骤开发具有动态视觉的交互式应用程序。

你将学习如何使用多媒体内容,在2D和3D场景中绘制生成图形,并让它们变成引人入胜的动画。

你将从使用Cinder创建简单的项目开始,然后学习使用多媒体,创建动画,并让它们和用户进行互动。

从带有粒子的动画,到使用视频、音频和图像,读者将会学到使用Cinder创建创意性应用的大部分知识。

本书的章节包含3D绘图、图形处理、实时探测和追踪摄像头输入等内容,将教会你如何开发可同时运行于台式机和移动设备的交互式应用程序,或使其成为交互式设备的一部分。

本书还将叙述如何使用Cinder创建动画和高级视觉项目。本书内容概要

第1章入门,使用Cinder创建应用程序的基础知识。

第2章为开发做准备,开发过程中简单而实用的几个知识点。

第3章使用图像处理技术,Cinder图像处理技术与第三方库的使用示例。

第4章使用多媒体内容,如何加载、操作、显示、保存和分享视频、图像和网格数据。

第5章创建粒子系统,如何使用流行的优秀物理算法创建粒子,并生成动画。

第6章粒子系统渲染和贴图,如何渲染粒子,应用材质贴图,以使其更加吸引人。

第7章使用2D图形,如何将OpenGL和内建Cinder工具运用于2D绘图中。

第8章使用3D图形,使用OpenGL创建3D图像和使用一些封装在Cinder中的高级OpenGL特性。

第9章添加动画,展示2D动画和3D对象技术。还将介绍与之相关的Cinder特性,例如时间线和数学函数。

第10章同用户交互,使用鼠标和触屏交互来创建能向用户作出反应的图形化对象,以及如何创建具有自身事件且更加灵活简单的图形界面,并同流行的物理库Bullet Physics相整合。

第11章检测与跟踪摄像头,如何接收和处理来自摄像头或微软Kinect传感器等输入设备的数据。

第12章使用音频输入输出,举例说明如何制作音频,声音通过物体的物理模拟碰撞而产生。本章将展示对声音做出反应的可视化示例。你需要哪些东西

你需要Mac OS X或Windows操作系统。Mac用户如需学习iOS章节,则需要具备XCode,它可以从Apple和iOS SDK免费获取。Windows用户则需要Visual C++2010,其精简版可以免费使用。Windows用户还需安装Windows Platform SDK。在本书写作过程中,Cinder最新版本0.8.4刚刚发布。协议

在本书中,不同类型的信息会以不同的字体呈现。以下列举一些字体,并对其含义做出解释。

代码语言将这样展示:“我们将通过include指令来包含其他上下文。”

代码块显示如下:

命令行输入或输出显示如下:

新术语和重要词语将加粗显示。在屏幕、菜单或对话框中看到的语句将在段落中这样显示:“点击下一步按钮,以查看下一屏。”本书适合谁

本书的目标读者是打算或已经开始使用Cinder开发创意型应用程序的C++开发者。对于使用过其他创意型编程框架并想要尝试Cinder的开发者来说,本书很容易学习。

本书读者应具备C++编程语言的基础知识。第1章 入门

本章学习目标:

►创建一般应用程序项目;

►创建屏保应用程序项目;

►创建iOS触屏应用程序;

►理解应用程序的基本结构;

►响应鼠标输入;

►响应键盘输入;

►响应触屏输入;

►访问被拖放到应用程序窗口的文件;

►改变窗口大小后调整场景;

►在Windows中使用资源;

►在iOS和OS X上使用资源;

►使用资源集(asset)。引言

本章我们学习使用Cinder开发应用程序的基础知识。

一开始我们将学习如何在Cinder所支持的不同平台中开发不同类型的应用,我们将使用一个强大的工具——TinderBox。

我们将阐述一个应用程序的基本结构,以及如何对用户输入事件作出响应。

最后,我们将学习如何使用Windows和Mac上的资源。1.1 创建一般应用程序项目

在本节中,我们将学习如何为Windows和Mac OSX创建一个桌面应用程序项目。做好准备

我们可以使用TinderBox这个强大的工具来创建项目。TinderBox捆绑在Cinder下载包中,并包含有模板,这些模板在Microsoft Visual C++2010和OSX XCode中用于创建不同应用。

打开Cinder文件夹,可以找到一个名为tools的文件夹,Tinderbox就在这个文件夹里,如图1-1所示。图1-1 打开TinderBox

第一次打开TinderBox,要求指定Cinder的安装目录。以后再打开TinderBox就不再要求了。如果需要重新设定Cinder的安装位置,在Windows系统下单击“文件”菜单并选择“系统预置”;在OS X系统下,则点击TinderBox菜单,并选择“系统设置”。如何操作

我们所要使用的实用工具TinderBox捆绑在了Cinder中,它将帮助我们便捷地创建项目。进行以下步骤,就可以创建一个基础应用程序项目。

1.打开TinderBox,选择项目所在位置。在TinderBox主菜单中选择BasicApp作为目标,选择OpenGL作为模板,如图1-2所示。图1-2 设置项目

2.选择项目位置。命名前缀和项目名称区域将默认为项目的名称,如图1-3所示。图1-3 选择项目位置

3.选择项目的编译器,Microsoft Visual C++2010或者OS X XCode,如图1-4所示。图1-4 选择项目编辑器

4.单击创建按钮,TinderBox将显示新项目所在的文件夹。TinderBox将保持开启;

现在可以将其关闭。如何工作

TinderBox将在所选平台(Visual C++2010和OS X XCode)创建所选项目,并创建对编译过的Cinder库的引用。被创建的应用程序的类为ci::app::AppBasic的子类,并提供一些示例代码作为基本样例,帮助你起步。还有更多

项目名称和命名前缀将被默认为项目所在文件夹的名称。如有需要,可以更改,但始终确保不要在项目名称和命名前缀区域产生空格,否则将可能导致错误。

命名前缀用来为应用程序的类命名,其后还需加上App作为后缀。例如,如果将命名前缀设置为MyCinderTest,那么应用类别将为MyCinderTestApp。1.2 创建屏保应用程序项目

在本节中,我们将学习创建Windows和Mac OS X桌面屏保应用项目。做好准备

请参照创建一般应用程序项目小节中的做好准备部分,准备好TinderBox。如何操作

我们所要使用的实用工具TinderBox捆绑在了Cinder中,它将帮助我们便捷地创建项目。进行以下步骤,就可以创建一个屏保应用程序项目:

1.打开TinderBox,选择项目所在位置。在TinderBox主菜单中选择Screensaver作为目标,选择OpenGL作为模板,如图1-5所示。图1-5 设置项目

2.选择项目所用的编译器,Microsoft Visual C++2010或者OS X XCode。

3.单击创建按钮,TinderBox将显示新项目所在的文件夹。如何工作

TinderBox将为你创建一个项目,并将其链接到编译好的Cinder库。此外,它还创建应用程序的类,并将其作为ci::app::AppScreenSaver的子类,该类别具备一个屏保应用的所有功能。TinderBox还提供一些示例代码作为基本样例,帮助你起步。1.3 创建iOS触屏应用程序

本节我们将学习如何为iPhone和iPad这样的iOS设备的创建应用程序项目。做好准备

请参照创建一般应用程序项目小节中的做好准备部分,以准备好TinderBox。

请注意,iOS触屏应用将只能在iPhone和iPad等iOS设备上运行,使用TinderBox创建的项目将只能用于OS X XCode。如何操作

我们所要使用的实用工具TinderBox捆绑在了Cinder中,它将帮助我们便捷地创建项目。进行以下步骤,就可以创建一个iOS触屏应用程序项目:

1.打开TinderBox,选择项目所在位置。在TinderBox主菜单中选择Cocoa Touch作为目标,选择Simple作为模板,如图1-6所示。图1-6 设置项目

2.选择项目所用的编译器,Microsoft Visual C++2010和(或者)OS X XCode。

3.单击创建按钮,TinderBox将显示新项目所在的文件夹。如何工作

TinderBox将创建一个OS X XCode项目,并创建一个引用链接到编译好的Cinder库。它还创建应用程序类,作为ci::app::AppCocoaTouch的一个子类,该类别具备触屏应用程序所需的所有基本功能。它还将提供一些示例代码作为基本样例,帮助你起步。

该应用将搭建在苹果Cocoa Touch框架之上,以创建iOS应用。1.4 理解应用程序的基本结构

应用程序的类中有几个方法在程序执行的不同时间点被调用,详见表1-1。表1-1 应用程序类中调用方式

为执行我们的代码,我们必须在自己的代码中重写这些方法。做好准备

并不一定要重写以上所有方法,你可以只重写需要的方法。例如,如果你不想进行绘图,就可以忽略draw方法。

为便于学习,本节我们将实现所有方法。

在类中声明以下方法。如何操作

我们将实现这几种方法,组成一个应用程序的基本结构。步骤如下:

1.执行prepareSettings方法。这里我们可以定义窗口大小、标题和帧率等。

2.执行setup方法。在这里,我们应该将应用程序类的所有成员进行初始化。例如,要将网络摄像头的截图功能初始化,我们需要声明以下成员。

在setup方法中初始化它们

3.实现update方法。例如,我们要把当前的帧数打印到控制台。

4.实现draw方法以及所有绘图指令。这里,我们用黑色清除背景,并绘制一个红色圆圈。

5.实现shutdown方法。此方法用于执行清理工作,例如,关闭线程或者保存应用程序的状态。

6.这里提供一个样例代码,该代码用于保存XML格式中的一些参数。如何工作

应用程序的超类会将以上方法当作空的虚方法来实现。

当应用程序运行时,这些方法被调用,调用我们自己的代码实现,如果我们没有这样做,则调用父类的空方法。

在步骤1中,我们在prepareSettings中定义了几个参数。不建议使用方法setup来初始化这些参数,因为那样就意味着渲染器将被以默认值初始化,然后在setup方法中被重新调整。导致产生额外的初始化时间。还有更多

响应用户输入的还有其他回调方法,如鼠标和键盘事件、窗口尺寸的改变、文件被拖入应用程序窗口。其细节将分别在以下章节中描述:响应鼠标输入、响应键盘输入、响应触屏输入、访问被拖放到应用程序窗口的文件,以及改变窗口大小后调整场景。参考其他内容

想要学习如何用TinderBox创建一个一般应用程序,请阅读章节创建一般应用程序项目。1.5 响应鼠标输入

应用程序通过调用几种事件处理程序对鼠标动作作出交互响应。已有的能对鼠标交互作出响应的处理程序见表1-2。表1-2 响应鼠标交互的处理程序

并不一定要实现以上所有方法,可以只实现所需要的方法。做好准备

根据需要响应的鼠标事件,实现必要的事件处理程序。例如,创建一个对所有鼠标事件作出响应的应用程序,必须在主类声明中实现以下代码:

MouseEvent对象作为参数被传递进来,其中包含了鼠标事件的相关信息。如何操作

我们将学习如何使用ci::app::MouseEvent类,以响应鼠标事件。需进行以下步骤。

1.为获得事件发生的位置,如屏幕坐标,可以输入以下代码。

或者通过调用方法getX和getY,可以单独获得X和Y的坐标。

2.通过调用方法isLeft, isMiddle或isRight,MouseEvent对象可以知道是哪个鼠标键触发了事件。它们会返回一个bool值,表明是左键、中键还是右键。

3.要想知道是否由一个鼠标按键触发了事件,可以调用方法isLeftDown, isRightDown和isMiddleDown,它们可以返回true,取决于鼠标的左键、右键还是中键被按下。

4.方法getWheelIncrement返回一个float值表示鼠标滚轮的移动增量。

5.还有可能知道,在事件过程中是否按过某个特别键。如果按下了Shift键,方法isShiftDown就会返回true;如果按下了Alt键,方法isAltDown就会返回true;如果按下了control键,isControlDown就会返回true;如果是在Windows系统下按下了Windows键,或是在OS X系统下按下了option键,isMetaDown就会返回true;如果是在Windows系统下按下了Ctrl键,或是在OS X系统下按下了command键, isAccelDown就会返回true。如何工作

Cinder应用会在内部响应系统的本地鼠标事件。接着它会使用本地信息创建一个ci::app::MouseEvent对象,并调用对应的鼠标事件处理程序。还有更多

通过调用方法getNativeModifiers,能访问本地的组合键掩码。Cinder在内部使用这些平台特定的值,用于可能的高级用途。1.6 响应键盘输入

Cinder应用通过几种回调函数对键盘事件作出响应。表1-3中列举了键盘交互可用的回调函数。表1-3 键盘交互可用的回调函数

这两种方法都会接收一个ci::app::KeyEvent对象,作为一个带有有关事件信息的参数,比如被按下的键的键码或被按下的任何特殊键(例如Shift或control)。

并不一定要实现以上所有键盘事件处理程序,可以只实现应用程序需要的方法。做好准备

根据需要作出响应的键盘事件,实现必要的事件处理程序。例如,为创建一个既能响应keyDown事件又能响应keyUp事件的应用,你必须声明以下方法:

ci::app::KeyEvent类型的参数包含有关键盘事件的信息。如何操作

我们将学习如何使用ci::app::KeyEvent类,学习如何理解键盘事件。步骤如下。

1.为获得触发键盘事件字符的ASCII代码,可以输入以下代码:

2.为响应那些不能映射到ASCII字符表的特殊键,必须调用方法getCode,提取一个int值,其能够映射到ci::app::KeyEvent类中的一个字符表。作为测试,如果是Esc键触发了键盘事件,可以输入以下代码:

如果是退出键触发了事件,escPressed将为true,否则将为false。

3.对于事件中被按下的组合键,参数ci::app::KeyEvent也有相关信息。如果按下了Shift键,方法isShiftDown会返回true;如果按下了Alt键,isAltDown会返回true;如果按下了control键,isControlDown会返回true;如果按下了Windows系统的Windows键,或OS X系统的command键,isMetaDown则会返回true;如果按下了Windows系统的Ctrl键,或OS X系统的command键,isAccelDown则会返回true。如何工作

Cinder应用会在内部响应系统的本地键盘事件。当接收到一个本地键盘事件,它会基于本地信息创建一个ci::app::KeyEvent对象,并调用应用程序类中相应的回调函数。还有更多

通过调用方法getNativeKeyCode,也可以访问本地键盘代码。该方法返回一个int值,以及键盘的本地平台特定码。这对高级用法很重要。1.7 响应触屏输入

Cinder应用可以接收几种触屏事件。表1-4中列举可用的触屏交互事件处理程序。表1-4 触屏交互事件处理程序

以上所有方法都接收一个ci::app::TouchEvent对象作为参数,以及存放ci::app::TouchEvent::Touch对象的std::vector,其中包含检测到的每个触屏的信息。由于很多设备能够同时检测和响应几个触屏动作,所以一个触屏事件包含几个触屏信息是可能并且常见的。

并不一定要实现以上所有事件处理程序,只需实现需要的方法。

Cinder应用可以在任何运行Windows7、OS X或iOS的触屏设备上响应触屏事件。做好准备

针对你所想要对其作出响应的触屏事件,实现必要的触屏事件处理程序。例如,为了响应所有可能的触屏事件(开始触摸、移动触点、释放触点),将需要声明和实现以下方法:如何操作

我们将学习如何使用ci::app::TouchEvent类,来理解触屏事件。步骤如下。

1.为访问触屏列表,你可以输入以下代码:

遍历容器访问每个独立元素。

2.调用getPos方法,它会返回一个Vec2f值,其中包含了触点的位置,或者使用方法getX和getY分别接收x和y的坐标,这样就可以得到触点的位置,代码如下:

3.getId方法会返回一个uint32_t值,其中包含touch对象的唯一ID。这个ID贯穿于触屏的整个生命周期,这意味着,通过在不同触屏事件中访问它,就可以用它来追踪某个特定的触屏。例如,制作一个用手指画线的应用程序,我们可以创建std::map,它可以使各个线条发生关联,其值是一个ci::PolyLine<Vec2f>对象,其键是表示触点唯一ID的uint32_t型。

通过把以下代码段添加到源文件的开头,我们就可以把带有std::map和PolyLine的文件放到项目中去:

4.现在我们声明以下容器对象:

5.在touchesBegan方法中,我们为每次被检测到的触屏创建一个新的线条,并将其映射到每个触点的唯一的ID上:

6.在touchesMoved方法中,我们将每次触屏的位置添加到其对应的线条中:

7.在touchesEnded方法中,我们将被移除的触点所对应的线条也删除:

8.最后,可以绘制这些线条。这里我们用黑色将背景清除,并用白色绘制线条。以下是draw方法的实现代码:

绘制结果如图1-7所示。图1-7 触屏绘制结果如何工作

Cinder应用程序会在内部响应任何触屏事件的系统调用。接着创建一个ci::app::TouchEvent对象,其中包含有关事件的信息,并调用应用类中相应的事件处理程序。Windows和Mac平台上使用统一的触屏事件响应方式。

ci::app::TouchEvent类只包含一种访问器方法,返回一个指向std::vector<TouchEvent::Touch>容器的const引用。该容器的ci::app::TouchEvent::Touch对象包含每个被检测到的触点的相关信息。

ci::app::TouchEvent::Touch对象含有的触屏信息包含位置、前一个位置、唯一的ID、时间戳以及指向本地事件对象的指针等,该指针映射到Cocoa Touch上的UITouch和Windows 7上的TOUCHPOINT。还有更多

任何时候,通过调用getActiveTouches方法,都可获得一个包含所有活跃触点的容器。它会返回一个const引用,指向std::vector<TouchEvent::Touch>容器。因为它可以在触屏应用的触屏事件方法之外被访问,所以提供了足够的灵活性。

例如,如果你想在每个活跃触点周围绘制一个实心的红色圆圈,你可以在draw方法中添加以下代码段:1.8 访问被拖放到应用程序窗口的文件

通过回调函数fileDrop,Cinder应用程序可以对被拖放到应用程序窗口的文件作出响应。此方法将一个ci::app::FileDropEvent对象作为参数,参数中包含有关事件的信息。做好准备

你的应用必须实现一个fileDrop方法,该方法将一个ci::app::FileDropEvent对象作为参数。在应用的类声明中添加以下代码:如何操作

我们将学习如何使用ci::app::FileDropEvent对象处理拖放事件。步骤如下:

1.在实现方法时,使用ci::app::FileDropEvent参数,通过调用getFiles方法,访问被拖放到应用中的文件列表。此方法会返回一个包含多个fs::path对象的conststd::vector容器:

2.通过以下回调函数,可访问被拖放文件在窗口中的位置。输入以下代码,获取含有被拖放文件位置的ci::Vec2i对象:

可以使用方法getX和getY,分别获得X和Y的坐标:

3.使用方法getNumFiles找到被拖放文件的数量:

4.如果你已经知道某个特定文件的索引值,可以使用方法getFile,将索引作为一个参数,来访问该文件。例如,可以使用以下代码,访问索引值为2的文件:如何工作

Cinder应用对系统本地拖放事件作出响应。它会创建一个ci::app::FileDropEvent对象,其中包含有关该事件的信息,并在应用中调用fileDrop回调函数。Cinder在Windows和Mac平台上使用统一的拖放事件响应方式。还有更多

Cinder使用ci::fs::path对象来定义路径。这里有boost::filesystem::path对象的typedef实例,其在使用路径时带来更大的灵活性。如需学习更多有关fs::path对象的知识,请参考http://www.boost.org/doc/libs/1_50-0/libs/filesystem/doc/index.htm中的boost::filesystem库引用。1.9 改变窗口大小后调整场景

通过resize函数实现尺寸调整事件,Cinder应用可以对改变窗口大小作出响应。使用一个ci::app::ResizeEvent对象作为参数,其中包含相关事件信息。做好准备

如果你的应用不具备resize方法,可在应用的类声明中,添加以下代码行来实现它。

在实现该方法时,你可以使用ResizeEvent参数,查找窗口的新尺寸和格式。如何操作

我们将学习如何使用ci::app::ResizeEvent参数响应窗口大小调整事件。步骤如下。

1.查询窗口的新尺寸使用getSize方法,返回一个ci::Vec2iwith对象,窗口宽度为x部分,高度为y部分。

getWidth和getHeight方法都返回int值,分别包含窗口的宽度和高度。例如:

2.方法getAspectRatio返回一个float值,包含窗口的纵横比,即宽度和高度之间的比例:

3.屏幕中任何元素都必须按照新窗口的大小作出调整,重新计算其属性。例如,有一个矩形位于窗口中心,四周留有20像素的空白,首先必须在类声明中声明一个ci::Rectf对象:

在setup方法中,设置其属性,在其四周保留20像素的空白:

4.在draw方法中添加以下代码段,即可绘制一个红色的矩形:

5.在resize方法中,必须重新计算矩形的属性,这样它就能重新调整自己的大小,在四周保留20像素的空白:

6.运行应用程序,并调整窗口的尺寸。如图1-8所示,该矩形将根据窗口大小调整它的相对大小和位置。图1-8 调整窗口的尺寸如何工作

Cinder应用会在内部对系统的窗口尺寸调整事件作出响应。接着它会创建ci::app::ResizeEvent对象,并在应用类中调用resize方法。Cinder在Windows和Mac平台上使用统一的窗口尺寸调整事件响应方式。1.10 在Windows中使用资源

Windows应用经常使用外部文件来加载图片、播放音频或视频、用XML文件加载或保存设置。外部文件作为资源被嵌入在应用程序中。资源文件对用户隐藏,以免遭到更改。做好准备

资源应存放在项目文件夹中名为resources的文件夹里。如果没有这个文件夹,需要创建它。

Windows中的资源必须在一个名为Resources.rc的文件中被引用。该文件应存放于vc10文件夹中Visual C++方案旁。如果这个文件不存在,必须新创建一个空文件。如果resources.rs文件还没有包含在项目方案中,必须添加这个文件,右键单击Resources过滤器,选择Add,再选择ExistingItem,即可添加。导航至该文件,并将其选取。依照惯例,该文件应被存放在项目方案所在的文件夹内。如何操作

我们使用Visual C++2010将资源添加到Windows中的应用程序里。步骤如下:

1.打开Visual C++方案,再打开Header Files过滤器中的resources.h文件。

2.将#pragma once宏添加至项目文件,以避免该文件被不止一次地包含到项目中,将CinderResources.h文件包含进来。

3.在Windows中,每个资源都必须拥有一个唯一的ID号。依照惯例,ID号是从128开始的序列号码,但如果有更加合适的号码,也可以使用其他ID。确保不要将同样的ID使用两次。必须定义一个类型字符串,类型字符串用于识别同类型的资源,例如,字符串IMAGE可能被用于声明图像资源,而VIDEO被用于声明视频资源等。

4.为简化多平台代码的编写,Cinder用来声明资源的宏在Windows和Mac中都可以使用。例如,为声明一个名为image.png的图像文件的资源,应该输入以下代码行:

CINDER_RESOURCE宏的第一个参数就是指向资源文件所在文件夹的相对路径,在本例中,该文件夹默认为resources文件夹。第二个参数是文件名称,接着是该资源的唯一的ID,最后是其类型字符串。

5.现在需要向resources.rs文件添加resources宏,应输入以下代码:

6.现在该资源已经做好准备,可以用于项目。为将该图像加载到ci::gl::Texture中,只需在应用的源代码中包含Texture.h文件:

7.现在可以对贴图进行声明:

8.在setup中,通过加载资源来创建贴图:

9.该贴图已做好准备,可以绘制在屏幕上。为将图像绘制在(20, 20)这个位置上,在方法draw中输入以下代码:如何工作

资源编译器利用文件resources.rc将资源嵌入到可执行文件中,作为二进制数据。还有更多

有了Cinder,就可以在所有被支持的平台上使用统一资源模式来编写代码,但Windows和OS X/iOS中资源的处理方式略有不同。如需学习如何在Mac上使用资源,请阅读在iOS和OS X上使用资源章节。1.11 在iOS和OS X上使用资源

Windows应用经常使用外部文件来加载图像、播放音频或视频、使用XML文件加载或保存设置。外部文件作为资源被打包存放在应用程序束(bundle)中。资源文件对用户隐藏,以免遭到更改。

有了Cinder,允许使用同样的资源访问方式为Windows和Mac应用编写代码,但资源的处理方式略有不同。如需学习如何在Windows上使用资源,请阅读在Windows上使用资源章节。做好准备

资源应存放在项目文件夹中名为resources的文件夹里。如果没有这个文件夹,需要创建它。如何操作

我们将使用XCode把资源添加到iOS和OS X的应用中。步骤如下:

1.将需要使用的任何资源文件放在resources文件夹中。

2.右键单击XCode项目中的Resources过滤器,选择Add,再选择ExistingFiles,导航至资源文件夹,并选择需要添加的资源文件,即可将这些文件添加至项目中。

3.使用loadResource方法,通过资源文件的名称在代码中加载一个资源。例如,想要加载一个名为image.png的图片,应该首先在类声明中创建gl::Texture成员:

4.在setup方法中,使用以下代码将贴图初始化:

5.现在贴图已经准备好被绘制到窗口中。在draw方法中输入以下代码,在位置(20, 20)绘制它:如何工作

在iOS和OS X上,应用程序实际上是包含了所有程序运行所需文件的文件夹。例如,Unix可执行文件、所用的框架以及资源。单击任何Mac应用,并选择Show Package Contents,就可以访问这些文件夹的内容。

当需要向XCode项目中的resources文件夹添加资源时,这些文件在构建阶段被复制到应用包的resources文件夹中。还有更多

还可以使用方法loadResource加载资源,同样的方法也适用于Windows应用。这在编写跨平台应用时十分有用,无须在代码中进行更改。

应该在Resources.h文件中创建resource宏,并添加唯一资源ID及其类型字符串。例如,加载图片image.png,可以输入以下代码段:

以下是Resources.rc文件应有的样子:

使用上述例子来加载一张图片,唯一的区别是将使用以下代码加载贴图:

在Mac应用中,资源的唯一ID和类型字符串将被忽略,但是添加它们能创建跨平台的代码。1.12 使用资源集(assets)

本节我们将学习如何加载和使用资源集。做好准备

作为示例,我们将加载和显示一张资源集图片。

在你的项目根目录的assets文件夹中放置一个图片文件,将其命名为image.png。在源代码顶端加入以下代码:

再添加以下有用的using声明:如何操作

作为示例,我们将学习如何加载和显示一个图片资源集。步骤如下:

1.声明一个ci::gl::Texture贴图:

2.在setup方法中,加载图片资源集。如果无法加载该资源集,我们将使用一个try/catch语句块。

3.在draw方法中,我们将绘制贴图。我们将使用一个if声明,检查贴图是否已经被成功初始化:如何工作

首先,应用程序使用一个Cinder资源集,它试图找到其默认的assets文件夹。它从可执行文件或应用程序束(bundle)文件夹开始搜索,具体搜索哪一种取决于不同平台,然后继续搜索其上一级文件夹,最多可搜索五级文件夹。这样做是为了适应不同的项目结构。还有更多

可以使用addAssetDirectory方法,添加一个附加的assets文件夹,该方法将ci::fs::path对象作为一个参数。每次当Cinder搜索一个资源集,它都将首先查看其默认的asset文件夹,然后查看用户可能添加的文件夹。

还可以在assets文件夹中创建子文件夹,例如,如果我们的图片位于一个名为My Images的子文件夹中,我们将在setup方法中输入以下代码段:

还可以获知某个特定文件夹的路径。要做到这一点,需要使用getAssetPath方法,它将一个ci::fs::path对象作为参数,其中包含文件的名称。第2章 为开发做准备

本章学习目标:

►用于调整参数设置的图形用户界面;

►保存和加载配置文件;

►为当前的参数状态制作快照;

►使用MayaCamUI;

►使用3D空间指南;

►同其他软件进行通信;

►准备iOS应用程序。引言

本章我们将介绍几个简单的小节,它们在开发过程中会很有用。2.1 用于调整参数设置的图形用户界面

图形用户界面(GUI)经常用来管理和调整Cinder应用程序。在很多示例中,需要不断调整应用参数,使其满足所要求的结果,花费的时间比编写代码还要长。特别是当处理一些生成式图形时。

Cinder提供InterfaceGl类,一种便捷而易用的GUI操作,如图2-1所示。图2-1 CUI操作做好准备

为使类InterfaceGl适用于Cinder应用,需要包括一个头文件。如何操作

将一个GUI添加到Cinder应用中,步骤如下。

1.首先,在我们的主类中声明几种不同类型的变量,我们将使用GUI来控制它们。

2.接着,声明InterfaceGl类成员,如下所示:

3.现在来到setup方法,初始化我们的GUI窗口,将窗口标题“Parameters”和尺寸传递至InterfaceGl构造函数:

4.现在可以为我们的变量添加并配置控件:

查看addParam方法及其参数。第一个参数是字段标题。第二个参数是指向存储值的变量指针。支持多种变量数据类型,例如bool, float, double, int, Vec3f, Quatf, Color, ColorA,和std::string。表2-1汇总了可能的变量类型及其界面图示。

表2-1变量类型及其界面图示。第三个参数定义了控制选项。表2-2中列出了一些常用的选项及其简短解释。表2-1 变量类型及其界面图示表2-2 常用控制选项及其解释在以下网址的AntTweakBar页面中,可以找到可用选项的完整文件资料:http://anttweakbar.sourceforge.net/doc/tools:anttweakbar:varparamsyntax

5.最后一步调用InterfaceGl::draw()方法。通过输入以下代码行,我们将在主类draw方法的末尾进行这一步骤:如何工作

在setup方法中,我们将设置GUI窗口,并添加控件,同时在addParam方法的第一个参数中设置名称。在第二个参数中,将指向一个变量,该变量是我们想要链接到GUI元素的变量。不论什么时候,当通过GUI更改数值,被链接的变量都将被更新。还有更多

对于InterfaceGl来说,还有更多选项,如果需要了解更多内置于GUI原理的控件,请参考AntTweakBar文档,该文档位于本节另请参阅部分中提到的项目页面。

按钮

可以向InterfaceGl (CIT)面板添加带某些回调函数的按钮。例如:

单击GUI中的开始按钮,启动MainApp类中的start方法。

面板位置

使用AntTweekBar工具,能够方便地控制GUI面板的位置。需要包含一个附加的头文件:

现在可以使用以下代码,改变GUI面板的位置:

在本例中,Parameters表示GUI面板的名称,而position选项包含x和y值。另请参阅

可以使用一些很美观的GUI库,例如CinderBlocks。Cinder有一个名为“blocks(方块)”的扩展系统。CinderBlocks的用意是将很多第三方库进行整合,使其易于使用。在同其他软件进行通信一节中,可以学习到如何向项目添加CinderBlocks的例子。

SimpleGUI

由Marcin Ignac开发的一种可供选择的GUI,作为一个CinderBlock项目,可以在这里找到它:https://github.com/vorg/MowaLibs/tree/master/SimpleGUI。

ciUI

由Reza Ali开发的一种可供选择的用户界面,作为一个CinderBlock项目,可以在这里找到它:http://www.syedrezaali.com/blog/?p=2366。

AntTweakBar

Cinder中的InterfaceGl建在AntTweakBar之上,可以在这里找到它的文档资料:http://www.antisphere.com/Wiki/tools:anttweakbar。2.2 保存和加载配置文件

很多应用程序依赖于用户输入的设置参数。例如,它可能是一些图形元素或参数的颜色或位置,用于同其他应用程序进行通信。对于应用来说,阅读来自外部文件的配置信息很有必要。我们将使用内置的Cinder支持,读写XML文件,实现配置持久化原理。做好准备

在主类中创建两个可配置的变量:要进行通信的IP地址和主机端口。如何操作

现在我们来实现loadConfig方法和saveConfig方法,用它们来加载应用程序启动时的配置信息,并在应用程序关闭时保存更改。

1.包含以下两个附加头文件:

2.准备两个方法,用来加载和保存XML配置文件。

3.在主类的setup方法中加入:

4.实现shutdown方法,如下所示:

5.要在主类中声明shutdown方法:如何工作

前两种方法loadConfig和saveConfig是必不可少的。loadConfig方法尝试打开配置文件config.xml,并找到general节点。general节点含有hostIP和hostPort节点。这些节点的值将被分配至应用程序中的相应变量:mHostIP和mHostPort。

在应用程序关闭前,Cinder自动触发shutdown方法,所以在退出应用程序时,配置值将被储存到XML文件中。最终,XML配置文件如下所示:

可以清楚地看到节点指向应用程序的变量值。还有更多

可编写自己的配置文件加载器和存储器,或使用已有的CinderBlock。

Cinder-Config

Cinder-Config是一个小型CinderBlock,同InterfaceGl一起用于创建配置文件。可以在这里找到它的资料:2.3 为当前的参数状态制作快照

我们将实现一个简单而有效的原理来保存和加载参数状态。范例中使用的代码基于前面章节所学。做好准备

例如,有一个变量需要频繁改变,即我们绘制的某个元素的颜色,主类包含以下成员变量:如何操作

使用内建的XML解析器和fileDrop事件处理程序。

1.包含以下附加头文件:

2.首先,实现两个方法,加载和保存参数:

3.声明一个类成员变量,作为触发快照生成的标记:

4.在setup方法中分配一个值:

5.在draw方法末尾的params::InterfaceGl::draw();代码行之前,输入以下代码:

6.在InterfaceGl窗口中创建一个按钮:

可以看到,此时还不具备makeSnapshotClick方法,但它很容易实现:

7.最后一步,添加以下方法,获得拖拽(drag-and-drop)支持:如何工作

有两种方法可以用于加载和存储XML文件中的mColor值:loadParameters和saveParameters。

需要对draw方法中输入的代码进行说明。等到mMakeSnapshot变量被设置为true,创建一个时间戳,以避免覆盖之前的快照。下面两行代码调用saveParameters方法,储存所选的值,并使用writeImage函数将当前窗口快照保存为PNG文件。注意,在调用InterfaceGl::draw前,已经加入代码,所以不用GUI即可保存窗口快照。

拖拽(drag-and-drop)功能是加载快照文件的好方法,其在fileDrop方法中实现;当文件被拖放到应用窗口中,Cinder调用该方法。首先,获得指向被拖放文件的路径;如果有多个文件,只需得到其中一个即可。然后调用loadParameters方法,被拖放文件的路径作为参数。2.4 使用MayaCamUI

由于我们模拟的是3D软件,所以要在3D场景中添加一个导航设备。使用MayaCamUI,只需几行代码就可以完成。做好准备

场景中需要有一些3D对象,可以使用Cinder提供的基元(Primitives),例如:

彩色立方体每一面都有一种不同的颜色,方便用来定位。其效果如图2-2所示。图2-2 3D对象图如何操作

进行以下步骤,创建摄像头导航。

1.需要MayaCam.h头文件:

2.在主类中声明一些成员:

3.在setup方法中,设置摄像头的初始状态:

4.实现三个方法:

5.在draw方法中,在3D绘制填充之前应用摄像头矩阵:如何工作

在setup方法中,对摄像头进行初始设置。在调整窗口尺寸时,必须更新摄像头的长宽比,所以需要在resize方法中添加代码。每当应用程序的窗口尺寸被调整时,Cinder会自动调用该方法。在mouseDown方法和mouseDrag方法中可捕获到鼠标事件。单击并拖拽鼠标进行滚动,右击鼠标进行缩放,使用中键进行平移。这样就能在应用程序中实现类似于常见3D软件的交互效果。2.5 使用3D空间指南

对于上述场景,使用内建的Cinder方法可将基本信息可视化,从而让3D空间用起来更轻松。做好准备

需使用前面章节中实现过的MayaCamUI导航。如何操作

绘制一些对象,帮助实现可视化,并找到3D场景的方位。

1.除MayaCamUI外,添加另一个摄像头。首先在主类中添加成员声明:

2.在setup方法中设置初始值:

3.在resize方法中更新mSceneCamera的长宽比:

4.实现keyDown方法,这样按下1键或2键就能在两个摄像头之间进行切换:

5.使用drawGrid方法,如下所示:

6.实现主要绘制流程,以下是完整的draw方法:如何工作

两个摄像头中的mSceneCam用于最终渲染,mMayaCam用于预览场景中的对象,其效果图如图2-3所示。按1键或2键,可切换摄像头。默认摄像头为MayaCam。图2-3 预览场景图

在图2-3中,可以看到整个场景中包含多种元素,如坐标系的原点,用来在3D空间中方便定位的结构网格,平截头体mSceneCam,以及3D空间两点之间的矢量视图。使用MayaCamUI可在整个空间中进行导航。

按下2键切换至mSceneCam视野图,则只能看到3D对象,无法看到向导,如图2-4所示。图2-4 换至mSceneCam视野图2.6 同其他软件进行通信

本节将在两个Cinder应用程序之间进行通信,以展示如何发送和接收信号。这两个应用程序中的任意一个都可轻松替换为非Cinder应用程序。

使用开源声音控制(OSC)消息格式,其专门用于网络中各种多媒体设备之间的通信。OSC使用UDP协议,具备优秀的灵活性和性能。每则消息包含类URL地址以及整数、浮点数或字符串格式的参数。OSC的普及使其成为连接网络乃至本地机器中不同环境或用不同开发技术开发的应用程序的强大工具。做好准备

下载Cinder包时,同时会下载四个主要代码模块。其中一个是位于blocks目录的osc模块。首先,在XCode项目根目录中添加一个新组,命名为Blocks,然后将osc文件夹拖拽至Blocks组中。注意检查Create groups for any added folders选项和Add to targets部分中的MainApp,如图2-5所示。图2-5 检查MainApp

由于只需包含osc文件夹中的一个src文件夹,因此在项目树中删除对lib和samples文件夹的引用。最终的项目结构如图2-6所示。图2-6 项目结构

在项目对话框中,必须向OSC库文件添加一个路径,指明链接标识的位置:CINDER_PATH作为项目build设置中用户自定义设置,表示Cinder根目录的路径。如何操作

首先处理sender指令,然后处理listener。

Sender

实现一个发送OSC消息的应用程序。

1.包含一个附加的头文件:

2.使用osc::Sender类,在主类中声明其所需属性:

3.在setup方法中建立发送器:

4.将mObjPosition的默认值设为窗口中心:

5.实现mouseDrag方法,其主要包含两个操作:一是根据鼠标位置更新对象位置;二是通过OSC发送位置信息。

6.最后,实现draw方法,将对象的位置可视化:

Listener

实现一个接收OSC消息的应用程序。

1.包含一个附加的头文件:

2.使用osc::Listener类,在主类中声明需要的属性:

3.在setup方法中建立监听器对象,将用于监听的端口号作为参数:

4.mObjPosition的默认值为窗口中心:

5.在update方法中,监听传入的OSC消息:

6.这里的draw方法同发送器版本基本相同,但需要绘制一个实心圆,替代多边形圆:如何工作

我们已经实现了通过OSC协议发送鼠标位置的发送器程序,其绘制了一个空心圆,如图2-7所示。这些带有/obj/position地址格式的消息,可以被任何其他框架和编程语言实现的非Cinder OSC应用程序接收。消息中的首个参数是鼠标的X轴位置,第二个参数是Y轴位置。两个参数都是float型。图2-7 发送器程序绘制图形

在本例中,接收消息的应用程序也是Cinder应用程序,其绘制了一个实心圆如图2-8所示,位置和发送器应用窗口中所指定的位置完全相同。图2-8 接收信息程序绘制图形还有更多

OSC能够提供多种可能性,以上只是其中一个简短的例子。这个简单的通信方法甚至可以应用在很复杂的项目中。当几个设备作为独立单元工作时,OSC会表现得很好。但在某种情况下,来自它们的数据会被处理。例如,来自摄像头的画面会被计算机视觉软件处理,其结果通过网络被发送到另一个机器上完成可视化投影。用UDP协议传输数据快于TCP,性能更优越,由于不需要连接握手,实现起来也更为简单。

广播

可设置一个广播地址作为目的主机:255.255.255.255,向网络中的所有主机发送OSC消息。例如,如果是子网络,可使用192.168.1.255。如链接器错误导致Mac OS X 10.7下编译有问题,在项目对话框中将Inline Methods Hidden设为No。另请参阅

打开以下链接,可以找到有关OSC使用的更多信息。

Flash中的OSC

使用以下库,在ActionScript 3.0代码中支持接收和发送OSC消息:http://bubblebird. at/tuioflash/。

Processing中的OSC

使用以下库,在Processing示意图中支持OSC协议:http://www.sojamo.de/libraries/oscP5/。

openFrameworks中的OSC

使用以下ofxOsc扩展,在openFrameworks项目中支持接收和发送OSC消息:http://ofxaddons.com/repos/112。

OpenSoundControl协议

有关OSC协议及相关工具的更多信息,访问其官方网站:http://opensoundcontrol.org/。2.7 准备iOS应用程序

使用Cinder的一大好处就是可以生成多平台代码。在很多示例中,无须太多修改,应用程序就可以在Windows、Mac OS X和iOS上进行编译。做好准备

为iOS设备开发应用程序需注册Apple Developer,并购买iOS Developer Program。如何操作

注册Apple Developer或购买iOS Developer Program后,可使用TinderBox创建一个用于iOS的初始化XCode项目。

1.运行TinderBox后,将Target设置为Cocoa Touch,如图2-9所示。图2-9 Target设置

2.它将生成一个项目框架,用来支持多点触控屏幕上的iOS事件。

事件可被用于多点触控,并为访问加速计数据带来便利。触屏和鼠标事件之间的主要区别是,可以存在多个活跃触点,但只能有一个鼠标光标。因此,每次触屏会话都有一个ID,可以从TouchEvent对象读取。表2-3列出了常用触控事件的方法及其解释。表2-3 常用触控事件的方法及其解释还有更多

建议参考Cinder包中的项目范例:MultiTouchBasic和iPhoneAccelerometer。

Apple Developer Center

有关iOS Developer Program的更多信息参考:https://developer.apple.com/。第3章 使用图像处理技术

本章学习目标:

►调整图片对比度和亮度;

►整合OpenCV;

►边缘识别;

►人脸识别;

►图像特征识别;

►将图像转换为矢量图形。引言

本章将使用几个例子来介绍Cinder中的图像处理技术以及第三方库。大多数例子包含图3-1这张被广泛使用的著名测试图片(从维基百科下载这张莱娜图:http://en.wikipedia. org/wiki/File:Lenna.png),用来阐述计算机视觉算法和技术。图3-1 测试图片3.1 调整图片对比度和亮度

本节介绍如何使用Surface类实现像素操作,进行基本的图片颜色转变。做好准备

更改对比度和亮度的值,需使用第2章用于调整参数设置的图形用户界面一节中的InterfaceGl。准备一张样图,将其命名为image.png,保存在assets文件夹中。如何操作

创建一个拥有简单GUI的应用程序,在样图上控制对比度和亮度。步骤如下:

1.包含必要的头文件:

2.添加属性到主类:

3.在setup方法中加载一张待处理图片,Surface对象用于储存处理好的图片:

4.将窗口尺寸设置为默认值:

5.添加参数值到InterfaceGl窗口:

6.实现update方法,如下所示:

7.最后,在draw方法中添加以下代码,绘制原图和处理过的图片:如何工作

最重要的部分在update方法中。在第6步,检查对比度和亮度参数是否被更改。如果是,则迭代原图的所有像素,并在mImageOutput中储存重新计算过的颜色值。改变亮度只是增加或减少每种颜色分量,而计算对比度则略为复杂。对于每一种颜色分量,使用乘法公式color=(color-0.5)*contrast+0.5,其中对比度是介于0.5和2之间的一个数字。在GUI中设置一个介于-0.5和1.0的值,这个范围更加自然;第6步的一开始重新计算了这个数值。在处理图片的过程中,必须更改所有像素的颜色值,所以在第6步后面,可以看到使用两个while循环迭代了每一行像素。为移动到下一行,在Surface迭代器上调用了line方法,接着调用了pixel方法移动到当前行的下一个像素。这种方法比getPixel和setPixel等方法更加快捷。

如图3-2所示调整测式图片对比度和亮度前后的对比图,左图为原图,右图为处理过的图片,可以对比颜色调整后的效果。图3-2 调整测试图片对比度和亮度前后的对比图3.2 整合OpenCV

OpenCV是一个强大的计算机视觉开源库。该库使用C++编写,因此可以轻易整合进Cinder应用程序。GitHub资源库中随Cinder包一起提供了很有用的OpenCV Cinder块(https://github.com/cinder/Cinder-OpenCV)。做好准备

确保启动和运行了带有Cinder项目的XCode。如何操作

如何向项目添加OpenCV Cinder块,添加任何其他Cinder块的方法与此相同。步骤如下。

1.在XCode项目根目录添加一个新组,命名为Blocks。将opencv文件夹拖到Blocks组中。选择Create groups for any added folders圆形按钮,如图3-3所示。图3-3 选择Create groups for any added folders选项

2.只需保留项目结构中opencv文件夹中的include文件夹即可,删除对其他文件夹的引用。最后项目结构如图3-4所示。图3-4 项目结构

3.在项目对话框的Other Linker Flags中添加OpenCV库文件的路径,如图3-5所示。这些路径例子如下:图3-5 添加OpenCV库文件的路径

4.如图3-6所示,在项目对话框的User Header Search Paths中添加将要使用的OpenCV Cinder块的路径:图3-6 添加OpenCV Cinder块的路径

5.包含OpenCV Cinder块的头文件:如何工作

OpenCV Cinder块为Cinder和OpenCV之间的数据交换提供了toOcv和fromOcv函数。在设置项目后即可使用它们,参考下面这个简短的例子:

在Cinder和OpenCV之间使用toOcv和fromOcv函数进行类型转换,储存经过ImageSourceRef类型处理过图片数据,例如Surface或Channel;其他类型见表3-1。表3-1 Cinder和OpenCV类型汇总表

此例中链接了来自OpenCV包的以下三个文件。

►libopencv_imgproc.a:该图片处理模块包含图片处理函数、过滤器、特征识别等。

►libopencv_core.a:该模块提供核心功能和数据结构。

►libopencv_objdetect.a:该模块含有对象识别工具,如级联分类器。

可在以下网址找到有关所有OpenCV模块的文档资料:http://docs.opencv.org/index.html。还有更多

OpenCV Cinder模块中预编译的OpenCV库有一些功能不可用,可以自行编译OpenCV库,仍可将OpenCV Cinder模块中的转换函数用于项目。3.3 边缘识别

本节将演示如何使用边缘识别函数,该函数是Cinder直接实现的图片处理函数之一。做好准备

确保启动和运行了带有Cinder项目的XCode。准备一张样图,命名为image.png并保存在assets文件夹中。如何操作

使用边缘识别函数处理样图,步骤如下。

1.包含必要的头文件:

2.在主类中添加两个属性:

3.加载源图片,在setup方法中为处理过的图片设置Surface:

4.使用图片处理函数:

5.在draw方法中添加以下两行代码,用来绘制图片:如何工作

可以看到,由于基本的图片处理函数直接在Cinder中实现,所以Cinder中的边缘识别非常容易,无需包含任何第三方库。这里,我们使用grayscale函数将原图的颜色空间转换为灰度模式。由于很多算法在灰度模式图片上更加高效,甚至专为灰度模式的源图片而设计,所以该函数在图片处理中很常用。边缘识别用edgeDetectSobel函数实现,使用索贝尔(Sobel)算法。首个参数是源灰度图片,第二个参数是用来储存输出结果的Surface对象。

两张图片都在draw方法中绘制,如图3-7所示,左图为原图,右图为灰度模式图。图3-7 测试图片转换为灰度模式前后对比图还有更多

Cinder实现的图片处理函数有可能不够用,因此可以在项目中包含第三方库,如OpenCV。上一节整合OpenCV已经讲述了如何一起使用Cinder和OpenCV。

Canny和findContours函数也可以用于识别边缘,其代码如下:

在执行以上代码后,构成轮廓的点存储在contours变量中。3.4 人脸识别

本节将讲述如何使用应用程序识别人脸。在OpenCV库的帮助下,这很容易做到。做好准备

由于要用到OpenCV库,请参考整合OpenCV一节,学习如何设置项目。准备一张样图,命名为image.png并保存在assets文件夹中。将哈尔(Haar)级联分类器文件放在assets目录中,用来识别正面人脸。该级联文件在下载的OpenCV包或在线公共存储库中可找到:https://github.com/Itseez/opencv/blob/master/data/haarcascades/haarcascade_frontalface_alt.xml。如何操作

创建一个应用程序,用来演示如何使用OpenCV和Cinder中的级联分类器,步骤如下:

1.包含必要的头文件:

2.在主类中添加以下成员变量:

3.在setup方法中添加以下代码段:

4.在setup方法末尾添加以下代码段:

5.在draw方法末尾添加以下代码段:如何工作

在第3步,加载了一个待处理的图片文件和一个XML分类文件,其中包含对所要识别对象特征的描述。在第4步,调用了mFaceCC对象的detectMultiScale函数,进行图片识别,在该对象中,将cvImage作为输入,并在矢量结构中储存结果。作为8位单通道图片(CV_8UC1),cvImage由mImage转换而来。下一步将迭代所有识别到的脸部,并储存Rectf变量,其表示被识别脸部周围的边界框。最后在第5步,绘制了原始图片和所有被识别的脸部,带有描边矩形,如图3-8所示。

我们使用了OpenCV库中的哈尔(Haar)级联分类器,它可以被训练用于识别图片中的一个特定对象。更多有关训练和使用级联分类器识别对象的信息可以在OpenCV文档资料中找到:http://docs.opencv.org/modules/objdetect/doc/cascade_classification.html。图3-8 脸部识别结果还有更多

使用来自摄像头的视频流并处理每幅画面,以实时人脸追踪。参考第11章检测与跟综摄像头中的从摄像头捕捉。3.5 图像特征识别

本节将介绍一种查找图像特征的方法,将使用OpenCV库中的SURF算法实现。做好准备

由于要用到OpenCV库,请参考整合OpenCV一节中有关如何设置项目的信息。准备一张样图,命名为image.png并保存在assets文件夹中,再保存该图片的一份备份,命名为image2.png并对其进行某些转换,如旋转。如何操作

创建一个应用程序,用来将两张图片之间的匹配特征点可视化。步骤如下:

1.在项目对话框的Other Linker Flags部分添加OpenCV库文件的路径,例如:

2.包含必要的头文件:

3.在主类声明中添加方法和属性:

4.在setup方法中加载图片,并调用匹配方法:

5.实现之前声明的matchImages方法:

6.最后一件事是完成可视化,在draw方法中放入以下代码行:如何工作

让我们看一看第5步的代码。首先将image1和image2转换为OpenCV Mat结构。然后将这两张图片转换为灰度模式。这样就可以使用SURF算法处理图片,能够识别一些关键点——由该算法计算出的图片特征点。使用两张图片中被计算出的关键点,并用FLANN来匹配它们,更准确地说是FlannBasedMatcher类。在过滤出合适的匹配点后将其储存在good_matches矢量中,然后实现可视化,匹配结果如图3-9所示。请注意第二张图片被旋转,但算法仍能找到并连接相应的关键点。还有更多

对于匹配图片来说,识别图片中的明显特征至关重要,这也是增强现实应用程序中更高级别算法的一部分。

如果图片匹配

可以使用matchImages方法判断其中一张图片是否是另一张的备份或旋转后的,它可以返回许多匹配点。图3-9 两图特征点匹配结果

其他可能性

对于实时匹配而言,SURF实际上是一种较为缓慢的算法,如需实时处理摄像头的画面,可在项目中使用FAST算法。FAST算法也包含在OpenCV库中。还有更多

►这里有对各种OpenCV特征识别算法的比较:

http://computer-vision-talks.com/2011/01/comparison-of-the-opencvs-feature-detection-algorithms-2/。3.6 将图像转换为矢量图形

本节将使用OpenCV库和Cairo库中的用于矢量绘制和输出的图像处理函数,把简单的手绘素描图像转换成矢量图形。做好准备

由于需要使用OpenCV库,请参考本章中整合OpenCV一节中有关如何设置项目的信息。可将自己的画用来处理。本例使用一张含有几个简单几何形状的素描图片,如图3-10所示。图3-10 转换前的素描图片如何操作

我们将创建一个应用程序,展示如何转换为矢量图形。步骤如下:

1.包含必要的头文件:

2.在主类中添加以下声明:

3.加载素描图片,在setup方法中设置默认值:

4.在setup方法末尾添加以下代码段:

5.添加renderDrawing方法的实现:

6.实现draw方法,如下所示:

7.在keyDown方法中插入以下代码段:如何工作

在第4步实现了关键的部分,识别了图片中的边缘,寻找了轮廓。在第5步中,在renderDrawing方法里绘制矢量图形,表示处理的形状。使用Cairo库绘制矢量图,该库能够将结果以多种矢量格式保存到一个文件里。正如图3-11中显示的,在左上角有一个原始图片,左下角是识别到的轮廓预览。右侧是简单手绘图的矢量版。图3-11 用Cairo库绘制矢量图

每个形状都是一个黑色填充的路径。路径包含第4步计算出来的点。图3-12是带有高亮点的可视化图形。图3-12 带有高亮点的可视化图

S按键可用来将矢量图形保存为文件。文件将保存在应用程序可执行文件所在的文件夹内,命名为output.svg。SVG只是表3-2中导出选项之一。表3-2 保存方法及其用途

导出的图像如图3-13所示。图3-13 导出的矢量图另请参阅

►Cairo:http://cairographics.org/

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载