NSDT工具推荐Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 - AI模型在线查看 - Three.js虚拟轴心开发包 - 3D模型在线减面 - STL模型在线切割 - 3D道路快速建模

VGG16 是一个强大的预训练模型,可用于识别图像之间的相似性。 通过使用该模型,我们可以从不同图像中提取高级特征并进行比较以识别相似性。 该技术具有广泛的应用,从图像搜索和推荐系统到安全和监控。

在本文中,我将利用该模型来查找两个图像之间的相似性。

1、开发环境搭建

对于这个项目,我们将利用流行的机器学习库(例如 keras 和 scikit-learn)来构建和训练我们的图像相似度模型。

除了提到的库之外,我们还将使用 numpy 和 matplotlib 库分别进行数据操作和可视化。 这些库对于准备图像数据和可视化图像相似性模型的结果非常有用。

import numpy as np 
from PIL import Image
from tensorflow.keras.preprocessing import image

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

from keras.applications.vgg16 import VGG16
from sklearn.metrics.pairwise import cosine_similarity

2、初始化VGG16模型

配置 VGG16 模型进行图像嵌入提取并了解其参数:

vgg16 = VGG16(weights='imagenet', include_top=False, 
              pooling='max', input_shape=(224, 224, 3))

# print the summary of the model's architecture.
vgg16.summary()

weights='imagenet' 参数指定应该使用 ImageNet 数据集(用于训练计算机视觉模型的标记图像的大型数据集)中的预训练权重来初始化模型。

include_top=False 参数表示不应包含模型中负责分类的顶部密集层。 当我们想要使用预先训练的模型作为特征提取器,然后在其上添加我们自己的自定义分类层时,就会完成此操作。

pooling='max' 参数操作对于减小特征图的大小同时保留最重要的信息非常有用。

input_shape=(224, 224, 3) 参数指定输入图像的预期形状,在本例中为 224x224 彩色图像。

3、迁移学习

冻结 VGG16 模型层以进行迁移学习:

for model_layer in vgg16.layers:
  model_layer.trainable = False

对于模型中的每一层,我们需要指定不需要额外的训练。 我们将使用 VGG16 模型的预设参数,该模型默认使用 ImageNet 数据集进行训练。

4、输入图像预处理

定义模型输入图像数据预处理的函数:

def load_image(image_path):
    """
        -----------------------------------------------------
        Process the image provided. 
        - Resize the image 
        -----------------------------------------------------
        return resized image
    """

    input_image = Image.open(image_path)
    resized_image = input_image.resize((224, 224))

    return resized_image

该函数将图像文件路径作为输入,由 image_path 参数表示,并使用 PIL(Python 图像库)模块中的 Image.open() 方法从磁盘加载图像。

然后,该函数使用 resize() 方法将图像大小调整为 (224, 224) 像素的固定大小。 这是深度学习图像模型中常用的预处理步骤,其中图像通常在输入模型之前调整为固定的输入大小。

最后,该函数将调整大小的图像作为 PIL 图像对象返回,该对象可以进一步处理或用作机器学习模型的输入。

5、输入图像嵌入向量计算

def get_image_embeddings(object_image : image):
    
    """
      -----------------------------------------------------
      convert image into 3d array and add additional dimension for model input
      -----------------------------------------------------
      return embeddings of the given image
    """

    image_array = np.expand_dims(image.img_to_array(object_image), axis = 0)
    image_embedding = vgg16.predict(image_array)

    return image_embedding

该函数将图像对象作为输入,并使用 Keras 图像模块中的 img_to_array 方法将图像转换为 3D 数组。

然后使用 np.expand_dims() 方法将生成的数组扩展为具有附加维度,这是 VGG16 深度学习模型输入所需的。 扩展后的数组表示形状为(1、高度、宽度、通道)的单个图像,其中高度、宽度和通道对应于图像的尺寸。

然后该函数调用 VGG16 模型上的 Predict() 方法,该方法之前已在代码中定义。 该方法将扩展的 numpyarray 作为输入,并使用 VGG16 模型的预训练权重生成图像的嵌入。

最后,该函数将图像嵌入作为 numpyarray 返回。 这种嵌入可以用作输入图像的特征表示,可用于图像检索、相似性搜索或分类等任务。

6、余弦相似度计算

def get_similarity_score(first_image : str, second_image : str):
    """
        -----------------------------------------------------
        Takes image array and computes its embedding using VGG16 model.
        -----------------------------------------------------
        return embedding of the image
        
    """

    first_image = load_image(first_image)
    second_image = load_image(second_image)

    first_image_vector = get_image_embeddings(first_image)
    second_image_vector = get_image_embeddings(second_image)
    
    similarity_score = cosine_similarity(first_image_vector, second_image_vector).reshape(1,)

    return similarity_score

该函数将两个图像的文件路径作为输入,由 first_imagesecond_image参数表示。 该函数首先调用 load_image() 函数从磁盘加载图像。

然后,该函数在每个图像上调用 get_image_embeddings() 函数,该函数使用 VGG16 模型为每个图像生成特征嵌入。 这些嵌入表示为 numpy 数组。

最后,该函数使用 sklearn.metrics.pairwise 模块中的 cosine_similarity() 函数计算两个嵌入之间的余弦相似度得分。 生成的相似度分数是 -1 到 1 之间的单个值,用于衡量两个图像之间的相似程度,分数为 1 表示完全相似。

7、图像显示

def show_image(image_path):
  image = mpimg.imread(image_path)
  imgplot = plt.imshow(image)
  plt.show()

该函数接受图像路径作为输入,并使用 matplotmodule 中的 plt.imshow() 方法将图像数组显示为 2D 绘图。

8、两个图像的比较

最后,我们将使用上面定义的函数以及初始化的 VGG16 模型来查找图像之间的相似性。

# define the path of the images
sunflower = '/content/sunflower.jpeg'
helianthus = '/content/helianthus.jpeg'

tulip = '/content/Tulip.jpeg'

# use the show_image function to plot the images
show_image(sunflower), show_image(helianthus)
similarity_score = get_similarity_score(sunflower, helianthus)
similarity_score

输出结果:

9、结束语

在这个项目中,我们探索了使用 VGG16 模型从图像中提取特征并计算它们之间的相似度分数。 我们首先导入必要的库,初始化 VGG16 模型,并定义用于加载和处理图像、计算其嵌入以及计算相似性分数的函数。

然后,我们将这些函数应用于一组图像,并使用各种技术将结果可视化。 总体而言,该项目展示了如何利用 VGG16 等深度学习模型来执行复杂的图像分析任务并从视觉数据中生成见解。


原文链接:Image Similarity Comparison using VGG16 Deep Learning Model

BimAnt翻译整理,转载请标明出处