webentwicklung-frage-antwort-db.com.de

Wie kann ich den Unterschied zwischen zwei Bildern quantifizieren?

Folgendes möchte ich tun:

Ich mache in regelmäßigen Abständen Bilder mit einer Webcam. Eine Art Zeitraffer. Wenn sich jedoch nichts wirklich geändert hat, das heißt das Bild ziemlich genau sieht aus das gleiche, ich möchte nicht den neuesten Schnappschuss speichern.

Ich stelle mir vor, es gibt eine Möglichkeit, den Unterschied zu quantifizieren, und ich müsste eine Schwelle empirisch bestimmen.

Ich suche eher nach Einfachheit als nach Perfektion. Ich benutze Python.

164
carrier

Grund Idee

Option 1: Laden Sie beide Bilder als Arrays (scipy.misc.imread) und berechne eine elementweise (pixelweise) Differenz. Berechnen Sie die Norm der Differenz.

Option 2: Laden Sie beide Bilder. Berechnen Sie für jeden von ihnen einen Merkmalsvektor (wie ein Histogramm). Berechnen Sie den Abstand zwischen Merkmalsvektoren und nicht zwischen Bildern.

Es gibt jedoch einige Entscheidungen, die zuerst getroffen werden müssen.

Fragen

Sie sollten diese Fragen zuerst beantworten:

  • Sind Bilder von gleicher Form und Abmessung?

    Wenn nicht, müssen Sie möglicherweise die Größe ändern oder sie zuschneiden. Die PIL-Bibliothek wird Ihnen dabei helfen, dies in Python zu tun.

    Wenn sie mit den gleichen Einstellungen und dem gleichen Gerät aufgenommen werden, sind sie wahrscheinlich gleich.

  • Sind die Bilder gut ausgerichtet?

    Wenn nicht, möchten Sie möglicherweise zuerst die Kreuzkorrelation ausführen, um zuerst die beste Ausrichtung zu finden. SciPy hat Funktionen, um dies zu tun.

    Wenn die Kamera und die Szene stillstehen, sind die Bilder wahrscheinlich gut ausgerichtet.

  • Ist die Belichtung der Bilder immer gleich? (Ist Helligkeit/Kontrast gleich?)

    Wenn nicht, möchten Sie vielleicht normalisieren Bilder.

    Aber seien Sie vorsichtig, in manchen Situationen kann dies mehr falsch als gut sein. Zum Beispiel wird ein einzelnes helles Pixel auf einem dunklen Hintergrund das normalisierte Bild sehr unterschiedlich machen.

  • Sind Farbinformationen wichtig?

    Wenn Sie Farbänderungen bemerken möchten, erhalten Sie einen Vektor mit Farbwerten pro Punkt und keinen Skalarwert wie im Graustufenbild. Sie benötigen mehr Aufmerksamkeit, wenn Sie solchen Code schreiben.

  • Gibt es deutliche Kanten im Bild? Bewegen sie sich wahrscheinlich?

    Wenn ja, können Sie zuerst den Kantenerkennungsalgorithmus anwenden (z. B. Gradient mit Sobel- oder Prewitt-Transformation berechnen, einen Schwellenwert anwenden) und dann die Kanten des ersten Bilds mit den Kanten des zweiten Bilds vergleichen.

  • Ist das Bild verrauscht?

    Alle Sensoren verschmutzen das Bild mit etwas Rauschen. Kostengünstige Sensoren weisen mehr Rauschen auf. Möglicherweise möchten Sie eine Rauschunterdrückung anwenden, bevor Sie Bilder vergleichen. Unschärfe ist hier der einfachste (aber nicht der beste) Ansatz.

  • Welche Art von Änderungen möchten Sie bemerken?

    Dies kann sich auf die Auswahl der Norm auswirken, die für den Unterschied zwischen Bildern verwendet werden soll.

    Verwenden Sie die Manhattan-Norm (die Summe der absoluten Werte) oder die Null-Norm (die Anzahl der Elemente ungleich Null), um zu messen, um wie viel sich das Bild geändert hat. Ersteres zeigt an, wie stark das Bild abweicht, letzteres zeigt nur an, wie viele Pixel sich unterscheiden.

Beispiel

Ich gehe davon aus, dass Ihre Bilder gut ausgerichtet sind, die gleiche Größe und Form haben, möglicherweise mit unterschiedlicher Belichtung. Der Einfachheit halber konvertiere ich sie in Graustufen, auch wenn es sich um Farbbilder (RGB) handelt.

