JS实现图片相似度的判断

这篇文章发布于 2023年12月26日,星期二,00:04,归类于 JS实例。 阅读 13709 次, 今日 4 次 10 条评论

 

对比封面示意图

一、图片近似度对比

开门见山,不绕弯路。

用的是这个Github项目:https://github.com/obartra/ssim

之所以选这个,是我看这个项目提交次数比较多,文件版本也比较高。

选择的理由

案例先行

不管怎样,先看对比效果。

您可以狠狠地点击这里:JS实现图片对比差异参数demo

首先,选两个近似的图,例如选择我的CSS书籍的书封,点击对比,则会有下图所示的结果:

相似图片

相似度在0.51左右,这两个图结构类似,尺寸有些许差别,颜色也有些不同,文案也有所不同,50%左右的差异符合预期。

然后,选择两个长得完全大相径庭的图片,例如使用我的帅照 ?:

完全不同风格图片相似度

可以看到对比的结果接近于0,也就是差别巨大,完全没有可比性。

最后,演示页面还支持选择本地图片进行相似度对比,大家可以选择本地的图片素材,看看结果如何。

例如,我选择了如下图所示的两张图,得到了相似值挺高的对比结果:

相似度高示意

高达0.83,这是一个比较高的对比值了。

使用总结

根据我的使用感受,对比值小于0.4的,就可以认为有明显差异,数值越小,自然差异就越大了。

二、使用说明

官方示意的代码是npm包引入,如下:

npm install ssim.js
import ssim from "ssim.js";

const img1 = loadImage("./img1.jpg");
const img2 = loadImage("./img2.jpg");

const { mssim, performance } = ssim(img1, img2);

console.log(`SSIM: ${mssim} (${performance}ms)`);

而上面出现的loadImage方法,其实是不存在的,我搜索了ssim的JS源码,根本就没有loadImage这个关键字。

而这里的img1和img2并非图片元素,而是ImageData对象,可以通过canvas元素获取,context.getImageData()方法。

代码示意:

// 图片转imageData需要的canvas
// 为了节省开销,就在外面定义,只用这一个玩耍了
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d', { 
    willReadFrequently: true 
});
// image 转 imagedata的方法
const image2data = (img, flag) => {
    const { width, height } = canvas;
    ctx.clearRect(0, 0, width, height);
    ctx.drawImage(img, 0, 0, width, height);
    return ctx.getImageData(0, 0, width, height);
};

在使用image2data方法之前,需要先给canvas元素设置高宽属性。

如果是Web直连引用

直连引用的话,使用下面示意的代码:

<script src="./ssim.web.js"></script>
<script>
const { mssim, performance } = ssim.ssim(imgData1, imgData2);
console.log(`相似度: ${mssim} (${performance}ms)`);
</script>

前面提供的演示页面就是使用直连引用的方式实现的。

更具体的使用细节直接参阅demo演示页面的源码即可。

三、应用场景,结束语

图片相似度的应用通常都与图片序列相关。

例如,GIF动图需要进行压缩,则可以删除相似度极为类似的图片序列帧,只保留第一个,同时增加这一帧的延时时间。

目前的Web技术对此需求的实现已经非常成熟,尤其是有个WebCodecs API,可以轻松对GIF图片进行解码。

又例如对识别视频素材的转场画面等。

另外,素材的大小并不会影响识别的准确性,但是会影响识别的性能。

也就是1024*1024的图片对比结果,和128*128的图片对比结果相差不大,但是性能差异那就非常明显了。

所以,这里有个小tips,在获取图片数据的时候,记得绘制在合适大小的Canvas上,没有必要基于原图尺寸绘制,除非你这个相似度对比就是一锤子买卖,而不是批量化的操作。

OK,就说这么多吧,一个小小的技术积累,说不定什么时候就会用到呢。

感谢阅读,欢迎,以及圣诞节快乐!

☃️⛄️??❤️

(本篇完)

分享到:


发表评论(目前10 条评论)

  1. sakura说道:

    感谢,将图片尺寸缩小10倍执行只有30ms。
    您的回复按钮我这边点击会报403~

  2. sakura说道:

    如果能有您这个demo的git仓库就好了,我使用vue electron执行速度是2200ms,太难了,我只能将您的代码复制过去移植成vue的试试

  3. 某某某说道:

    但是,更多的时候是在比较图片压缩算法的时候使用这个算法(

  4. sa说道:

    试着把CSS世界截图截取一部分和原图进行识别 相似只有0.25了 看来图片尺寸影响不小 现实中的以图搜图好多都是部分图片

  5. 崮生说道:

    ?

  6. 迷弟说道:

    请问能介绍下这个的实现原理么,某宝某东等购物网站上以图找图功能是不是也是类似的意思?

  7. Visitor说道:

    你好,我发现你的博客现在运行的wordpress版本是4年多前发布的,存在诸多安全问题,建议升级一下。