《Java图像处理:基于OpenCV与JVM》 ——1.15 用Kotlin写OpenCV代码
1.15 用Kotlin写OpenCV代码
问题定义
使用Scala写OpenCV变换程序令人兴奋,但现在谷歌正在力推Kotlin语言,你将会非常喜欢使用Kotlin写OpenCV代码。
解决方法
当然,Leiningen中有Kotlin插件。就像Scala设置一样,你需要再一次在project.clj文件中更新元数据。
你最需要做的是添加Kotlin插件以及访问Kotlin源文件的路径。
工作原理
基本设置
在project.clj文件中需要更新的地方同那些在Scala设置需要更新的地方十分相似,并且已在接下来的代码片段中被高亮标出。
因为Kotlin类是通过插件显式地编译到JavaVM字节码中,你可以参考那些到目前为止你已经完成编译的类。
显而易见,第一个测试是检验你是否可以加载一个矩阵对象并且打印它的0和1值。
下面十分简短的Kotlin代码片段实现了上述功能。
在你执行通常的Leiningen运行命令之前,需要将First.kt文件放到Kotlin文件夹中。
这个命令输出同样是必要的,展示了正确创建的OpenCV对象并且将它打印到控制台中。
这是一个简单的示例。让我们使用Kotlin和OpenCV来完成更加复杂一点的事情吧。
颜色映射
下面这个新示例展示出如何使用Imgproc类中的applyColorMap函数完成不同颜色映射之间的变换,这个示例完全用Kotlin代码实现。
就像你掌握的那样,Kotlin的构造函数调用不需要使用明确的new关键字,而且就像在Scala中一样,可以使用静态引入方法。
现在你可以从图1-41中的原始输入图像开始看这段代码的运行效果。
你会看到程序创建了三个文件,如图1-42、图1-43和图1-44所展示的三个输出文件所示。
图1-41 猫咪做好了准备 图1-42 应用BONE的猫咪
图1-43 应用WINDER的猫咪 图1-44 应用HOT,并变换了尺寸的猫咪
在Kotlin中,合适的类型转换看上去有一些挑战,但是代码同样是非常紧凑的,就像在Scala中移除了一些样板代码。
用户接口
你想要使用Kotlin的一个主要原因是它那不可思议的tornadofx库,这个库使在GUI框架JavaFX下的JVM中编写简单的用户接口变得更容易。
这样的小应用对于给用户创造调整OpenCV参数的机会并且伪实时地看到结果,是非常有用的。
Kotlin设置
tornadofx库可以被添加到存在于依赖部分的project.clj文件中,如下面提取出的片段所示。
由于本攻略的目的是培养你创造性的想法,因此我们不再深入学习如何编写Kotlin程序以及使用tornadofx库编写Kotlin程序。但是你将很快学习到一些如何将这些方法集成到OpenCV中的Kotlin示例。
下面的第一个示例将向你介绍如何引导你的Kotlin代码显示一帧中的一副图像。
仿制用户接口
一个简单的tornadofx应用基本遵循了一个结构,即给定的启动器(Launcher)→应用→视图,如图1-45中的流程图所示。
图1-45 tornadofx应用流程图
有了这张图的概念,我们需要创建三个类。
HelloWorld0:UI应用的主视图
MyApp0:用来发送给JavaFX启动器的JavaFX应用对象
World0:主类,只会被创建一次,因此使用对象代替类来定义它,以此启动基于JVM的应用
一个tornadofx中的视图由一个根面板(Root Panel)组成,你可以按照自己的意愿定制JavaFX小部件作为根面板。
下面的代码创建一个单一视图,该视图由嵌入在imageview小部件中的图像组成。
imageview中图像的尺寸由定义小部件的模块设置。
视图初始化由init{......}模块完成,而且由于根对象无法再一次初始化,因此使用神奇的with函数完成。
这段代码的其余部分是标准的tornadofx/javafx样板模板,以此正确启动基于JavaFX的应用。
如同到目前为止你所完成的那样,通过如下命令使用Leiningen自动模式运行上述代码。
你的屏幕上将会出现图形化的一帧(图1-46)。
图1-46 一帧中的图像
实际上,这段代码和这一帧有一些不同。在根模块中,通过在合适的地方插入下面的代码片段设置了一个标题。你会找到这是在哪里插入的。
反馈按钮的用户接口
接下来的示例基于前述示例并且增加了一个按钮,当按下按钮,内部计数器会增加,而且计数器的值会实时显示在屏幕上。
反馈值可以通过SimpleIntegerProperty建立,或者通过javafx.beans包中的Simple-
XXXProperty建立。
该反馈值可以绑定到小部件上,在接下来的示例中,将会绑定到一个标签上,因此标签值与属性值相同。
按钮是你可以用来定义一个处理句柄的UI小部件。句柄代码存在于模块内部或者一个不同的Kotlin函数中。
根据上述目标和解释,让我们开始介绍下面的代码片段。
运行计数器应用的结果如图1-47所示。
在点击这个漂亮的按钮几次之后,你会得到如图1-48所示内容。
图1-47 简单的计数器应用 图1-48 点击几次按钮后增加计数器数值
模糊应用
这些应用很酷,但这看上去像是创建GUI的课程,而且同OpenCV没有太大关系。
确实如此。
因此,最后一个Kotlin应用基于上述两个示例,介绍如何建立一个模糊应用,其中模糊程度由反馈属性设置。
你需要在Java环境下的图像对象和OpenCV环境下的Mat对象来回转换。下面的示例介绍一种快速转换的方法,通过使用OpenCV的imencode函数实现,该函数将Mat对象编码为字节而无须将它们存储到文件中。
这个模糊应用使用了SimpleObjectProperty类型的变量,该变量随着它的图像化视图更新而变化。
较长的导入列表有些烦人,但你可能不必为自己自定义的应用加入更多的导入。
通常情况下,Leiningen在文件改变后为你自动完成全部Kotlin编译工作,模糊应用效果如图1-49所示。
图1-49 模糊应用
当你点击增加(increment)按钮后,猫咪图像变得越来越模糊;当你点击减小(decrement)按钮后,它变得越来越清晰。
在本书的代码样本中有更多的tornadofx示例,因此无须犹豫,找出它们来练习。你可能会通过OpenCV方法获得更多的UI。例如一个图像拖拽面板,图像可以根据你的意愿被模糊处理。那听起来不再是无法实现的,是吗?
第1章写满了攻略,从在基于JavaVM的OpenCV中建立一个小项目开始,逐渐学习更加复杂的图像操作示例,最开始使用Java,最终熟练使用JavaVM运行环境,以使用Scala代码以及含有令人印象深刻的tornadofx库的Kotlin代码。
介绍origami库的大门已经打开,该库是为OpenCV设计的Clojure封装。该环境带给你更加简洁的代码并且更具有交互性,以此来尝试新事物并且变得更加有创造性。是时候兴奋起来了。
我对未来有兴奋的感觉,而我不知道那看上去会是什么样。但是无论如何,未来将会是我创造的样子。
——Amanda Lindhout
- 点赞
- 收藏
- 关注作者
评论(0)