1
kop1989smurf 2023-03-31 11:57:55 +08:00
一万张图的总大小是多大?
|
2
laoooo OP @kop1989smurf 40MB 左右,都是小图,分辨率在 128*128 的样子
|
3
frankmdong 2023-03-31 12:56:58 +08:00
首先要定义相似度具体是怎么计算,如果是单纯的比较相同位置的像素颜色是否相同,那可以多线程跑 compute shader ,在 gpu 对比两张图片对应的像素是否相同。可以参考 https://zhuanlan.zhihu.com/p/392448858 这篇文章中提到的资源优化工具,但是一分钟内几乎不可能跑完一万张图。
|
4
oylinv 2023-03-31 13:19:39 +08:00 via Android
|
5
qq565425677 2023-03-31 13:39:44 +08:00
我提供一个思路,不过具体我也不是太清楚
有没有可能计算图片的奇异值分解,128*128 应该很快,然后基于奇异值定义距离来判断 |
6
kzzhr 2023-03-31 13:44:50 +08:00
我把这个问题丢给了 GPT ,以下是他的回答(还给了个代码,太长了不贴了。。。)
要实现一个高性能的图片相似度计算方案,可以使用以下方法: 1. 使用深度学习模型:使用预训练的深度学习模型,如 VGG, ResNet 等,可以更高效地提取图像特征。这些特征可以用于计算相似度。 2. 特征向量降维:使用 PCA 或 t-SNE 等方法对特征向量进行降维,这样可以减少计算量,提高相似度计算速度。 3. 近似最近邻搜索:对于相似度计算,可以使用近似最近邻搜索( Approximate Nearest Neighbors ,ANN )算法,如 Annoy 、Faiss 等库。它们可以在保持搜索质量的同时大大提高搜索速度。 4. 多线程 /多进程:使用 Python 的 multiprocessing 或 concurrent.futures 模块来实现多线程 /多进程并行计算。 |
7
kop1989smurf 2023-03-31 13:50:45 +08:00
|
8
horizon 2023-03-31 13:56:44 +08:00
准备开始学深度学习了。。
|
9
Donahue 2023-03-31 14:19:45 +08:00
可以问问 chatGPT
|
10
NoOneNoBody 2023-03-31 15:51:13 +08:00 2
小图很快的,不需要 3000s ,但 1m 又基本不行
不知道你的参照有多少,我 1000 vs 1000 ,5~10MB/pic ,也就 30 分钟内 如果参照已经缓存了计算值,时间减半,小图(<1MB/pic),时间减 2/3 方案 1. pyvips def viMse(vim, refvim)->float: '''计算 MSE 差异值,vim/refvim 都是 pyvips.Image 类型''' return ((vim - refvim) ** 2).avg() 然后你按 mse 比较,网上有 opencv 也有 mse 计算,但比 pyvips 慢 方案 2 pyvips|opencv 有些图片字节数相同或极度接近,但 md5/crc32 不同,它们可能只是 exif 或者文件头不同,图片内容是完全相同的 可以用 np.isclose((vim1-vim2).max(), 0, rtol=1e-9) 或 cvim1.shape==cvim2.shape and not (numpy.bitwise_xor(cvim1, cvim2).any()) vim 为 pyvips.Image 格式,cvim 为 opencv/numpy 格式,vips 较快且耗内存小,但大图有可能有未知错误,全自动的话 opencv 在保证内存足够的情况下比较保险 方案 3 opencv.imgHash target 和 refer 分别计算 imgHash ,opencv 的 imgHash 有七八种,阙值是自定的,但网上有参考,自己选择 无论哪种方案,应该做预匹配,不然就是 10000 * 10000 ,计算量大 预匹配就是从字节、文件名相似、exif 日期时间一致,长宽比……这些很少计算能快速排除“完全不可能相似” 如果很难做预匹配,例如上述参数都没有规律,那就只能硬着头皮按组合双循环计算了 还有其他方案,但此题好像不适用,我主要目标是找有没有裁切水印把图变小了,和你需求略有不同 PS: 如果 refer 经常使用的话,建议把上述计算的中间值保存,以后使用跳过计算,省时间,我是入库的 |
11
NoOneNoBody 2023-03-31 15:57:31 +08:00
PS: 上述时间是 intel 12700 使用 16 个并发(因为我要留 CPU 做其他事情,用尽的话其他 app 会没响应,无奈)
|
12
orangie 2023-03-31 16:31:39 +08:00
插一句,python 的多线程还是单核性能,不能用来并行、提高计算速度,只能用来做异步、并发。
|
13
faithid 2023-03-31 16:33:16 +08:00 1
用深度学习模型提取 embedding ,用 milvus 计算相似度
|
14
NoOneNoBody 2023-03-31 16:46:45 +08:00
再补充一个经验,做图片比较,耗时最大是生成上述各种中间值,因为不仅计算,还有 IO
但如果已经有中间值,并发计算是很快的,如 imgHash ,千万对(就是两张)并发计算只是几分钟( i7 12700 16 并发) 另一个好处是“离线”,不需要挂载 refer 图片所在硬盘就能比较 这就是我把这些中间值入库的原因 |
15
qiayue 2023-03-31 16:53:00 +08:00
基于 #13 @faithid 的回答,我补充下,使用 OpenAI 的 https://github.com/openai/CLIP 为每一张图片计算向量,之后存储到文本文件里。
再写个程序,把所有图片的向量载入到内存中,循环计算任意一张图片的向量与其它图片的向量的距离,欧几里得距离( Euclidean distance )和余弦距离( cosine distance )都行,对于所得到的距离从小到大排序,就得到了每一张图片和其它所有图片的相似度。 你再取一个阈值,如距离小于多少,就算你定义的很像近图片。把所有小于这个阈值的图片放一起。 |
16
LuffyWong 2023-03-31 17:34:27 +08:00 1
如果相似度算法 ok 了的话, python 调用 pytorch 实现直接 cuda 跑更快
|
17
yousabuk 2023-03-31 18:41:17 +08:00 via iPhone
帖子内容和格式像极了甲方对楼主提的需求
|
18
laoooo OP @NoOneNoBody 谢谢,我之前问过 GPT ,尝试过第三种方案,和你说的一样,这些小图片没法做预匹配,现在就是卡在了计算量上。第二种方案有所启发,非常感谢。
|
19
laoooo OP @kop1989smurf 每一张图都需要作为基准图与其他图进行对比,你说的这些情况理论上都要考虑。阈值的范围需要通过参数指定,并不是固定值。
|