Нахождение идентичных изображений в Python

feniks

Новичок
Пользователь
Апр 6, 2020
8
1
3
Всем привет. Подскажите, пожалуйста, как мне написать такую задачу.

Питон прога делает скрины каждые 5 секунд и сохраняет их в папке. Каждый скрин должен искать такой же (т.е. должны быть одинаковы изображения) скрин в другой папке (там заранее скрины заготовлены). И писать print("True"), если они одинаковы или print("False"), если они разные. Уже долго ломаю голову как это осуществить. Может кто подсказать?

Фрагмент кода:
Python:
def uslovie():

# Скрин экрана, сохраняемый в первую папку
    i = 1
    while True:
        time.sleep(1)
        box = (x_pad+1, y_pad+1,x_pad+321,y_pad+589)
        im = ImageGrab.grab(box)
        im.save('D:\Мася\ImageBot\-vse\-№__' + str(int(time.time())) + '.png', 'PNG')
        i += 1
        
    # Открытие папки с изображениями   
    scrin = glob.glob("D:\Мася\ImageBot\-vse\*.png")  # первая папка
    file = glob.glob("D:\Мася\ImageBot\-B\*.png")   # вторая папка, в которой ищем похожее изображение

# Здесь должна быть функция поиска идентичного скрина (только какая????)
    if:
           print("True")
    else:
           print("False")
 
Последнее редактирование модератором:
  • Мне нравится
Реакции: Student

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Вот пример:
Python:
from PIL import Image, ImageGrab
import os
import time


# сравнение скринов
def compare_img(img1, img2):
    with Image.open(img1) as im1, Image.open(img2) as im2:
        return im1 == im2


# поиск совпадений
def find_image(path1, path2, image_list, img):
    # поиск в цикле нужного скрина
    for image in image_list:
        if compare_img(path1 + img, path2 + image):
            print('Совпадающий скрин: ', image)
            break
    else:
        print('Совпадений не найдено')


path1 = 'D://Мася/ImageBot/-vse/'
path2 = 'D:/Мася/ImageBot/-B/'

# список файлов в папке со скринами
image_list = os.listdir(path2)

filename = None
while True:
    time.sleep(5)
    # тут нужно установить правильные координаты
    box = (1, 1, 321, 589)
    im = ImageGrab.grab(box)
    filename = str(int(time.time())) + '.png'
    im.save(filename, 'PNG')
    find_image(path1, path2, image_list, filename)
 
  • Мне нравится
Реакции: Student и feniks

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Забыл путь исправить:
Python:
im.save(filename, 'PNG')
нужно заменить на
Python:
im.save(path1 + filename, 'PNG')
чтобы сохраняло скрин в нужную папку
 
  • Мне нравится
Реакции: Student

Student

throw exception
Команда форума
Администратор
Апр 2, 2020
195
103
43
Москва
Используй библиотеку Pillow.
Python:
import Image
import ImageChops

im1 = Image.open("screen-1.png")
im2 = Image.open("screen-2.png")

# Здесь должна быть функция поиска идентичного скрина (только какая????)
if ImageChops.difference(im2, im1):
    print("True")
else:
    print("False")

Не используй название file для переменных т.к. это зарезервированное ключевое слово из Python.
 
  • Мне нравится
Реакции: feniks

feniks

Новичок
Пользователь
Апр 6, 2020
8
1
3
Используй библиотеку Pillow.
Python:
import Image
import ImageChops

im1 = Image.open("screen-1.png")
im2 = Image.open("screen-2.png")

# Здесь должна быть функция поиска идентичного скрина (только какая????)
if ImageChops.difference(im2, im1):
    print("True")
else:
    print("False")

Не используй название file для переменных т.к. это зарезервированное ключевое слово из Python.

Спасибо за подсказку. Но это пример для двух файлов. А мне нужно, чтобы текущее полученное изображение, находящееся в первой папке, находило идентичное в другой папке, в которой много скринов. Т.е. ссылка не на определенное изображение, а в папку сними и там находило похожее. Можно это реализовать и если да, то как?
 

Student

throw exception
Команда форума
Администратор
Апр 2, 2020
195
103
43
Москва
Спасибо за подсказку. Но это пример для двух файлов. А мне нужно, чтобы текущее полученное изображение, находящееся в первой папке, находило идентичное в другой папке, в которой много скринов. Т.е. ссылка не на определенное изображение, а в папку сними и там находило похожее. Можно это реализовать и если да, то как?

Берешь основной скрин, открываешь его через Image.open() потом получаешь весь список названий файлов скринов через glob из твоей папки. Так-же открываешь каждый скрин через Image.open() и проверяешь если он идентичен с твоим основным через метод ImageChops.difference(im2, im1).

Не забудь выполнить .close() для каждого скрина в цикле, чтобы не израсходовать память.
 

feniks

Новичок
Пользователь
Апр 6, 2020
8
1
3
Берешь основной скрин, открываешь его через Image.open() потом получаешь весь список названий файлов скринов через glob из твоей папки. Так-же открываешь каждый скрин через Image.open() и проверяешь если он идентичен с твоим основным через метод ImageChops.difference(im2, im1).

