65.9K
CodeProject 正在变化。 阅读更多。
Home

Catalano 框架

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.98/5 (37投票s)

2013年11月4日

CPOL

10分钟阅读

viewsIcon

125745

downloadIcon

3767

Java 和 Android 的科学计算。

引言

大家好!我叫 Diego Catalano,是一名 Java 程序员。有一段时间,这对我来说是个问题,因为我是 .NET 中用于图像处理和科学计算的 AForge.NETAccord.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 框架中,您还会找到其他几种算法,例如

  1. Bernsen 阈值
  2. Niblack 阈值
  3. Sauvola 阈值
  4. 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 的幂的图像上执行。这意味着计算 64x64512x5121024x1024 图像的 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 框架。在这里,我们看到了这个相对较新的框架如何通过统一 AccordAForge.NET Frameworks 的最佳功能,为在 Java 中创建图像处理和科学计算应用程序提供了新的途径,从而丰富了开源生态系统。开发正在全力进行,并且 正在 Github 上运行。

从我开始构建框架到现在,我获得了在多个不同领域的知识,从科学方法到软件工程和系统设计。为此,我非常感谢一路上遇到的所有好人,包括同意以 LGPL 兼容许可证共享其代码的研究人员,以便他们能够集成到框架中。

我希望您能像我享受开发它一样享受这个框架!

未来工作

从现在开始,我打算改进几个领域。我的大部分贡献正在逐步与 César(来自 Accord.NET Framework)共享,以便集成到他的框架中;其他功能也在一些帮助下从 .NET 移植到 Java。

 

我打算创建一个博客,解释 Catalano Framework 中的每个过滤器,并展示一些实际的示例应用程序来演示其功能。还有一个计划是将存储库迁移到 GitHub,以简化代码贡献。

还有一些关键点我想继续努力:

  • 移植到 Google Glass®(我很乐意接受一个用于测试 :-P)。
  • 将所有过滤器转换为使用多线程、并行处理。
  • 添加一个用于生物识别相关算法的库。
  • 继续工作、扩展和改进整个框架。

历史 

  • 2013 年 11 月 1 日 - 首个版本发布。
© . All rights reserved.