gpt4 book ai didi

java - 哈希位图的廉价/快速方法?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:02:22 24 4
gpt4 key购买 nike

我有一个应用程序可以获取图片库(全部为 Jpeg 格式)并给出每对可能图片之间的相似度分数。在每个时间点,只能选择一对并显示其相似度得分。

比较两幅图像的算法具有一定的性能成本,因此比较一对图像需要几秒钟。

选中两张图片时:

  1. 如果该对从未进行过比较,则分数显示“尚未得分”。用户可以单击“分数”按钮,这对将被发送到一个线程,该线程对要计算的分数进行排队。示例:http://db.tt/gb1Yk6yx
  2. 如果该对当前在要计算的队列中,则分数字段显示“正在计算...”。示例:http://db.tt/OvS1qGP3
  3. 如果该对已被比较,则显示该对所附的分数。示例:http://db.tt/m2OQGybW

示例(进行批处理时):http://db.tt/iD67SdCp

如果从未计算过分数,并且用户单击“分数”,该字段将切换为“正在计算...”,然后在计算完成时显示分数。

在分数字段显示任何内容之前,选择两对时,将其附加的位图发送到hashmap,以验证这两个位图是否已经具有附件分数,在这种情况下,它只是将其返回。如果没有分数,则作业在队列中发送。

要知道分数是否存在于缓存中,我需要找到一种方法来散列该对,以便我可以使用生成的键来查找缓存。这就是我的问题所在。为了有意义,两个 Bitmap 的散列应该很快。否则,我只是添加了另一层计算。但是,到目前为止,我对这两个位图进行哈希处理的方法是将它们发送到字节数组中并获取它们的 MD5 校验和。像这样:

private Long getHashKey(Bitmap first, Bitmap second){

// TODO this IS costly, it render useless the cache optimization.
// also, it doesn't detect that comp(A,B) is the same as comp(B,A).
// much work to do here.

if(D) Profiling.start(TAG, "getHashKey");

ByteArrayOutputStream stream = new ByteArrayOutputStream();
first.compress(Bitmap.CompressFormat.JPEG, 100, stream);

byte[] firstArray = stream.toByteArray();
second.compress(Bitmap.CompressFormat.JPEG, 100, stream);

byte[] secondArray = stream.toByteArray();
byte[] bitmapBuffer = new byte[firstArray.length + secondArray.length];

System.arraycopy(firstArray, 0, bitmapBuffer, 0, firstArray.length);

System.arraycopy(secondArray, 0, bitmapBuffer,
firstArray.length, secondArray.length);

Adler32 md5Hash = new Adler32();
md5Hash.update(bitmapBuffer);
long hashKey = md5Hash.getValue();

if(D) Profiling.stop();

return hashKey;
}

但是,根据我所做的性能分析,此方法的运行时间约为 53 毫秒,这会导致 UI 中出现非常令人不快的延迟。在更详细的分析中,我发现大约 95% 的计算时间是在 compress 方法中完成的。但是,我还没有找到另一种方法来获取支持位图的字节。

05-26 17:56:13.220: D/Profiling(9458): Profile for ImageCompareActivity.getHashKey:
05-26 17:56:13.220: D/Profiling(9458): > Count : 1996 calls
05-26 17:56:13.220: D/Profiling(9458): > Total runtime : 105765140 us
05-26 17:56:13.220: D/Profiling(9458): > Avg runtime : 52988 us

我知道我对 Bitmap 进行哈希处理的方式非常粗暴。但我不太了解散列函数,以及我可以使用位图的哪些部分来唯一标识文件。我不想使用文件名或类似的东西,因为我想最终将这些位图发送到数据库中。

[更新 1]我不知道 Object.hashCode()。现在,我修改了这样的方法:

private Integer getHashKey(Bitmap first, Bitmap second){

if(D) Profiling.start(TAG, "getHashKey");

Integer hashKey = new Integer(
1013 * (first.hashCode()) ^ 1009 * (second.hashCode()) );

if(D) Profiling.stop();

return hashKey;
}

平均运行时间约为 18 us。

最佳答案

Here 是最近关于散列的问题。 Adler 可能是 JRE 内置的最快方法。您是否考虑过预先计算哈希并将其与图像一起存储或存储在数据库中?

关于java - 哈希位图的廉价/快速方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10767631/

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