Не забудь выполнить .close() для каждого скрина в цикле, чтобы не израсходовать память.

Хорошо. А если у меня через каждые 5 секунд идут скрины и кидаются в папку. Можно автоматизировать проверку текущего скрина, который получается через каждые 5 секунд и постоянно разный, с проверкой в другой папке? Т.е. в ручную не достовать название скрина, а чтоб был какой-то цикл получения скрина и тут же нахождение такого же в другой папке?
 

Student

throw exception
Команда форума
Администратор
Апр 2, 2020
195
103
43
Москва
Хорошо. А если у меня через каждые 5 секунд идут скрины и кидаются в папку. Можно автоматизировать проверку текущего скрина, который получается через каждые 5 секунд и постоянно разный, с проверкой в другой папке? Т.е. в ручную не достовать название скрина, а чтоб был какой-то цикл получения скрина и тут же нахождение такого же в другой папке?

Вставь данную логику в вечный цикл каждый раз прогоняя каждый новый скрин через папку со старыми скринами. Я бы поставил проверку в момент сохранения файла, если конечно ты контролируешь данный процесс. Чтобы файл сперва проверял если есть уже такой скриншот и уже потом сохранил себя.

Еще как вариант ты можешь называть файлы скрина используя md5 хеш содержимого файла.

Python:
from PIL import Image
import hashlib

screen = Image.open('temp-screen.png')
md5hash = hashlib.md5(screen.tobytes())
filename = "%s.png" % md5hash.hexdigest() # Будет что-то вроде 0a4d55a8d778e5022fab7.png

open(filename, 'wb').write(screen.tobytes())

И так у тебя даже если и будут дубли, то они будут сами себя перезаписывать.
 
  • Мне нравится
Реакции: Rud356 и feniks

feniks

Новичок
Пользователь
Апр 6, 2020
8
1
3
Вставь данную логику в вечный цикл каждый раз прогоняя каждый новый скрин через папку со старыми скринами. Я бы поставил проверку в момент сохранения файла, если конечно ты контролируешь данный процесс. Чтобы файл сперва проверял если есть уже такой скриншот и уже потом сохранил себя.

Еще как вариант ты можешь называть файлы скрина используя md5 хеш содержимого файла.

Python:
from PIL import Image
import hashlib

screen = Image.open('temp-screen.png')
md5hash = hashlib.md5(screen.tobytes())
filename = "%s.png" % md5hash.hexdigest() # Будет что-то вроде 0a4d55a8d778e5022fab7.png

open(filename, 'wb').write(screen.tobytes())

И так у тебя даже если и будут дубли, то они будут сами себя перезаписывать.

Можете еще примером подсказать, как прогнать новый скрин через папку со старыми скринами? А то у меня получается папка с папкой сравнивается и все время True выбивает. Хотя есть скрины и не похожие.
Python:
def finder():
    i = 1
    while True:
        time.sleep(5)
        box = (x_pad+1, y_pad+1,x_pad+321,y_pad+589)
        im = ImageGrab.grab(box)
        im.save('D:\Мася\ImageBot\-vse\-№__' + str(int(time.time())) + '.png', 'PNG')
        i += 1
##        break  

##def proverkaB():
    # Открытие папки с изображениями
        dir_name1 = "D:\Мася\ImageBot\-vse\*.png"
        names1 = glob.glob(dir_name1)
        for name1 in names1:
            fullname1 = os.path.join(os.getcwd(), name1)
            if os.path.isfile(fullname1):
##          print(fullname1)
                im1 = Image.open(fullname1)
##          print(im1)
                       
        dir_name2 = "D:\Мася\ImageBot\-B\*.png"
        names2 = glob.glob(dir_name2)
        for name2 in names2:
            fullname2 = os.path.join(os.getcwd(), name2)
            if os.path.isfile(fullname2):
            ##          print(fullname2)
                im2 = Image.open(fullname2)
                       print(im2)

                if ImageChops.difference(im2, im1):
                         print("True")
                else:
                        print("False")
 
Последнее редактирование:

feniks

Новичок
Пользователь
Апр 6, 2020
8
1
3
Вот пример:
Python:
from PIL import Image, ImageGrab
import os
import time


# сравнение скринов
def compare_img(img1, img2):
    with Image.open(img1) as im1, Image.open(img2) as im2:
        return im1 == im2


# поиск совпадений
def find_image(path1, path2, image_list, img):
    # поиск в цикле нужного скрина
    for image in image_list:
        if compare_img(path1 + img, path2 + image):
            print('Совпадающий скрин: ', image)
            break
    else:
        print('Совпадений не найдено')


path1 = 'D://Мася/ImageBot/-vse/'
path2 = 'D:/Мася/ImageBot/-B/'

# список файлов в папке со скринами
image_list = os.listdir(path2)

filename = None
while True:
    time.sleep(5)
    # тут нужно установить правильные координаты
    box = (1, 1, 321, 589)
    im = ImageGrab.grab(box)
    filename = str(int(time.time())) + '.png'
    im.save(filename, 'PNG')
    find_image(path1, path2, image_list, filename)

спасибо за помощь
 

Форум IT Специалистов