我正在尝试使用Clojure处理图像,我想使用Clojure数据结构来表示图像。基本上,我的第一种方法是使用向量矢量和mapv
来操作每个像素值,并返回具有相同数据结构的新图像表示。但是,一些基本操作需要花费太多时间。
使用Jvisual分析器,我得到的结果如下所示。有人可以给我一个改善表现的小费吗?如果有必要,我可以提供更多详细信息,但也许只是查看seq
和next
的成本可以让人有个好猜测。
答案 0 :(得分:7)
您应该查看 core.matrix 和相关库,了解与矩阵计算有关的任何内容。 core.matrix是一种用于矩阵计算的通用Clojure API,支持多种后端实现。
Clojure的持久数据结构非常适合大多数用途,但实际上并不适合快速处理大型矩阵。主要问题是:
您可能想要查看的相关库是:
根据您的想法,最佳方法可能是使用图像矩阵将图像转换为vectorz-clj矩阵并在那里进行处理。或者,Clisk可能能够开箱即用(它有很多现成的滤镜/失真效果等)。
免责声明:我是上述大部分图书馆的首席开发人员。但是我自己一直在使用它们来做认真的工作,所以非常愿意保证它们的实用性,并帮助解决你发现的任何问题。
答案 1 :(得分:3)
我真的认为你应该为此使用基元数组。 Clojure内置阵列支持,即使它没有突出显示,也适用于这样的情况,你有大量的数值数据。
任何其他方法,向量,甚至是java集合都会导致所有数字被单独装箱,这非常浪费。基元的数组(int,double,byte,任何合适的)都没有这个问题,这就是为什么它们存在的原因。人们对在clojure中使用数组感到害羞,但他们出于某种原因,这就是它。并且它将是好的可用的clojure代码 - int-array在jvm clojure和clojure-script中都有效。
尝试数组和基准测试。
答案 2 :(得分:1)
Clojure的Transients提供了完全持久性和无持久性之间的中间地带,就像使用标准java数组一样。这允许您使用快速mutate-in-place操作(仅限于当前线程)构建映像,然后调用persistent!
将其在常量时间转换为适当的持久性结构,以便在其余部分中进行操作程序
看起来你也看到了使用序列覆盖图像内容的大量开销,如果瞬态没有产生足够的差异,你可能想要接下来考虑使用普通的java数组并构建访问权限直接访问数组元素。