Какие функции из библиотеки изображений Python помогут мне найти разницу между двумя изображениями?

Я просматриваю документы Python Imaging Library для того, чтобы взять 2 похожих изображения и "вычесть одно из другого". Вот наглядное пособие:

Мы все видели эти изящные "превращающие слово в смысл" вещи, верно? Я хочу в основном взять второе изображение и вычесть первое изображение, поэтому я хочу возвращать только строки, добавленные к слову "кошка", чтобы сделать фактическую кошку. Какие функции помогут мне в этом?

Обновление: я работал над этим непрерывно, ожидая. Это то, что я пробовал.

import numpy as np
from PIL import Image
from PIL import ImageChops
import math,operator, matplotlib.cm as cm

img1 = Image.open("cat1.PNG")
img2 = Image.open("cat2.PNG")


img1array = (list(img1.getdata()))
img1new = Image.fromarray(np.uint8(cm.gist_earth(img1array)*255))

img2array = (list(img2.getdata()))
img2new = Image.fromarray(np.uint8(cm.gist_earth(img2array)*255))

dif = np.fabs(np.subtract(img2array[:], img1array[:]))

difimg = Image.fromarray(np.uint8(cm.gist_earth(dif)*255))

difimg.save("out1.PNG")

Тем не менее, это выводит файл, который Windows 10 даже не может открыть. Моя идея состояла в том, чтобы преобразовать оба изображения в массив, вычесть их, а затем воссоздать разницу как изображение. Это действительно сохраняет файл с именем out1.PNG, но Windows выдает ошибку при попытке открыть ее: We can't open this file. Примечание - я изменил размер 2-го изображения с помощью онлайн-ресайзера, PIL доставлял мне проблемы с размерами...

1 ответ

Я думаю, что вы ищете, называется регистрация изображений. Вы хотите знать, насколько вам нужно сдвинуть одно изображение, чтобы получить другое. Тогда вы можете сделать простое вычитание. Есть разные способы сделать это. Самый простой - использовать грубую силу (см. Код ниже). Я устанавливаю пороговые значения изображений, чтобы уменьшить проблемы, связанные с колебаниями интенсивности освещения.

Другой альтернативой является использование более сложного метода выравнивания. Некоторые из них реализованы в opencv 1, 2, или вы можете использовать метод, основанный на БПФ.

import numpy as np
import matplotlib.pylab as plt


th = 170 #arbitrary threshold, you can use automatic methods like otsu or even better some adaptative thresholding.
Ibth = (Ibig < th).astype(np.int)
Isth = (Ismall < th).astype(np.int)

dxt = (Ibth.shape[1] - Isth.shape[1])-1
dyt = (Ibth.shape[0] - Isth.shape[0])-1

xdiff = np.zeros((dyt, dxt))

S = Isth.shape
for dx in range(dxt):
    for dy in range(dyt):

        dpix = Isth-Ibth[dy:(S[0]+dy), dx:(S[1]+dx)]

        #I am only considering pixels that get overlaped in the bigger image.
        #The non-uniform illumination spoils minimization if I use np.abs.
        #This could be corrected using opencv adaptativeThreshold
        xdiff[dy,dx] = np.sum(dpix>0)

#find the global minima
im_shift = np.unravel_index(xdiff.argmin(), xdiff.shape)

#show the result
im_diff = np.copy(Ibth).astype(np.int)
im_diff[im_shift[0]:(S[0]+im_shift[0]), im_shift[1]:(S[1]+im_shift[1])] -= Isth


plt.figure()

plt.subplot(2,2,1)
plt.imshow(Ib,  cmap='gray', interpolation='none')

plt.subplot(2,2,3)
plt.imshow(Is,  cmap='gray', interpolation='none')

plt.subplot(1,2,2)
plt.imshow(im_diff,  cmap='gray', interpolation='none')
Другие вопросы по тегам