Sie benötigen diese Importe:

import sys

from scipy.misc import imread
from scipy.linalg import norm
from scipy import sum, average

Hauptfunktion, zwei Bilder auslesen, in Graustufen konvertieren, Ergebnisse vergleichen und ausdrucken:

def main():
    file1, file2 = sys.argv[1:1+2]
    # read images as 2D arrays (convert to grayscale for simplicity)
    img1 = to_grayscale(imread(file1).astype(float))
    img2 = to_grayscale(imread(file2).astype(float))
    # compare
    n_m, n_0 = compare_images(img1, img2)
    print "Manhattan norm:", n_m, "/ per pixel:", n_m/img1.size
    print "Zero norm:", n_0, "/ per pixel:", n_0*1.0/img1.size

Wie man vergleicht. img1 und img2 sind 2D SciPy Arrays hier:

def compare_images(img1, img2):
    # normalize to compensate for exposure difference, this may be unnecessary
    # consider disabling it
    img1 = normalize(img1)
    img2 = normalize(img2)
    # calculate the difference and its norms
    diff = img1 - img2  # elementwise for scipy arrays
    m_norm = sum(abs(diff))  # Manhattan norm
    z_norm = norm(diff.ravel(), 0)  # Zero norm
    return (m_norm, z_norm)

Wenn es sich bei der Datei um ein Farbbild handelt, gibt imread ein 3D-Array mit durchschnittlichen RGB-Kanälen (die letzte Achse des Arrays) zurück, um die Intensität zu ermitteln. Für Graustufenbilder ist dies nicht erforderlich (z. B. .pgm):

def to_grayscale(arr):
    "If arr is a color image (3D array), convert it to grayscale (2D array)."
    if len(arr.shape) == 3:
        return average(arr, -1)  # average over the last axis (color channels)
    else:
        return arr

Normalisierung ist trivial, Sie können statt auf [0,255] auch auf [0,1] normalisieren. arr ist hier ein SciPy-Array, daher sind alle Operationen elementweise:

def normalize(arr):
    rng = arr.max()-arr.min()
    amin = arr.min()
    return (arr-amin)*255/rng

Führen Sie die Funktion main aus:

if __== "__main__":
    main()

Jetzt können Sie dies alles in ein Skript einfügen und gegen zwei Bilder ausführen. Wenn wir das Bild mit sich selbst vergleichen, gibt es keinen Unterschied:

$ python compare.py one.jpg one.jpg
Manhattan norm: 0.0 / per pixel: 0.0
Zero norm: 0 / per pixel: 0.0

Wenn wir das Bild verwischen und mit dem Original vergleichen, gibt es einen Unterschied:

$ python compare.py one.jpg one-blurred.jpg 
Manhattan norm: 92605183.67 / per pixel: 13.4210411116
Zero norm: 6900000 / per pixel: 1.0

P.S. Gesamtes compare.py Skript.

Update: relevante Techniken

Da es sich um eine Videosequenz handelt, bei der die Frames wahrscheinlich fast gleich sind und Sie nach etwas Ungewöhnlichem suchen, möchte ich einige alternative Ansätze erwähnen, die relevant sein können:

  • hintergrundsubtraktion und -segmentierung (zur Erkennung von Vordergrundobjekten)
  • spärlicher optischer Fluss (um Bewegung zu erkennen)
  • vergleich von Histogrammen oder anderen Statistiken anstelle von Bildern

Ich empfehle dringend, einen Blick in das Buch „Learning OpenCV“ zu werfen, Kapitel 9 (Bildteile und Segmentierung) und 10 (Verfolgung und Bewegung). Ersteres lehrt die Verwendung der Hintergrundsubtraktionsmethode, letzteres gibt einige Informationen zu optischen Flussmethoden. Alle Methoden sind in der OpenCV-Bibliothek implementiert. Wenn Sie Python verwenden, empfehle ich OpenCV ≥ 2.3 und dessen cv2 Python module.

Die einfachste Version der Hintergrundsubtraktion:

  • lernen Sie für jedes Pixel des Hintergrunds den Mittelwert μ und die Standardabweichung σ
  • aktuelle Pixelwerte mit dem Bereich von (μ-2σ, μ + 2σ) oder (μ-σ, μ + σ) vergleichen

