利用 inceptionV3 特征简单实现以图搜图

从百度图片搜集一些素材:

分别有:喵x4,汪x4,猪x4,鸡x4

实验的目的

是希望通过输入一张图片,返回与其最相似的图片,达到以图搜图的效果。

在这里插入图片描述

代码

首先,导入必要的包

import os
import tarfile
import matplotlib.pyplot as plt
import numpy as np
import PIL
import tensorflow as tf
import tensorflow.contrib.slim as slim
import tensorflow.contrib.slim.nets as nets
from six.moves.urllib.request import urlretrieve
# 获取图片
images = []
img_dir = '\Download\img'
for idx, img_name in enumerate(os.listdir(img_dir)):
    img_path = os.path.join(img_dir,img_name)
    print('fetching pic:',img_path)
    img = PIL.Image.open(img_path)
    img = img.resize((299, 299))
    images.append(img)
NUM = len(images)

从网上下载别人训练好的模型,也可以手动下载解压到文件夹。

# 下载 inceptionV3 模型
data_dir = '.'
checkpoint_filename = os.path.join(data_dir, 'inception_v3.ckpt')
if not os.path.exists(checkpoint_filename):
    print('downloading inceptionV3 model...')
    inception_tarball, _ = urlretrieve(
        'http://download.tensorflow.org/models/inception_v3_2016_08_28.tar.gz')
    tarfile.open(inception_tarball, 'r:gz').extractall(data_dir)
# 计算流 (注意:299,299,3,1001是inceptionV3的标准参数
image = tf.Variable(tf.zeros((299, 299, 3)))
preprocessed = tf.multiply(tf.subtract(tf.expand_dims(image, 0), 0.5), 2.0)
arg_scope = nets.inception.inception_v3_arg_scope(weight_decay=0.0)
with slim.arg_scope(arg_scope):
    logits, end_points = nets.inception.inception_v3(
        preprocessed, 1001, is_training=False, reuse=False)
    # logits = logits[:, 1:]  # ignore background class
    # probs = tf.nn.softmax(logits)  # probabilities
#利用 saver 载入网络参数
restore_vars = [
    var for var in tf.global_variables() if var.name.startswith('InceptionV3/')
]
saver = tf.train.Saver(restore_vars)

在 session 中得到所有图片的 inception 特征

with tf.Session() as sess:
    saver.restore(sess, os.path.join(data_dir, 'inception_v3.ckpt')) #加载网络参数
    layer = 'PreLogits'
    features = []
    for img in images:
        img = np.asarray(img).astype(np.float32)/ 255.0
        feature_values = sess.run( end_points, feed_dict={image: img})
        feature = feature_values[layer].squeeze()
        features.append(feature)
    feature_vectors = np.stack(features)
# 计算欧氏距离
# 在这里不做归一化,因为归一化之后和余弦距离等价
distance_euclidean = np.sum(
    np.power(feature_vectors, 2), axis=1, keepdims=True) + np.sum(
        np.power(feature_vectors, 2), axis=1,
        keepdims=True).T - 2 * np.dot(feature_vectors, feature_vectors.T)
# 计算余弦距离
features_norm = feature_vectors / np.linalg.norm(
    feature_vectors, axis=1)[:, np.newaxis]
distance_cosin = np.dot(features_norm, features_norm.T)

到这里,所有图片之间的相似度就已经得到了。

接下来,我们从素材中挑4张图片来展示效果: 找出和输入图片最相似的前6张图片

test_images = [(i,img) for i, img in enumerate(images) if i%4==2]
TEST_NUM = len(test_images)
TOP_NUM = 6
# 测试欧式距离
plt.figure()
for i,(idx_img,plt_img) in enumerate(test_images):
    order_euclidean = np.argsort(distance_euclidean[idx_img])

    plt.subplot(TEST_NUM, TOP_NUM+1, i * (TOP_NUM+1) + 1)
    plt.axis('off')
    plt.title('input')
    plt.imshow(plt_img)

    for idx_sim, j in enumerate(order_euclidean):
        if idx_sim>=TOP_NUM:
            break
        similar_img = images[j]
        plt.subplot(TEST_NUM, TOP_NUM+1, i * (TOP_NUM+1) + idx_sim + 2)
        plt.axis('off')
        plt.title('{:.2}'.format(distance_euclidean[idx_img,j]))
        plt.imshow(similar_img)
