Не так давно я наткнулся на игру, в которую играл много лет назад. Я думаю, многие при поиске отличий ломали себе глаза долгое время. Сегодня я решил пройти её еще раз, но проходить её с 0 мне было, честно говоря, лень. Поэтому я решил написать себе помощника. Итак, начнем.
Писал я всё на python 2.7
Использовалась библиотека PIL
from PIL import Image, ImageDraw
Далее необходимо описать все функции и методы, которые мы будем использовать, для того, чтобы всем был понятен дальнейший код.
image1 = Image.open("1.jpg")
Так мы открываем нужный нам файл.
pix1 = image1.load()
Записываем в pix1 цвета всех пикселов картинки. Теперь по координате пикселя мы можем получить его цвет.
draw = ImageDraw.Draw(ANS)
Создание инструмента для рисования.
image1.size
Возвращает пару (ширина и высота картинки).
draw.ellipse((x1, y1, x2, y2), fill = "black")
Рисование чёрного элипса по заданным координатам.
ANS.save("ans.png", "PNG")
Сохранение изображения в формате PNG. Если не указан полный путь, то сохраняется в папку с исполняемой программой.
del draw
Удаление инструмента «draw».
Приступим к главному…
Откроем файлы, которые мы хотим сравнивать.
from PIL import Image, ImageDraw
image1 = Image.open("1.jpg") # Картинка № 1
image2 = Image.open("2.jpg") # Картинка № 2
ANS = Image.open("1.jpg") # Результат
Теперь создадим кисть и выгрузим из картинок все данные о цветах пикселов.
from PIL import Image, ImageDraw
image1 = Image.open("1.jpg") # Картинка № 1
image2 = Image.open("2.jpg") # Картинка № 2
ANS = Image.open("1.jpg") # Результат
draw = ImageDraw.Draw(ANS)
pix1 = image1.load()
pix2 = image2.load()
Необходимо определить размеры изображений. Так как они могут немного различаться, то возьмем минимальное из них, для того, чтобы не обратиться к несуществующим пикселам.
from PIL import Image, ImageDraw
image1 = Image.open("1.jpg") # Картинка № 1
image2 = Image.open("2.jpg") # Картинка № 2
ANS = Image.open("1.jpg") # Результат
draw = ImageDraw.Draw(ANS)
pix1 = image1.load()
pix2 = image2.load()
width = min(image1.size[0], image2.size[0])
height = min(image1.size[1], image2.size[1])
Осталось последнее. Будем перебирать пикселы и проверять их на сходство. Но точно их проверять нельзя, так как могут быть погрешности. Для этого введем eps, и будем сравнивать с ним. В местах, где наблюдается сильное различие, мы будем рисовать чёрные точки (эллипсы). Сохраняем результат.
from PIL import Image, ImageDraw
image1 = Image.open("1.jpg")
image2 = Image.open("2.jpg")
ANS = Image.open("1.jpg")
draw = ImageDraw.Draw(ANS)
pix1 = image1.load()
pix2 = image2.load()
width = min(image1.size[0], image2.size[0])
height = min(image1.size[1], image2.size[1])
eps = 30
for i in range(width):
for j in range(height):
dx1 = abs(pix1[i, j][0] - pix2[i, j][0])
dx2 = abs(pix1[i, j][1] - pix2[i, j][1])
dx3 = abs(pix1[i, j][2] - pix2[i, j][2])
if (dx1 > eps or dx2 > eps or dx3 > eps):
if (i % 5 == 0 and j % 5 == 0):
draw.ellipse((i, j, i + 5, j + 5), fill = "black")
ANS.save("ans.png", "PNG")
del draw
Вот и всё.
В данном примере вторая картинка немного сдвинута, поэтому большая погрешность, но всё равно выделяются отличия. (Бант, точки на мяче и ноги)
Автор: artem200