Проверьте, есть ли точно такое же изображение, как входное изображение
Я хочу знать, как я могу найти изображение в массиве данных (в папке много изображений), и я хочу найти изображение, которое точно совпадает с входным изображением (учитывая входное изображение из другой папки, отсутствующей в данных папку) и сравните входное изображение со всеми массивными данными, если оно обнаружило точно такое же изображение, а затем отобразите его имя в качестве выходного (имя того же изображения в папке, а не входное имя) (например, dafs.jpg)
используя питон
Я думаю о сравнении точного значения пикселей RGB и вычитания пикселя входного изображения из каждого изображения в папке
но я не знаю, как это сделать в Python
1 ответ
Сравнение значений пикселей RGB
Вы можете использовать модуль подушки, чтобы получить доступ к данным пикселей определенного изображения. Имейте в виду, что pillow
поддерживает эти форматы изображений.
Если мы сделаем несколько предположений о том, что значит идентифицировать 2 изображения, основываясь на вашем описании, оба изображения должны:
- Имеют одинаковые размеры (высота и ширина)
- Иметь одинаковые значения пикселей RGB (значения пикселей RGB [x, y] во входном изображении должны совпадать со значениями пикселей RGB [x, y] в выходном изображении)
- Быть одинаковой ориентации (в связи с предыдущим предположением изображение считается не идентичным по сравнению с тем же изображением, повернутым на 90 градусов)
тогда, если у нас есть 2 изображения, используя pillow
модуль
from PIL import Image
original = Image.open("input.jpg")
possible_duplicate = Image.open("output.jpg")
следующий код сможет сравнить 2 изображения, чтобы увидеть, были ли они идентичны
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)
Обратите внимание, что приведенная выше реализация найдет только первый дубликат и вернет его. Если дубликат не найден, None
будет возвращен.
Нужно иметь в виду, что сравнение каждого пикселя может оказаться дорогостоящим. Я использовал это изображение и побежал compare_images
используя это как вход и выход 100 раз, используя модуль timeit, и взял среднее значение всех этих запусков
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 на 600 пикселей. Если вы сделали это с "массивным" набором возможных дубликатов изображений, где я буду принимать "массивный", чтобы обозначить как минимум 1M изображений одинакового размера, это может занять ~15 дней (1 000 000 * 1,28 с / 60 секунд / 60 минут / 24 часа), чтобы пройти и сравнить каждое выходное изображение с входным, что не является идеальным.
Также имейте в виду, что эти показатели будут различаться в зависимости от машины и используемой операционной системы. Числа, которые я предоставил, являются скорее для иллюстративных целей.
Альтернативная реализация
Хотя я не полностью исследовал эту реализацию сам, одним из способов, который вы могли бы попробовать, было бы предварительное вычисление хеш-значения данных пикселей каждого из ваших изображений в вашей коллекции с использованием хеш-функции. Если вы сохранили их в базе данных, где каждый хеш содержит ссылку на исходное изображение или имя изображения, то все, что вам нужно будет сделать, - это вычислить хеш входного изображения, используя ту же функцию хеширования, и сравнить хэши. Это потребовало бы много времени вычислений и сделало бы гораздо более эффективный алгоритм.
Этот блог описывает одну реализацию для этого.
Обновление - 2018-08-06
Согласно запросу OP, если вам дали каталог возможных дублированных изображений, а не самих явных путей к изображениям, то вы могли бы использовать os
а также ntpath
модули вроде так
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))
Выше будет напечатано имя дублированного изображения только в том случае, если дубликат был, иначе ничего не будет напечатано.