Python 如何快速找到每对图像之间的欧氏距离
我有一个图像数据集,包含8000个RGB图像,大小为(256256)(Linnaeus 5数据集)。我想用欧几里德距离为每幅图像找到最近的图像。我不能在一个数组中保存所有的图像(因为它太大了,内存已经满了)。 所以我试着制作一个包含两列的数据框:image\u name和image\u label。每次我想找到两个图像之间的距离时,我都会得到它们的名称,将它们保存在一个变量中,然后计算距离。但这需要花费太多的时间(为每个图像找到最近的图像需要35秒,总共大约需要40小时)。 这是我的代码:Python 如何快速找到每对图像之间的欧氏距离,python,image,tensorflow,gpu,cpu,Python,Image,Tensorflow,Gpu,Cpu,我有一个图像数据集,包含8000个RGB图像,大小为(256256)(Linnaeus 5数据集)。我想用欧几里德距离为每幅图像找到最近的图像。我不能在一个数组中保存所有的图像(因为它太大了,内存已经满了)。 所以我试着制作一个包含两列的数据框:image\u name和image\u label。每次我想找到两个图像之间的距离时,我都会得到它们的名称,将它们保存在一个变量中,然后计算距离。但这需要花费太多的时间(为每个图像找到最近的图像需要35秒,总共大约需要40小时)。 这是我的代码: im
import pandas as pd
import os
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
import numpy as np
import tensorflow as tf
import time
def find_image_nearest_label(data_frame,path):
n = len(data_frame)
nearest_label = [-1 for i in range(n)]
for i in range(n):
start_time = time.time()
print("iteration number: " + str(i))
if nearest_label[i] == -1:
first_img = load_img(path + data_frame['image_name'][i])
first_img = img_to_array(first_img)/255
min_dist = float('inf')
nearest_img = -1
nearest_category = -1
for j in range(i+1,n):
second_img = load_img(path + data_frame['image_name'][j])
second_img = img_to_array(second_img)/255
# ss = time.time()
distance = np.sum((first_img-second_img)**2)
# ee = time.time()
# print(ee - ss)
if distance < min_dist:
min_dist = distance
nearest_category = data_frame['image_label'][j]
nearest_img = j
nearest_label[i] = nearest_category
nearest_label[j] = data_frame['image_label'][i]
end_time = time.time()
print("execution time: ", end_time - start_time)
return nearest_label
将熊猫作为pd导入
导入操作系统
从keras.preprocessing.image导入加载\u img
从keras.preprocessing.image导入img_到_数组
将numpy作为np导入
导入tensorflow作为tf
导入时间
def查找最近的图像标签(数据帧、路径):
n=len(数据帧)
最近的_标签=[-1表示范围(n)内的i]
对于范围(n)中的i:
开始时间=time.time()
打印(“迭代编号:+str(i))
如果最近的_标签[i]=-1:
第一个\u img=加载\u img(路径+数据帧['image\u name'][i])
first\u img=img\u到\u数组(first\u img)/255
最小距离=浮动('inf')
最近的_img=-1
最近的_类=-1
对于范围(i+1,n)内的j:
第二个\u img=加载\u img(路径+数据帧['image\u name'][j])
second\u img=img\u到\u数组(second\u img)/255
#ss=时间。时间()
距离=np.和((第一次\u img-第二次\u img)**2)
#ee=时间。时间()
#打印(ee-ss)
如果距离<最小距离:
最小距离=距离
最近的类别=数据帧['image\u label'][j]
最近的_img=j
最近的_标签[i]=最近的_类别
最近的_标签[j]=数据_帧['image_标签][i]
结束时间=time.time()
打印(“执行时间:”,结束时间-开始时间)
返回最近的标签
搜索之后,我想也许我应该使用GPU而不是CPU(实际上基于GPU的方法对我来说是新的)。所以我稍微修改了我的代码:
def find_image_nearest_label(data_frame,path):
n = len(data_frame)
nearest_label = [-1 for i in range(n)]
for i in range(n):
start_time = time.time()
print("iteration number: " + str(i))
if nearest_label[i] == -1:
first_img = load_img(path + data_frame['image_name'][i])
first_img = img_to_array(first_img)/255
first_img = tf.convert_to_tensor(first_img)
min_dist = float('inf')
nearest_img = -1
nearest_category = -1
for j in range(i+1,n):
second_img = load_img(path + data_frame['image_name'][j])
second_img = img_to_array(second_img)/255
second_img = tf.convert_to_tensor(second_img)
# ss = time.time()
with tf.device('/device:GPU:0'):
distance = tf.norm(tf.subtract(first_img, second_img))
# ee = time.time()
# print(ee - ss)
if distance < min_dist:
min_dist = distance
nearest_category = data_frame['image_label'][j]
nearest_img = j
nearest_label[i] = nearest_category
nearest_label[j] = data_frame['image_label'][i]
end_time = time.time()
print("execution time: ", end_time - start_time)
return nearest_label
def查找最近的图像标签(数据帧、路径):
n=len(数据帧)
最近的_标签=[-1表示范围(n)内的i]
对于范围(n)中的i:
开始时间=time.time()
打印(“迭代编号:+str(i))
如果最近的_标签[i]=-1:
第一个\u img=加载\u img(路径+数据帧['image\u name'][i])
first\u img=img\u到\u数组(first\u img)/255
first\u img=tf。将\u转换为\u张量(first\u img)
最小距离=浮动('inf')
最近的_img=-1
最近的_类=-1
对于范围(i+1,n)内的j:
第二个\u img=加载\u img(路径+数据帧['image\u name'][j])
second\u img=img\u到\u数组(second\u img)/255
第二个img=tf。将第二个img转换为张量(第二个img)
#ss=时间。时间()
使用tf.device('/device:GPU:0'):
距离=tf.范数(tf.减法(第一个img,第二个img))
#ee=时间。时间()
#打印(ee-ss)
如果距离<最小距离:
最小距离=距离
最近的类别=数据帧['image\u label'][j]
最近的_img=j
最近的_标签[i]=最近的_类别
最近的_标签[j]=数据_帧['image_标签][i]
结束时间=time.time()
打印(“执行时间:”,结束时间-开始时间)
返回最近的标签
它变得稍微快了一点(为一张图像找到最近的图像需要25秒,大约
总共30小时)。但这还是太慢了。有没有更好的方法(对于GPU或CPU)使其更快
更新:我只需使用一个图像列表,就可以加快更新速度(每张图像3秒,总共3小时)。实际上,它不会使RAM满,我可以将图像保存在数组列表中。我仍然感谢任何帮助或指导。多谢各位