Fortgeschrittenere Versionen berücksichtigen Zeitreihen für jedes Pixel und verarbeiten nicht statische Szenen (wie sich bewegende Bäume oder Gras).

Die Idee des optischen Flusses besteht darin, zwei oder mehr Bilder aufzunehmen und jedem Pixel (dichter optischer Fluss) oder einigen von ihnen (spärlicher optischer Fluss) einen Geschwindigkeitsvektor zuzuweisen. Um den spärlichen optischen Fluss abzuschätzen, können Sie Lucas-Kanade-Methode verwenden (dies ist auch in OpenCV implementiert). Wenn viel Fluss herrscht (hoher Durchschnitt über die Maximalwerte des Geschwindigkeitsfelds), bewegt sich offensichtlich etwas im Rahmen, und nachfolgende Bilder sind unterschiedlicher.

Das Vergleichen von Histogrammen kann dabei helfen, plötzliche Änderungen zwischen aufeinanderfolgenden Bildern zu erkennen. Dieser Ansatz wurde verwendet in Courbon et al, 2010 :

Ähnlichkeit aufeinanderfolgender Bilder Der Abstand zwischen zwei aufeinanderfolgenden Bildern wird gemessen. Wenn es zu hoch ist, bedeutet dies, dass das zweite Bild beschädigt ist und somit das Bild eliminiert wird. Die Kullback-Leibler-Distanz oder gegenseitige Entropie auf den Histogrammen der beiden Frames:

$$ d(p,q) = \sum_i p(i) \log (p(i)/q(i)) $$

dabei werden p und q die Histogramme der Frames verwendet. Die Schwelle ist fest auf 0,2 eingestellt.

249
sastanin

Eine einfache Lösung:

Codiere das Bild als jpeg und achte auf eine wesentliche Änderung in Dateigröße.

Ich habe etwas Ähnliches mit Video-Thumbnails implementiert und hatte viel Erfolg und Skalierbarkeit.

75
keparo

Sie können zwei Bilder mit den Funktionen von PIL vergleichen.

import Image
import ImageChops

im1 = Image.open("splash.png")
im2 = Image.open("splash2.png")

diff = ImageChops.difference(im2, im1)

Das Diff-Objekt ist ein Bild, in dem jedes Pixel das Ergebnis der Subtraktion der Farbwerte dieses Pixels im zweiten Bild vom ersten Bild ist. Mit dem Diff-Bild können Sie verschiedene Dinge tun. Die einfachste ist die Funktion diff.getbbox(). Es wird Ihnen das minimale Rechteck anzeigen, das alle Änderungen zwischen Ihren beiden Bildern enthält.

Sie können wahrscheinlich auch mithilfe von PIL-Funktionen Annäherungen an die anderen hier genannten Dinge implementieren.

55
elifiner

Zwei beliebte und relativ einfache Methoden sind: (a) der bereits vorgeschlagene euklidische Abstand oder (b) eine normalisierte Kreuzkorrelation. Normalisierte Kreuzkorrelation ist gegenüber Beleuchtungsänderungen tendenziell deutlich robuster als einfache Kreuzkorrelation. Wikipedia gibt eine Formel für die normalisierte Kreuzkorrelation . Es gibt auch ausgefeiltere Methoden, die jedoch viel mehr Arbeit erfordern.

