我想知道如何在海量数据中查找图像(文件夹中有很多图像),并且我想查找 完全 的图像与输入图像相同(给出来自不在数据文件夹中的另一个文件夹的输入图像),并将输入图像与所有海量数据进行比较(如果找到了“完全相同”图像),则将其名称显示为output(文件夹中的图像相同,但未输入名称)(例如:dafs.jpg )
使用python
我正在考虑比较RGB像素的确切值,并从文件夹中的每个图像中减去输入图像的像素
但是我不知道如何在python中做到这一点
答案 0 :(得分:0)
您可以使用pillow模块来访问特定图像的像素数据。请记住,pillow
支持these image formats。
如果我们根据您的描述对两张图片相同的含义作一些假设,则两张图片必须:
然后如果我们使用pillow
模块获得2张图片
from PIL import Image
original = Image.open("input.jpg")
possible_duplicate = Image.open("output.jpg")
以下代码将能够比较两张图片,看它们是否相同
def compare_images(input_image, output_image):
# compare image dimensions (assumption 1)
if input_image.size != output_image.size:
return False
rows, cols = input_image.size
# compare image pixels (assumption 2 and 3)
for row in range(rows):
for col in range(cols):
input_pixel = input_image.getpixel((row, col))
output_pixel = output_image.getpixel((row, col))
if input_pixel != output_pixel:
return False
return True
通过致电
compare_images(original, possible_duplicate)
使用此功能,我们可以浏览一组图像
from PIL import Image
def find_duplicate_image(input_image, output_images):
# only open the input image once
input_image = Image.open(input_image)
for image in output_images:
if compare_images(input_image, Image.open(image)):
return image
将它们放在一起,我们可以简单地调用
original = "input.jpg"
possible_duplicates = ["output.jpg", "output2.jpg", ...]
duplicate = find_duplicate_image(original, possible_duplicates)
请注意,上述实现只会找到 first 重复项,然后将其返回。如果找不到重复项,将返回None
。
要记住的一件事是,像这样对每个像素执行比较可能会很昂贵。我使用this image并使用timeit模块将compare_images
用作输入和输出100次,并取了所有这些运行的平均值
num_trials = 100
trials = timeit.repeat(
repeat=num_trials,
number=1,
stmt="compare_images(Image.open('input.jpg'), Image.open('input.jpg'))",
setup="from __main__ import compare_images; from PIL import Image"
)
avg = sum(trials) / num_trials
print("Average time taken per comparison was:", avg, "seconds")
# Average time taken per comparison was 1.3337286046380177 seconds
请注意,这是在只有600 x 600像素的图像上完成的。如果您使用一组“大量”的可能重复图像进行此操作,而我将“大量”表示至少100万张类似尺寸的图像,则这可能需要约15天的时间(1,000,000 * 1.28s / 60秒/ 60分钟/ 24小时),将每个输出图像与输入图像进行比较,这并不理想。
还请记住,这些指标将根据您使用的计算机和操作系统而有所不同。我提供的数字仅供参考。
虽然我本人还没有完全研究过此实现,但是您可以尝试的一种方法是使用hash function预计算集合中每个图像的像素数据的哈希值。如果将它们存储在数据库中,并且每个散列都包含指向原始图像或图像名称的链接,那么您要做的就是使用相同的散列函数计算输入图像的散列,然后比较散列。这将花费大量的计算时间,并使算法效率更高。
This blog post描述了一种实现此目的的方法。
根据OP的要求,如果为您提供了可能的重复图像的目录,而不是明确的图像路径本身,则可以像这样使用os
和ntpath
模块< / p>
import ntpath
import os
def get_all_images(directory):
image_paths = []
for filename in os.listdir(directory):
# to be as careful as possible, you might check to make sure that
# the file is in fact an image, for instance using
# filename.endswith(".jpg") to check for .jpg files for instance
image_paths.append("{}/{}".format(directory, filename))
return image_paths
def get_filename(path):
return ntpath.basename(path)
使用这些功能,更新后的程序可能看起来像
possible_duplicates = get_all_images("/path/to/images")
duplicate_path = find_duplicate_image("/path/to/input.jpg", possible_duplicates)
if duplicate_path:
print(get_filename(duplicate_path))
以上仅在存在重复图像的情况下打印名称,否则将不打印任何内容。