# 测试余弦距离
plt.figure()
for i,(idx_img,plt_img) in enumerate(test_images):
    order_cosin = np.argsort(distance_cosin[idx_img])[::-1]

    plt.subplot(TEST_NUM, TOP_NUM+1, i * (TOP_NUM+1) + 1)
    plt.axis('off')
    plt.title('input')
    plt.imshow(plt_img)

    for idx_sim, j in enumerate(order_cosin):
        if idx_sim>=TOP_NUM:
            break
        similar_img = images[j]
        plt.subplot(TEST_NUM, TOP_NUM+1,i* (TOP_NUM+1) + idx_sim + 2)
        plt.title('input')
        plt.axis('off')
        plt.title('{:.2}'.format(distance_cosin[idx_img,j]))
        plt.imshow(similar_img)

结果

结果展示的第一列是输入的图片,显然和其最相似的是它自己,然后是同类

Fig.1 欧氏距离:
在这里插入图片描述
Fig.2 余弦距离:
在这里插入图片描述

### 回答1: Java实现以图搜图功能的实现主要依赖于图像处理和图像识别技术。 首先,需要使用Java的图像处理库,例如OpenCV或Java Advanced Imaging(JAI),来读取和处理图像。这些库提供了丰富的图像处理函数和算法,可以完成图像的预处理和特征提取等任务。 其次,需要使用机器学习或深度学习算法,来对图像进行特征提取和识别。可以使用Java的机器学习库,例如Weka或TensorFlow,来训练一个图像分类模型。该模型可以使用一组已知的图像样本进行训练,使其能够识别不同类型的图像。 在实际的搜索过程中,用户需要提供一个待搜索的图像。程序将使用同样的图像处理和特征提取算法,对待搜索的图像进行处理,并提取出与已知图像样本相似的特征。 最后,根据待搜索图像的特征与已知图像样本的相似度,可以通过计算两者之间的距离或相似性度量,来进行图像匹配和相似图像的搜索。模型会返回与待搜索图像最接近的已知图像样本,或者返回一组相似度较高的图像。 总结起来,Java实现以图搜图功能需要借助图像处理库和机器学习算法,对图像进行特征提取和识别。用户提供待搜索图像后,程序将对其进行处理,并通过比较特征相似度,来找到与之最接近或相似的图像。这样可以实现图像的搜索和相似图像的查找。 ### 回答2: Java实现以图搜图功能可以通过以下步骤: 1. 图片特征提取使用Java图像处理库,如OpenCV或Java Advanced Imaging(JAI),读取输入图像,并提取图像的关键特征,如颜色直方图、纹理特征或边缘特征等。这些特征可以通过计算图像的统计特性或使用深度学习算法进行提取。 2. 图像相似度计算:对于给定的检索图像,计算其与数据库中所有图像的相似度。可以使用Java的相似度计算库,如Apache Commons Math,来计算两个图像特征之间的距离或相似度。常用的相似度度量包括欧氏距离、曼哈顿距离或余弦相似度等。 3. 数据库管理:将图像和其对应的特征值存储在数据库中。可以使用Java的关系型数据库,如MySQL或PostgreSQL,以及相应的JDBC驱动程序进行数据库管理。数据库的设计可以根据实际需求选择合适的表结构,包括图像文件路径、图像特征值等字段。 4. 图像搜索功能:用户输入待搜索图像,并提供图像路径或上传图像文件。程序读取输入图像,并提取特征值。然后,程序计算输入图像与数据库中所有图像的相似度,找出相似度最高的图像。 5. 结果展示:将搜索结果展示给用户。可以使用Java图形化界面库,如JavaFX或Swing,创建一个用户友好的界面,显示搜索结果,并提供交互功能,如点击结果图像以显示详细信息、保存结果等。 总结起来,Java实现以图搜图功能主要涉及图像处理、特征提取相似度计算、数据库管理和图形化界面等方面。这需要使用Java的图像处理库和相关算法,以及数据库和图形化界面的相关技术,结合数据库设计和Java编程知识来实现
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值