Mit numpy-ähnlicher Syntax

 dist_euclidean = sqrt (sum ((i1 - i2) ^ 2))/i1.size 
 
 dist_manhattan = sum (abs (i1 - i2))/i1.size 
 
 dist_ncc = Summe ((i1 - Mittelwert (i1)) * (i2 - Mittelwert (i2))/(
 (i1.size - 1) * stdev (i1) * stdev (i2)) 

vorausgesetzt, dass i1 und i2 sind 2D-Graustufenbild-Arrays.

19
Mr Fooz

Eine Kleinigkeit zu versuchen:

Setzen Sie beide Bilder zu kleinen Miniaturansichten zusammen (z. B. 64 x 64) und vergleichen Sie die Miniaturansichten pixelweise mit einem bestimmten Schwellenwert. Wenn die Originalbilder fast gleich sind, sind die neu abgetasteten Miniaturansichten sehr ähnlich oder sogar genau gleich. Diese Methode sorgt für Rauschen, das insbesondere bei schlechten Lichtverhältnissen auftreten kann. Es kann sogar besser sein, wenn Sie Graustufen gehen.

13
Ates Goral

Ich spreche speziell die Frage an, wie zu berechnen ist, ob sie "unterschiedlich genug" sind. Ich gehe davon aus, dass Sie herausfinden können, wie Sie die Pixel einzeln subtrahieren.

Zuerst würde ich eine Reihe von Bildern aufnehmen, bei denen sich nichts ändert, und den maximalen Betrag ermitteln, um den sich ein Pixel ändert, nur weil sich die Aufnahme ändert, Rauschen Im Imaging-System treten JPEG-Komprimierungsartefakte und Änderungen der Beleuchtung von Moment zu Moment auf. Vielleicht werden Sie feststellen, dass 1 oder 2 Bit Unterschiede zu erwarten sind, auch wenn sich nichts bewegt.

Dann wollen Sie für den "echten" Test ein Kriterium wie das folgende:

  • gleich, wenn sich bis zu P Pixel um nicht mehr als E unterscheiden.

Wenn also E = 0,02, P = 1000, würde dies (ungefähr) bedeuten, dass es "anders" wäre, wenn sich ein einzelnes Pixel um mehr als ~ 5 Einheiten ändert (unter der Annahme von 8-Bit-Bildern), oder wenn mehr als 1000 Pixel hatten überhaupt keine Fehler.

Dies ist hauptsächlich als eine gute "Triage" -Technik gedacht, um Bilder schnell zu identifizieren, die nah genug sind, um keine weitere Untersuchung zu benötigen. Die Bilder, die "scheitern", könnten dann mehr zu einer aufwändigeren/teureren Technik werden, die keine Fehlalarme hätte, wenn die Kamera zum Beispiel etwas wackelte oder widerstandsfähiger gegen Lichtveränderungen wäre.

Ich führe ein Open-Source-Projekt aus, OpenImageIO , das ein Hilfsprogramm namens "idiff" enthält, das Unterschiede mit solchen Schwellenwerten vergleicht (genauer gesagt). Auch wenn Sie diese Software nicht verwenden möchten, sollten Sie sich die Quelle ansehen, um zu sehen, wie wir das gemacht haben. Es wird kommerziell ziemlich oft verwendet und diese Schwellenwerttechnik wurde entwickelt, damit wir eine Testsuite für Rendering- und Bildverarbeitungssoftware mit "Referenzbildern" haben können, die kleine Unterschiede von Plattform zu Plattform aufweisen können oder an denen wir geringfügige Änderungen vorgenommen haben Die Algorithmen, also wollten wir eine "Übereinstimmung innerhalb der Toleranz" -Operation.

7
Larry Gritz

Die meisten Antworten beziehen sich nicht auf die Beleuchtungsstärke.

Ich würde das Bild zuerst auf ein Standardlichtniveau normalisieren, bevor ich den Vergleich vornehme.

5
Loren Pechtel

Ein weiterer einfacher Weg, um die Ähnlichkeit zwischen zwei Bildern zu messen:

import sys
from skimage.measure import compare_ssim
from skimage.transform import resize
from scipy.ndimage import imread

# get two images - resize both to 1024 x 1024
img_a = resize(imread(sys.argv[1]), (2**10, 2**10))
img_b = resize(imread(sys.argv[2]), (2**10, 2**10))

# score: {-1:1} measure of the structural similarity between the images
score, diff = compare_ssim(img_a, img_b, full=True)
print(score)

Wenn andere an einer leistungsfähigeren Methode zum Vergleichen der Bildähnlichkeit interessiert sind, habe ich ein Tutorial und ein web App zusammengestellt, um ähnliche Bilder mit Tensorflow zu messen und zu visualisieren.

4
duhaime

Bei der Arbeit hatte ich ein ähnliches Problem. Ich habe unseren Image-Transformations-Endpunkt neu geschrieben und wollte überprüfen, ob die neue Version die gleiche oder fast die gleiche Ausgabe wie die alte Version liefert. Also habe ich folgendes geschrieben:

https://github.com/nicolashahn/diffimg

Bei Bildern gleicher Größe und auf Pixelebene wird die Wertedifferenz für jeden Kanal gemessen: R, G, B (, A), wird die durchschnittliche Differenz dieser Kanäle ermittelt und die Differenz dann gemittelt alle Pixel und gibt ein Verhältnis zurück.

Beispiel: Bei einem 10x10-Bild mit weißen Pixeln und demselben Bild mit einem Pixel, das sich in Rot geändert hat, beträgt der Unterschied bei diesem Pixel 1/3 oder 0,33 ... (RGB 0,0,0 vs 255,0,0 ) und bei allen anderen Pixeln ist 0. Bei 100 Pixeln insgesamt 0,33 .../100 = ~ 0,33% Unterschied im Bild.

Ich glaube, dass dies perfekt für das OP-Projekt funktionieren würde (mir ist klar, dass dies jetzt ein sehr alter Beitrag ist, aber ein Beitrag für zukünftige StackOverflowers, die auch Bilder in Python vergleichen möchten).

4
nicolashahn

Haben Sie die Frage Algorithmus zum Auffinden ähnlicher Bilder gesehen? Probieren Sie es aus, um Vorschläge zu sehen.

Ich würde eine Wavelet-Transformation Ihrer Frames vorschlagen (ich habe dafür eine C-Erweiterung mit Haar-Transformation geschrieben); Wenn Sie dann die Indizes der größten (proportionalen) Wavelet-Faktoren zwischen den beiden Bildern vergleichen, sollten Sie eine numerische Ähnlichkeitsnäherung erhalten.

3
tzot

Ich entschuldige mich, wenn dies zu spät ist, um zu antworten, aber da ich etwas Ähnliches mache, dachte ich, ich könnte irgendwie dazu beitragen.

Vielleicht könnten Sie mit OpenCV den Template-Abgleich verwenden. Angenommen, Sie verwenden wie gesagt eine Webcam:

  1. Vereinfachen Sie die Bilder (Schwellenwert vielleicht?)
  2. Wenden Sie den Template-Abgleich an und überprüfen Sie den max_val mit minMaxLoc

Tipp: max_val (oder min_val, abhängig von der verwendeten Methode) gibt Ihnen Zahlen, große Zahlen. Um die prozentuale Differenz zu ermitteln, verwenden Sie eine Vorlage, die mit demselben Bild übereinstimmt. Das Ergebnis ist 100%.

Pseudocode zur Veranschaulichung:

previous_screenshot = ...
current_screenshot = ...

# simplify both images somehow

# get the 100% corresponding value
res = matchTemplate(previous_screenshot, previous_screenshot, TM_CCOEFF)
_, hundred_p_val, _, _ = minMaxLoc(res)

# hundred_p_val is now the 100%

res = matchTemplate(previous_screenshot, current_screenshot, TM_CCOEFF)
_, max_val, _, _ = minMaxLoc(res)

difference_percentage = max_val / hundred_p_val

# the tolerance is now up to you

Ich hoffe es hilft.

2
zanfranceschi

Abstand der Erdbewegungsmaschinen könnte genau das sein, was Sie brauchen. Es könnte etwas schwer sein, es in Echtzeit zu implementieren.

1
shoosh

Was ist mit der Berechnung der Manhattan-Entfernung der beiden Bilder. Das gibt Ihnen n * n Werte. Dann könnten Sie so etwas wie einen Zeilendurchschnitt machen, um auf n Werte zu reduzieren, und eine Funktion darüber, um einen einzelnen Wert zu erhalten.

1
Tobias
import os
from PIL import Image
from PIL import ImageFile
import imagehash

#just use to the size diferent picture
def compare_image(img_file1, img_file2):
    if img_file1 == img_file2:
        return True
    fp1 = open(img_file1, 'rb')
    fp2 = open(img_file2, 'rb')

    img1 = Image.open(fp1)
    img2 = Image.open(fp2)

    ImageFile.LOAD_TRUNCATED_IMAGES = True
    b = img1 == img2

    fp1.close()
    fp2.close()

    return b





#through picturu hash to compare
def get_hash_dict(dir):
    hash_dict = {}
    image_quantity = 0
    for _, _, files in os.walk(dir):
        for i, fileName in enumerate(files):
            with open(dir + fileName, 'rb') as fp:
                hash_dict[dir + fileName] = imagehash.average_hash(Image.open(fp))
                image_quantity += 1

    return hash_dict, image_quantity

def compare_image_with_hash(image_file_name_1, image_file_name_2, max_dif=0):
    """
    max_dif: The maximum hash difference is allowed, the smaller and more accurate, the minimum is 0.
    recommend to use
    """
    ImageFile.LOAD_TRUNCATED_IMAGES = True
    hash_1 = None
    hash_2 = None
    with open(image_file_name_1, 'rb') as fp:
        hash_1 = imagehash.average_hash(Image.open(fp))
    with open(image_file_name_2, 'rb') as fp:
        hash_2 = imagehash.average_hash(Image.open(fp))
    dif = hash_1 - hash_2
    if dif < 0:
        dif = -dif
    if dif <= max_dif:
        return True
    else:
        return False


def compare_image_dir_with_hash(dir_1, dir_2, max_dif=0):
    """
    max_dif: The maximum hash difference is allowed, the smaller and more accurate, the minimum is 0.

    """
    ImageFile.LOAD_TRUNCATED_IMAGES = True
    hash_dict_1, image_quantity_1 = get_hash_dict(dir_1)
    hash_dict_2, image_quantity_2 = get_hash_dict(dir_2)

    if image_quantity_1 > image_quantity_2:
        tmp = image_quantity_1
        image_quantity_1 = image_quantity_2
        image_quantity_2 = tmp

        tmp = hash_dict_1
        hash_dict_1 = hash_dict_2
        hash_dict_2 = tmp

    result_dict = {}

    for k in hash_dict_1.keys():
        result_dict[k] = None

    for dif_i in range(0, max_dif + 1):
        have_none = False

        for k_1 in result_dict.keys():
            if result_dict.get(k_1) is None:
                have_none = True

        if not have_none:
            return result_dict

        for k_1, v_1 in hash_dict_1.items():
            for k_2, v_2 in hash_dict_2.items():
                sub = (v_1 - v_2)
                if sub < 0:
                    sub = -sub
                if sub == dif_i and result_dict.get(k_1) is None:
                    result_dict[k_1] = k_2
                    break
    return result_dict


def main():
    print(compare_image('image1\\815.jpg', 'image2\\5.jpg'))
    print(compare_image_with_hash('image1\\815.jpg', 'image2\\5.jpg', 6))
    r = compare_image_dir_with_hash('image1\\', image2\\', 10)
    for k in r.keys():
        print(k, r.get(k))


if __== '__main__':
    main()
  • ausgabe:

    False
    Wahr
    image2\5.jpg image1\815.jpg
    image2\6.jpg image1\819.jpg
    image2\7.jpg image1\900.jpg
    image2\8.jpg image1\998.jpg
    image2\9.jpg image1\1012.jpg

  • die beispielbilder:

    • 815.jpg
      815.jpg

    • 5.jpg
      5.jpg

1
admin

Sehen Sie sich an, wie Haar Wavelets von isk-daemon implementiert werden. Sie können den imgdb-C++ - Code verwenden, um den Unterschied zwischen Bildern im laufenden Betrieb zu berechnen:

isk-daemon ist ein Open-Source-Datenbankserver, der inhaltsbasierte (visuelle) Bildersuche zu jeder bildbezogenen Website oder Software hinzufügen kann.

Mit dieser Technologie können Benutzer jeder bildbezogenen Website oder Software auf einem Widget skizzieren, welches Bild sie suchen möchten, und auf jeder Bilddetailseite von der Website die ähnlichsten Bilder beantworten oder einfach mehr ähnliche Fotos anfordern lassen.

1
Ricardo Cabral

Ein etwas grundsätzlicherer Ansatz ist die Verwendung eines globalen Deskriptors zum Vergleichen von Bildern wie Gist oder CENTRIST. Eine Hash-Funktion, wie beschrieben hier , bietet ebenfalls eine ähnliche Lösung.

1
Felix Goldberg

Ich hatte das gleiche Problem und schrieb ein einfaches python Modul, das zwei Bilder gleicher Größe mit Hilfe von ImageChops von pillow vergleicht, um ein Schwarz/Weiß-Diff-Bild zu erstellen und die Histogrammwerte zusammenzufassen.

Sie können entweder diese Punktzahl direkt oder einen Prozentwert im Vergleich zu einem Vollschwarz-Weiß-Diff erhalten.

Es enthält auch eine einfache Funktion is_equal, mit der Möglichkeit, eine Fuzzy-Schwelle unter (und einschließlich) dem Bild als gleich zu übergeben.

Der Ansatz ist nicht sehr aufwändig, aber vielleicht nützlich für andere, die mit dem gleichen Problem zu kämpfen haben.

https://pypi.python.org/pypi/imgcompare/

1
datenhahn

sie können das Histogramm beider Bilder berechnen und dann den Bhattacharyya-Koeffizient berechnen. Dies ist ein sehr schneller Algorithmus und ich habe ihn verwendet, um Schussänderungen in einem Cricket-Video zu erkennen (in C mit openCV).

1
vishalv2050

Ich hatte viel Glück mit JPG-Bildern, die mit derselben Kamera auf einem Stativ aufgenommen wurden, indem ich (1) stark vereinfacht habe (z. B. von 3000 Pixel auf 100 Pixel oder noch weniger) (2) jedes JPG-Array zu einem einzigen abgeflacht habe Vektor (3) Paarweises Korrelieren von sequentiellen Bildern mit einem einfachen Korrelationsalgorithmus, um den Korrelationskoeffizienten (4) zum Quadrieren des Korrelationskoeffizienten zu erhalten, um das r-Quadrat (dh den Anteil der Variabilität in einem Bild, erklärt durch Variation im nächsten) (5) im Allgemeinen in meiner Anwendung Wenn R-Quadrat <0,9, sage ich, dass die beiden Bilder unterschiedlich sind und etwas dazwischen passiert ist.

Das ist robust und schnell in meiner Implementierung (Mathematica 7)

Es lohnt sich, mit dem Teil des Bildes zu spielen, an dem Sie interessiert sind, und sich darauf zu konzentrieren, indem Sie alle Bilder auf diesen kleinen Bereich zuschneiden. Andernfalls wird eine von der Kamera entfernte, aber wichtige Änderung übersehen.

Ich weiß nicht, wie man Python benutzt, aber bin ich sicher, dass es auch Korrelationen gibt, nein?

1
Roman Dial

Ich denke, Sie könnten einfach den euklidischen Abstand (d. H. Sqrt (Summe der Quadrate von Differenzen, Pixel für Pixel)) zwischen der Luminanz der beiden Bilder berechnen und als gleich betrachten, wenn dies unter einen empirischen Schwellenwert fällt. Und Sie sollten es besser machen, wenn Sie eine C-Funktion umbrechen.

0

Es gibt viele Metriken, mit denen bewertet werden kann, ob und wie viele Bilder aussehen.

Ich werde hier auf keinen Code eingehen, da ich der Meinung bin, dass es sich nicht um ein technisches Problem, sondern um ein wissenschaftliches Problem handeln sollte.

Im Allgemeinen hängt die Frage mit der Wahrnehmung des Menschen auf Bildern zusammen, sodass jeder Algorithmus die Merkmale des menschlichen visuellen Systems unterstützt.

Klassische Ansätze sind:

Prädiktor für sichtbare Unterschiede: Ein Algorithmus zur Bewertung der Bildtreue ( https://www.spiedigitallibrary.org/conference-proceedings-of-spie/1666/0000/Visible-differences-predictor--an-algorithm- for-the-assessment-of/10.1117/12.135952.short? SSO = 1 )

Bewertung der Bildqualität: Von der Fehlersichtbarkeit zur strukturellen Ähnlichkeit ( http://www.cns.nyu.edu/pub/lcv/wang03-reprint.pdf )

FSIM: Ein Merkmalähnlichkeitsindex für die Beurteilung der Bildqualität ( https://www4.comp.polyu.edu.hk/~cslzhang/IQA/TIP_IQA_FSIM.pdf )

Unter diesen ist SSIM (Image Quality Assessment: Von der Fehlersichtbarkeit zur strukturellen Ähnlichkeit) am einfachsten zu berechnen, und sein Overhead ist ebenfalls gering, wie in einem anderen Artikel "Image Quality Assessment Based Gradient Similarity" ( https://www.semanticscholar.org/paper/Image-Quality-Assessment-Based-on-Gradient-Liu-Lin/2b819bef80c02d5d4cb56f27b202535e119df988 ).

Es gibt noch viele andere Ansätze. Werfen Sie einen Blick auf Google Scholar und suchen Sie nach etwas wie "visuellem Unterschied", "Bildqualitätsbewertung" usw., wenn Sie an der Kunst interessiert sind/sich wirklich dafür interessieren.

0
cyfex

Es gibt eine einfache und schnelle Lösung mit numpy, indem der mittlere quadratische Fehler berechnet wird:

before = np.array(get_picture())
while True:
    now = np.array(get_picture())
    MSE = np.mean((now - before)**2)

    if  MSE > threshold:
        break

    before = now
0
Arian Soltani