gpt4 book ai didi

c++ - Imagemagick C++ : Reducing memory usage

转载 作者:行者123 更新时间:2023-11-28 05:53:07 25 4
gpt4 key购买 nike

我有一个用例,我想交叉比较 2 组图像以了解最相似的对。

但是,集合很大,出于性能目的,我不想一直打开和关闭图像。

所以我的想法是:

std::map<int, Magic::Image> set1;
for(...) { set1[...] = Magic::Image(...);}

std::map<int, int> best;
for(...) {
set2 = Magic::Image(...);
//Compare with all the set1
...
best[...] = set1[...]->first;
}

很明显,我不需要存储所有第 2 组,因为我是逐张处理图像。但无论如何 set1 已经太大了,存储 32 位图像太多了。供引用:15000 张图片,300x300 = 5GB

我想通过将图像降采样为单色来减少内存(这不会影响我的用例)。但是怎么做呢?即使我得到一个颜色 channel ,Image-Magick 仍然威胁新图像为 32 位,即使它只是一个 channel 。

我的 final方法是编写一个自解析器,逐个读取颜色、转换它并创建一个位 vector 。然后做 XOR 和计数位。这样可行。 (仅使用 170 MB)

但是,并不灵活。如果我想在某个时候使用 2 位或 8 位怎么办?是否有可能以任何方式使用 Imagemagick 自己的类并调用 compare()

谢谢!

最佳答案

我有几个建议 - 也许可以给您一些建议!

建议1

也许您可以使用感知哈希。您无需将所有图像保存在内存中,而是一次为每张图像计算一个哈希值,然后比较哈希值之间的距离。

一些 PHASHes 对图像缩放具有不变性(或者您可以在散列之前将所有图像缩放到相同的大小)并且大多数对图像格式具有不变性。

这是 Neal Krawetz 博士的一篇文章... Perceptual Hashing .

ImageMagick 还可以执行感知散列并且可以从 PHP 调用 - 参见 here .

前段时间我也为这类事情写了一些代码... code.

建议2

我知道 ImageMagick 第 7 版即将推出 - 不知道谁能告诉你更多 - 它支持真正的单 channel 、灰度图像 - 以及多达 32 channel 的多光谱图像。我相信它也可以充当服务器——在内存中保存图像以供后续使用。也许这会有所帮助。

建议3

也许您可以从 GNU Parallel 中获得一些好处 - 它可以让您的所有 CPU 内核并行忙碌,并且还可以使用 ssh 在多个服务器上分配工作。那里有很多教程和示例,但只是为了演示将一组命名图像 (a、b、c、d) 中的每一项与一组编号图像 (1,2) 中的每一项进行比较,您可以这样做:

parallel -k echo {#} compare {1} {2} ::: a b c d ::: 1 2

输出

1 compare a 1
2 compare a 2
3 compare b 1
4 compare b 2
5 compare c 1
6 compare c 2
7 compare d 1
8 compare d 2

显然,我已经将 echo 放在那里,因此您可以看到生成的命令,但您可以删除它并实际运行 compare

因此,您的代码可能看起来更像这样:

#!/bin/bash

# Create a bash function that GNU Parallel can call to compare two images
comparethem() {
result=$(convert -metric rmse "$1" "$2" -compare -format "%[distortion]" info:)
echo Job:$3 $1 vs $2 $result
}
export -f comparethem

# Next line effectively uses all cores in parallel to compare pairs of images
parallel comparethem {1} {2} {#} ::: set1/*.png ::: set2/*.png

输出

Job:3 set1/s1i1.png vs set2/s2i3.png 0.410088
Job:4 set1/s1i1.png vs set2/s2i4.png 0.408234
Job:6 set1/s1i2.png vs set2/s2i2.png 0.406902
Job:7 set1/s1i2.png vs set2/s2i3.png 0.408173
Job:8 set1/s1i2.png vs set2/s2i4.png 0.407242
Job:5 set1/s1i2.png vs set2/s2i1.png 0.408123
Job:2 set1/s1i1.png vs set2/s2i2.png 0.408835
Job:1 set1/s1i1.png vs set2/s2i1.png 0.408979
Job:9 set1/s1i3.png vs set2/s2i1.png 0.409011
Job:10 set1/s1i3.png vs set2/s2i2.png 0.407391
Job:11 set1/s1i3.png vs set2/s2i3.png 0.408614
Job:12 set1/s1i3.png vs set2/s2i4.png 0.408228

建议3

我不久前写了一篇关于使用 REDIS 缓存图像的回答 - 它也可以在小型服务器池中以分布式方式工作。那个答案是here .

建议4

您可能会发现,将第二组图像转换为 Magick Pixel Cache 格式可以获得更好的性能,这样它们就可以通过 DMA 存储到内存中,而不是每次都需要解码和解压缩。所以你会这样做:

convert image.png image.mpc

它为您提供了 ImageMagick 可以非常快速读取的这两个文件。

-rw-r--r--      1 mark  staff      856 16 Jan 12:13 image.mpc
-rw------- 1 mark staff 80000 16 Jan 12:13 image.cache

请注意,我并不是建议您以 MPC 格式永久存储图像,因为它是 ImageMagick 独有的并且可以在不同版本之间更改。我建议您在每次运行分析之前生成该格式的拷贝。

关于c++ - Imagemagick C++ : Reducing memory usage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34791778/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com