Я пробовал 3 метода, упомянутых выше и в других местах.
Похоже, существует два основных типа сравнения изображений: пиксель за пикселем и гистограмма.
Я испробовал оба варианта, и первый пиксель потерпел неудачу на 100%, как и должно быть, как если бы мы смещали второе изображение на 1 пиксель, все пиксели не будут совпадать, и у нас не будет совпадения на 100%.
Но сравнение гистограмм в теории должно работать очень хорошо, но это не так.
Вот два изображения со слегка смещенным портом просмотра, и гистограмма выглядит на 99% похожей, но алгоритм выдает результат, который говорит: «Очень разные»
1010 * Сосредоточенный *
То же, но смещено ~ 15º
4 различных алгоритма результата:
- Идеальное совпадение: False
- Разница в пикселях: 115816402
- Сравнение гистограммы: 83,69564286668303
- HistComparison: 1744.8160719686186
И то же сравнение первого изображения (в центре QR) с другим изображением, на 100%:
Совершенно другое изображение и гистограмма
Результаты алгоритма:
- Идеальное совпадение: False
- Разница в пикселях: 207893096
- Сравнение гистограммы: 104.30194643642095
- HistComparison: 6875.766716148522
Будем весьма благодарны за любые предложения о том, как измерить разницу в два изображения более точным и удобным способом. На данном этапе ни один из этих алгоритмов, по-видимому, не дает полезных результатов, поскольку немного отличающееся изображение имеет очень похожие / близкие результаты к 100% другому изображению.
from PIL import Image
from PIL import ImageChops
from functools import reduce
import numpy
import sys
import math
import operator
# Just checking if images are 100% the same
def equal(im1, im2):
img1 = Image.open(im1)
img2 = Image.open(im2)
return ImageChops.difference(img1, img2).getbbox() is None
def histCompare(im1, im2):
h1 = Image.open(im1).histogram()
h2 = Image.open(im2).histogram()
rms = math.sqrt(reduce(operator.add, map(lambda a, b: (a - b)**2, h1, h2)) / len(h1))
return rms
# To get a measure of how similar two images are, we calculate the root-mean-square (RMS)
# value of the difference between the images. If the images are exactly identical,
# this value is zero. The following function uses the difference function,
# and then calculates the RMS value from the histogram of the resulting image.
def rmsdiff_1997(im1, im2):
#"Calculate the root-mean-square difference between two images"
img1 = Image.open(im1)
img2 = Image.open(im2)
h = ImageChops.difference(img1, img2).histogram()
# calculate rms
return math.sqrt(reduce(operator.add,
map(lambda h, i: h * (i**2), h, range(256))
) / (float(img1.size[0]) * img1.size[1]))
# Pixel by pixel comparison to see if images are reasonably similar.
def countDiff(im1, im2):
s = 0
img1 = Image.open(im1)
img2 = Image.open(im2)
if img1.size != img2.size or img1.getbands() != img2.getbands():
return -1
for band_index, band in enumerate(img1.getbands()):
m1 = numpy.array([p[band_index] for p in img1.getdata()]).reshape(*img1.size)
m2 = numpy.array([p[band_index] for p in img2.getdata()]).reshape(*img2.size)
s += numpy.sum(numpy.abs(m1 - m2))
return s
print("[Same Image]")
print("Perfect match:", equal("data/start.jpg", "data/start.jpg"))
print("Pixel difference:", countDiff("data/start.jpg", "data/start.jpg"))
print("Histogram Comparison:", rmsdiff_1997("data/start.jpg", "data/start.jpg"))
print("HistComparison:", histCompare("data/start.jpg", "data/start.jpg"))
print("\n[Same Position]")
print("Perfect match:", equal("data/start.jpg", "data/end.jpg"))
print("Pixel difference:", countDiff("data/start.jpg", "data/end.jpg"))
print("Histogram Comparison:", rmsdiff_1997("data/start.jpg", "data/end.jpg"))
print("HistComparison:", histCompare("data/start.jpg", "data/end.jpg"))
print("\n[~5º off]")
print("Perfect match:", equal("data/start.jpg", "data/end2.jpg"))
print("Pixel difference:", countDiff("data/start.jpg", "data/end2.jpg"))
print("Histogram Comparison:", rmsdiff_1997("data/start.jpg", "data/end2.jpg"))
print("HistComparison:", histCompare("data/start.jpg", "data/end2.jpg"))
print("\n[~15º off]")
print("Perfect match:", equal("data/start.jpg", "data/end3.jpg"))
print("Pixel difference:", countDiff("data/start.jpg", "data/end3.jpg"))
print("Histogram Comparison:", rmsdiff_1997("data/start.jpg", "data/end3.jpg"))
print("HistComparison:", histCompare("data/start.jpg", "data/end3.jpg"))
print("\n[100% different]")
print("Perfect match:", equal("data/start.jpg", "data/end4.jpg"))
print("Pixel difference:", countDiff("data/start.jpg", "data/end4.jpg"))
print("Histogram Comparison:", rmsdiff_1997("data/start.jpg", "data/end4.jpg"))
print("HistComparison:", histCompare("data/start.jpg", "data/end4.jpg"))