Catalano 框架






4.98/5 (37投票s)
Java 和 Android 的科学计算。
引言
大家好!我叫 Diego Catalano,是一名 Java 程序员。有一段时间,这对我来说是个问题,因为我是 .NET 中用于图像处理和科学计算的 AForge.NET 和 Accord.NET Frameworks 的忠实粉丝。不幸的是,这意味着我无法在我最喜欢的环境之一:Android 中使用这两个框架。
在本文中,我将介绍一项持续的努力,旨在将这两个框架的最佳功能引入 Java;并进一步暗示一旦我们将所有这些强大功能融入移动计算中,我们可以做什么。我将介绍 Catalano Framework,一个用 Java 编写的科学计算框架,充分考虑了最大程度的可移植性。 在此过程中,我得到了 Accord.NET 作者 César Souza 的帮助,不仅将最新的更新引入我自己的框架,还将我自己的实现和发现贡献给 Accord.NET。
另外,请允许我澄清一点。由于我了解 AForge.NET 和 Accord.NET 的使用,我获得了一份工作。今天,我的愿望是回馈社区,用我自己的贡献来回报大家。一个工具,在一个独立的应用程序中,为桌面、服务器和移动应用程序带来科学计算功能。
引言
主要思想是将这两个框架的大部分类进行扩展、改进和移植到 Java。因此,我已经建立了与上述库相同的著名架构划分,为不同的需求使用不同的命名空间。
如果您已经熟悉这两个项目中的任何一个,您应该会感觉很自在。该框架分为以下命名空间:
- Catalano.Image
- Catalano.Fuzzy
- Catalano.MachineLearning
- Catalano.Math
- Catalano.Neuro
- Catalano.Statistics
要使用该框架,只需像在 AForge.NET 或 Accord.NET 中一样添加库引用。在 NetBeans 中,您可以像在 Visual Studio 或 SharpDevelop 中加载 .dll 库一样,添加对 .jar 文件的引用。
如果您使用 Eclipse 开发Android应用程序(例如,使用 Android SDK),您只需要做一个小小的改动:将引用 Catalano.Image.jar 改为引用 Catalano.Android.Image.jar。
这就是您开始使用该库所需的一切。现在让我们看看我们可以用它做什么!
图像处理库
图像处理是 AForge.NET 的核心功能之一。除了提供上述框架中的所有实现之外,我还添加了几个新的图像处理算法,特别适用于各种应用。我想展示的一个应用是自动二值化图像文档。
下面两张图片将演示我们如何使用 Bradley 局部阈值化来恢复文档。
原始图像: 处理后的图像
这是我用来实现这一功能的代码:
//Load an image
FastBitmap fb = new FastBitmap("bradley.png");
// Convert to grayscale
Grayscale g = new Grayscale();
g.applyInPlace(fb);
// Apply Bradley local threshold
BradleyLocalThreshold bradley = new BradleyLocalThreshold();
bradley.applyInPlace(fb);
//Show the result
JOptionPane.showMessageDialog(null, fb.toIcon(), "Result", JOptionPane.PLAIN_MESSAGE);
正如所见,我们在这里使用了 AForge.NET 框架提供的几乎完全相同的接口。这应该可以轻松地将知识从一个框架迁移到另一个框架,只需最少的工作。除了 Bradley 局部阈值化之外,在 Catalano 框架中,您还会找到其他几种算法,例如
- Bernsen 阈值
- Niblack 阈值
- Sauvola 阈值
- Wolf Jolion 阈值
如果您对图像二值化不感兴趣,让我们来看另一个例子:找到场景中的一些兴趣点。
角点检测算法有多种用途,包括 在 CodeProject 的其他文章中已经展示的一些用途。除其他外,它们可用于匹配图像之间的点,执行特征提取以进行后续的图像分类、场景理解、图像配准等等。
在 Catalano 框架中,角点检测几乎完全遵循 Accord 和 AForge.NET 中的接口。下面的示例展示了如何应用 Susan 角点检测来识别样本图像中的兴趣点:
//Load an image
FastBitmap fb = new FastBitmap("blocksTest.gif");
Grayscale g = new Grayscale(Grayscale.Algorithm.Average);
g.applyInPlace(fb);
SusanCornersDetector susan = new SusanCornersDetector();
ArrayList<IntPoint> lst = susan.ProcessImage(fb);
//If you want to detect using Harris
//HarrisCornersDetector harris = new HarrisCornersDetector();
//ArrayList<IntPoint> lst = harris .ProcessImage(fb);
fb.toRGB();
for (IntPoint p : lst) {
fb.setRGB(p, 255, 0, 0);
}
Susan 角点检测器 Harris 角点检测器
图像处理库 (Android)
现在,这才是本框架真正的威力所在。让我们看看我们如何实现与之前相同的功能,但这次是从 Android 设备内部进行的。以下代码重现了本文中的第一个示例,使用 Bradley 的局部阈值化算法二值化样本图像,但直接从 Android 设备进行。
ImageView image = (ImageView)findViewById(R.id.imageView1);
//Load an image
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.sample20);
//Load Fast bitmap
FastBitmap fb = new FastBitmap(bm);
//Convert to grayscale
Grayscale g = new Grayscale();
g.applyInPlace(fb);
//Apply Bradley local threshold
BradleyLocalThreshold bradley = new BradleyLocalThreshold();
bradley.applyInPlace(fb);
//Display the result
image.setImageBitmap(fb.toBitmap());
在此框架下,还有其他几种图像处理算法可用。其他示例包括边缘检测算法,例如Sobel 算子。作为一种边缘检测算法,它能够突出图像中存在的任何边框或边界。其用法在 Android 和标准 Java 应用程序中完全相同。
以下示例演示了如何在 Android 中运行 Sobel 边缘检测器。
//Convert to grayscale
Grayscale g = new Grayscale();
g.applyInPlace(fb);
//Apply Bradley local threshold
SobelEdgeDetector sobel = new SobelEdgeDetector ();
sobel.applyInPlace(fb);
我希望这能引起大多数人的兴趣——但请注意,我们才刚刚触及框架的表面!
改进
AForge.NET 中最古老的功能之一是能够对图像执行快速傅里叶变换 (FFT)。此功能将图像从空间域转换到频率域,允许使用几种有趣的图像处理过滤器,如频率通带滤波器,甚至通过空间卷积/频率乘法定理来帮助改进卷积。
然而,大多数 FFT 实现都存在一个限制,包括 AForge.NET 中提供的实现。问题在于,根据定义,FFT 只能在宽度和高度均为 2 的幂的图像上执行。这意味着计算 64x64
、512x512
、1024x1024
图像的 FFT 是可以的,但如果尝试计算 592x634
图像的变换,则行不通。
请注意,这并非实现本身的限制,而是由于使快速傅里叶变换快速的几个基本假设所致。为了规避这一点,可以使用一种称为零填充的功能。
零填充只是向图像添加额外的零值像素,直到其尺寸成为 2 的幂。之后,我们正常计算 FFT,然后移除我们在第一步中添加的额外元素。因此,请考虑以下在 C# 中使用 AForge.NET 的示例:
Bitmap image = new Bitmap("test.bmp");
image = new GrayscaleBT709().Apply(image);
ComplexImage ci = ComplexImage.FromBitmap(image);
ci.ForwardFourierTransform();
在这里,如果 test.bmp 的尺寸不是 2 的幂,我们很可能会遇到 AForge.Imaging.InvalidImagePropertiesException
异常。
现在,在以下示例中,我们将不仅执行傅里叶变换,还将运行频率过滤器来提取任意大小图像的低频成分:
FastBitmap fb = new FastBitmap("c:\\files\\test.bmp");
fb.toGrayscale();
JOptionPane.showMessageDialog(null, fb.toIcon(), "Image", JOptionPane.PLAIN_MESSAGE);
FourierTransform ft = new FourierTransform(fb);
ft.Forward();
fb = ft.toFastBitmap();
JOptionPane.showMessageDialog(null, fb.toIcon(), "Fourier Transform", JOptionPane.PLAIN_MESSAGE);
FrequencyFilter ff = new FrequencyFilter(0, 60);
ff.ApplyInPlace(ft);
fb = ft.toFastBitmap();
JOptionPane.showMessageDialog(null, fb.toIcon(), "Frequency Filter", JOptionPane.PLAIN_MESSAGE);
ft.Backward();
fb = ft.toFastBitmap();
JOptionPane.showMessageDialog(null, fb.toIcon(), "Result", JOptionPane.PLAIN_MESSAGE);
结果如下所示。我们可以看到非方形图像是如何被转换到频域,过滤,然后以相同的前原始尺寸转换回时域的。
|
|
原始图像 (480x361)
![]() |
傅里叶变换 (512x512)
![]() |
频率过滤器 (512x512)
![]() |
结果图像 (480x361)
![]() |
基准测试
我决定专门开辟一个部分来展示 Catalano 框架与 AForge.NET 和 Accord.NET 中可用标准功能的基准测试。这里的目标不是证明哪个更好,而是提供一些基线比较,以表明当前实现可以期待什么。
所有测试都重复了 100 次。在实际测量开始之前,已经排除了初始执行(100 次之前的执行),以让任何可能的编译器/JIT 优化能够快速启动。所有测试均在 Visual Studio 外部进行,即通过转到二进制文件夹并直接运行可执行文件。所有二进制文件均以 Release 模式编译,适用于 Any CPU(意味着它们在 64 位模式下运行)。所有测试均使用以下规格的同一台机器运行:
处理器:Intel® i7-2670QM CPU @ 2.20Hz,4 核(超线程 8 个),6 MB 缓存
内存:8 GB,DDR3 1600MHz
第一个测试以简单的中值滤波器开始。在此测试中,我们使用 5x5 内核窗口处理了一个 1024 x 770
的 RGB 图像。
在此特定测试中,Catalano 框架(非并发)和 AForge.NET 之间的差异约为 10 秒。如果我们考虑一个并行实现,它应该利用测试机器上的所有 4 个核心,那么差异会更大,达到惊人的 71 秒。
第二个测试以简单的 Sobel 边缘检测器开始。在此测试中,我们使用并行、直接和 AForge.NET 的默认实现处理了一个 1024 x 770
的灰度图像。
正如我们在这里可以看到的,Catalano 框架(非并发)和 AForge.NET 之间的差异仅为 467 毫秒。并发版本在此基础上进一步提高,速度大约是原始 AForge.NET 实现的两倍。由于测试机器有 8 个虚拟核心,这意味着该算法并不是可以轻松并行化的。
现在,关于第三个测试。这个测试涉及到测量对 1024 x 770 RGB 图像进行高斯模糊处理所需的时间。结果如下所示。
在此特定测试中,我们可以看到 AForge.NET 以至少 4 秒的优势胜过了 Catalano。再次,我们可以看到两个实现是可比的,而 AForge.NET 在此测试中得分稍高。
第四个测试是针对 Accord.NET 的 Harris 角点检测器进行的。在此测试中,我们处理了一个 1024 x 770 的灰度图像,结果如下所示。
正如我们所见,Accord.NET 在此测试中得分略高,但两者的差异非常可比且相同。这表明 C# 和 Java 在此类应用程序上的性能也可以非常相似。
最后,最后一个测试是通过比较 Catalano 和 Accord.NET 中的 FAST 角点检测器进行的。此测试涉及使用 FAST-9(FAST 检测的特定版本)处理一个 1024 x 770
的灰度图像。结果如下所示。
可以看到,这一次 Catalano Framework 和 Accord.NET 之间的差异实际上非常显著,约为 23649 毫秒。此测试清楚地表明 Accord.NET 的实现优于 Catalano Framework 的实现。正如我们所见,还有很大的改进空间和工作要做——但最重要的是,将图像处理引入 Android 的总体目标已经基本实现!
结论
在本文中,我尝试向世界介绍 Catalano 框架。在这里,我们看到了这个相对较新的框架如何通过统一 Accord 和 AForge.NET Frameworks 的最佳功能,为在 Java 中创建图像处理和科学计算应用程序提供了新的途径,从而丰富了开源生态系统。开发正在全力进行,并且 正在 Github 上运行。
从我开始构建框架到现在,我获得了在多个不同领域的知识,从科学方法到软件工程和系统设计。为此,我非常感谢一路上遇到的所有好人,包括同意以 LGPL 兼容许可证共享其代码的研究人员,以便他们能够集成到框架中。
我希望您能像我享受开发它一样享受这个框架!
未来工作
从现在开始,我打算改进几个领域。我的大部分贡献正在逐步与 César(来自 Accord.NET Framework)共享,以便集成到他的框架中;其他功能也在一些帮助下从 .NET 移植到 Java。
我打算创建一个博客,解释 Catalano Framework 中的每个过滤器,并展示一些实际的示例应用程序来演示其功能。还有一个计划是将存储库迁移到 GitHub,以简化代码贡献。
还有一些关键点我想继续努力:
- 移植到 Google Glass®(我很乐意接受一个用于测试 :-P)。
- 将所有过滤器转换为使用多线程、并行处理。
- 添加一个用于生物识别相关算法的库。
- 继续工作、扩展和改进整个框架。
历史
- 2013 年 11 月 1 日 - 首个版本发布。