![]() | 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 ![]() 小图很快的,不需要 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 ![]() 用深度学习模型提取 embedding ,用 milvus 计算相似度 |
14 NoOneNoBody 2023-03-31 16:46:45 +08:00 再补充一个经验,做图片比较,耗时最大是生成上述各种中间值,因为不仅计算,还有 IO 但如果已经有中间值,并发计算是很快的,如 imgHash ,千万对(就是两张)并发计算只是几分钟( i7 12700 16 并发) 另一个好处是“离线”,不需要挂载 refer 图片所在硬盘就能比较 这就是我把这些中间值入库的原因 |
![]() | 15 qiayue PRO 基于 #13 @faithid 的回答,我补充下,使用 OpenAI 的 https://github.com/openai/CLIP 为每一张图片计算向量,之后存储到文本文件里。 再写个程序,把所有图片的向量载入到内存中,循环计算任意一张图片的向量与其它图片的向量的距离,欧几里得距离( Euclidean distance )和余弦距离( cosine distance )都行,对于所得到的距离从小到大排序,就得到了每一张图片和其它所有图片的相似度。 你再取一个阈值,如距离小于多少,就算你定义的很像近图片。把所有小于这个阈值的图片放一起。 |
![]() | 16 LuffyWong 2023-03-31 17:34:27 +08:00 ![]() 如果相似度算法 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 每一张图都需要作为基准图与其他图进行对比,你说的这些情况理论上都要考虑。阈值的范围需要通过参数指定,并不是固定值。 |