首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >基于Java深度学习库Deep Java Library 的图片相似度计算

基于Java深度学习库Deep Java Library 的图片相似度计算

作者头像
九转成圣
发布2024-11-21 13:48:53
发布2024-11-21 13:48:53
4160
举报
文章被收录于专栏:csdncsdn

基于Java深度学习库Deep Java Library的图片相似度计算

完整代码见

在本文中,我们将使用DJL中的预训练模型ResNet50来提取图片的特征向量,并计算图片之间的相似度。我们主要关注使用余弦相似度、欧氏距离和内积三种方法对图片特征向量进行1:1比对,以评估图片的相似性,进一步实现图片分类。

1. 基本流程:加载模型和提取特征

我们选用ResNet50模型,该模型在ImageNet数据集上进行了预训练,能够提取512维的特征向量来表征图片的内容。我们将用这些特征向量来计算两张图片之间的相似度。

以下是提取图片特征向量的基本代码:

代码语言:javascript
复制
@SneakyThrows
@Test
public void test1() {
    // 初始化图片编码模型
    ImageEncoderModel imageEncoderModel = new ImageEncoderModel();
    imageEncoderModel.init("models/CLIP-ViT-B-32-IMAGE.pt", 4);
    
    // 加载图片并转换成特征向量
    Path imageFile1 = Paths.get("models/3_3.jpg");
    Image img1 = OpenCVImageFactory.getInstance().fromFile(imageFile1);
    Path imageFile2 = Paths.get("models/3_5.jpg");
    Image img2 = OpenCVImageFactory.getInstance().fromFile(imageFile2);

    float[] feature1 = imageEncoderModel.predict(img1);
    float[] feature2 = imageEncoderModel.predict(img2);

    // 计算相似度
    float dis = FeatureComparison.dis(feature1, feature2);
    logger.info("欧氏距离: " + dis);
    float cos = FeatureComparison.cosineSim(feature1, feature2);
    logger.info("余弦相似度: " + cos);
    float dot = FeatureComparison.dot(feature1, feature2);
    logger.info("内积: " + dot);
}
1.1 运行结果示例
代码语言:javascript
复制
[INFO ] - 欧氏距离: 3.9849436
[INFO ] - 余弦相似度: 0.918966
[INFO ] - 内积: 89.196815

2. 相似度解释

余弦相似度

余弦相似度是通过计算两个向量夹角的余弦值来度量相似度。值越接近1,说明两个向量越相似,代表图片内容越接近:

  • 接近1(如0.9及以上):图片内容非常相似。
  • 0.7到0.9之间:图片内容有一定相似性,但可能存在细微差异。
  • 0.5到0.7之间:图片相似度较低,内容有明显差异。
  • 低于0.5:一般认为图片相似度较低,内容差异较大。
欧式距离

欧式距离用于测量两个特征向量之间的距离。距离越接近0,表示图片内容越相似:

  • 接近0:图片内容几乎完全相同。
  • 小于10:通常认为图片相似。
  • 10到30之间:相似度下降,存在较大差异。
  • 大于30:一般认为图片差异较大。
内积(或点积)

内积主要用于计算向量相似性,尤其在特征向量方向接近时,内积值会增大。数值越高表示图片越相似。

3. 图片分类在消消乐游戏中的应用

在一些游戏场景中,例如消消乐,能够自动识别相似图片对于提高游戏体验非常有帮助。以下示例展示了如何在游戏截图中找到与特定目标图像最相似的图片。

3.1 查找与2_4图片相似的图片
代码语言:javascript
复制
@SneakyThrows
@Test
public void test2_4() {
    ImageEncoderModel imageEncoderModel = new ImageEncoderModel();
    imageEncoderModel.init("models/CLIP-ViT-B-32-IMAGE.pt", 4);
    
    // 加载目标图片特征向量
    Path imageFile1 = Paths.get("models/xxl/2_4.jpg");
    Image img1 = OpenCVImageFactory.getInstance().fromFile(imageFile1);
    float[] feature1 = imageEncoderModel.predict(img1);

    // 遍历目录下的所有图片,找到相似度大于0.9的图片
    for (File file : new File("models/xxl/").listFiles()) {
        Image img2 = OpenCVImageFactory.getInstance().fromFile(Paths.get(file.getAbsolutePath()));
        float[] feature2 = imageEncoderModel.predict(img2);
        float cos = FeatureComparison.cosineSim(feature1, feature2);
        if (cos > 0.9f) {
            logger.info("与" + file.getName() + "的余弦相似度: " + cos);
        }
    }
}
运行结果示例
代码语言:javascript
复制
[INFO ] - 与2_4.jpg的余弦相似度: 1.0
[INFO ] - 与3_1.jpg的余弦相似度: 0.9555674
[INFO ] - 与3_3.jpg的余弦相似度: 0.95913744
[INFO ] - 与4_1.jpg的余弦相似度: 0.95366186
[INFO ] - 与5_5.jpg的余弦相似度: 0.95639783

可以看出,与2_4图片的余弦相似度较高的图片是3_1、3_3、4_1和5_5,符合预期。

3.2 查找与0_0图片相似的图片并提高阈值

在某些情况下,为避免误判,我们可以通过设定更高的余弦相似度阈值来减少相似度较低的匹配结果。

代码语言:javascript
复制
@SneakyThrows
@Test
public void test0_0() {
    ImageEncoderModel imageEncoderModel = new ImageEncoderModel();
    imageEncoderModel.init("models/CLIP-ViT-B-32-IMAGE.pt", 4);
    
    // 加载目标图片特征向量
    Path imageFile1 = Paths.get("models/xxl/0_0.jpg");
    Image img1 = OpenCVImageFactory.getInstance().fromFile(imageFile1);
    float[] feature1 = imageEncoderModel.predict(img1);

    // 增加阈值限制,找到相似度高于0.95的图片
    for (File file : new File("models/xxl/").listFiles()) {
        Image img2 = OpenCVImageFactory.getInstance().fromFile(Paths.get(file.getAbsolutePath()));
        float[] feature2 = imageEncoderModel.predict(img2);
        float cos = FeatureComparison.cosineSim(feature1, feature2);
        if (cos > 0.95f) {
            logger.info("与" + file.getName() + "的余弦相似度: " + cos);
        }
    }
}
运行结果示例
代码语言:javascript
复制
[INFO ] - 与0_0.jpg的余弦相似度: 1.0
[INFO ] - 与0_5.jpg的余弦相似度: 0.9142534
[INFO ] - 与2_0.jpg的余弦相似度: 0.9079724

通过调整阈值,可以更严格地控制相似匹配的结果,减少误差。

结论

本文通过使用DJL和ResNet50模型对图片特征进行提取和对比,演示了如何实现图片相似度计算和分类的基本流程。余弦相似度、欧氏距离和内积在不同场景下能有效地评估图片之间的相似性,并能够根据不同阈值来提高匹配的准确性。

完整代码见

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-11-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基于Java深度学习库Deep Java Library的图片相似度计算
    • 1. 基本流程:加载模型和提取特征
      • 1.1 运行结果示例
    • 2. 相似度解释
      • 余弦相似度
      • 欧式距离
      • 内积(或点积)
    • 3. 图片分类在消消乐游戏中的应用
      • 3.1 查找与2_4图片相似的图片
      • 3.2 查找与0_0图片相似的图片并提高阈值
      • 结论
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档