[PYTHON] Programm zur Suche nach demselben Bild

Programm zur Suche nach demselben Bild

Es ist ein Programm, das doppelte Bilder findet, die unter einem bestimmten Ordner verstreut sind Berechnen Sie den Abstand zwischen den Vektoren, nachdem Sie das Bild verkleinert und monochromisiert und vektorisiert haben, während Sie die Merkmale des Bildes auf ein Minimum beschränken. Objekte mit einem Abstand von 0 oder nahe 0 werden als dasselbe Bild beurteilt. Ein solches Programm.

Machen Sie das Bild so klein wie möglich

Konvertieren Sie es dann zur einfacheren Berechnung in numpy.array.

def img2vec(filename):
    img = Image.open(filename)
    img = img.resize((200, 200), resample=Image.BILINEAR) #Schrumpfen
    img = img.convert('1') #Binarisierung
    #img.save(get_mono_filename(filename)) #Wenn Sie das Bild überprüfen möchten
    return np.array(img)

Die hier eingestellte Größe von 200 x 200 ist möglicherweise zu groß, und es dauerte ungefähr 9 Stunden, um dieses Programm für 22000 Blatt auszuführen. Ich denke also, dass ungefähr 50 x 50 in Ordnung sind.

Bilder vergleichen

Finden Sie den Abstand zwischen Vektoren mit numpy, es ist sehr einfach, numpy zu verwenden.

def normdiff(vec1, vec2):
    norm = np.linalg.norm(vec1 - vec2)
    return norm

Testcode

    norm = normdiff(img2vec("picture1.bmp"), img2vec("picture2.bmp"))
    print(norm)

Wenn Sie einen Testcode wie diesen mit der obigen Funktion ausführen, ist der Grad der Nähe zwischen Bildern? Wird angezeigt.

Ganze Quelle

import csv
import datetime
import glob
import multiprocessing as mulproc
import numpy as np
import os
from PIL import Image
import sys

def log(*args):
    timestr = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
    body = " ".join([timestr] + [str(v) for v in args])
    print(body)
    with open("log.txt", mode="a", encoding="utf-8") as wf:
        wf.write(body + "\n")

def get_mono_filename(filename):
    dirname, filename = os.path.split(filename)
    return os.path.join("mono", filename)

def img2vec(filename):
    # ANTIALIAS
    # BILINEAR
    # BICUBIC
    # NEAREST
    img = Image.open(filename)
    img = img.resize((200, 200), resample=Image.BILINEAR)
    img = img.convert('1')
    #img.save(get_mono_filename(filename)) #Wenn Sie das Bild überprüfen möchten
    return np.array(img)

def normdiff(vec1, vec2):
    norm = np.linalg.norm(vec1 - vec2)
    return norm

def walk_img_files(walk_dir):
    for root, dirs, files in os.walk(walk_dir):
        yield root
        for file in files:
            yield os.path.join(root, file)

def is_picture_filename(filename):
    extensions = ["png", "jpg"]
    for ext in extensions:
        if filename.endswith("." + ext): return True
    return False

def save_vector(filename, vec):
    with open(filename, mode="w", encoding="utf-8") as wf:
        writer = csv.writer(wf, lineterminator='\n')
        writer.writerows(vec)

def save_labels(filenames):
    with open("./labels.txt", mode="w", encoding="utf-8") as wf:
        wf.write("\n".join(filenames))

def create_vector_dump(search_dir):
    files = list(walk_img_files(search_dir))
    img_files = []
    for f in files:
        if is_picture_filename(f): img_files.append(f)

    for img_file in img_files:
        vec = img2vec(img_file)
        dir, filename = os.path.split(img_file)
        save_vector(os.path.join("vector", filename) + ".vector", list(vec.astype(int)))
    save_labels(img_files)
    return

def load_labels():
    with open("./labels.txt", mode="r", encoding="utf-8") as rf:
        body = rf.read()
        labels = body.split("\n")
        labels = [l for l in labels if len(l) > 0]
        return labels

def load_vecs(labels):
    log("start load vectoes")
    vecs = []
    for i, l in enumerate(labels):
        dirname, filename = os.path.split(l)
        filename = os.path.join("vector", filename + ".vector")
        vecs.append(np.loadtxt(filename, delimiter=","))
        log("load vectoes {}/{} complete".format(i, len(labels)))
    log("end load vectoes")
    return np.array(vecs)

def save_results(rows):
    with open("results.csv", mode="w", encoding="utf-8") as wf:
        writer = csv.writer(wf, lineterminator='\n')
        writer.writerows(rows)

def create_join_imgs(filename, vecs):
    vecs = np.concatenate(vecs, axis=1)
    vecs *= 255
    img = Image.fromarray(vecs).convert("1")
    img.save(filename)

def create_dup_imgs(approximates, vecs, labels):
    for i, approximate in enumerate(approximates):
        orig_label = labels[i]
        if len(approximate) < 1: continue
        img_vecs = [vecs[i]] + [vecs[ai] for ai in approximate]
        dirname, filename = os.path.split(orig_label)
        filename = os.path.join("dupulicate", filename)
        img = create_join_imgs(filename, img_vecs)

class EnumApproximate:
    def __init__(self):
        labels = load_labels()
        #labels = labels[0:1000]
        self.labels = labels
        vecs = load_vecs(labels)
        self.vecs = vecs
        self.threthold = float(10.0)

    def enum_approximate(self, index):
        indexes = []
        vec = self.vecs[index]
        for i, v in enumerate(self.vecs):
            if i == index: continue
            dif = normdiff(vec, v)
            if dif <= self.threthold: indexes.append(i)
        return indexes

    def exec(self):
        log("start")
        approximates = []
        for i in range(len(self.labels)):
            log("enum_approximate vectoes {}/{} complete".format(i, len(self.labels)))
            approximates.append(self.enum_approximate(i))
        rows = []
        for i in range(len(self.labels)):
            idxs = approximates[i]
            cols = [self.labels[i]] + [self.labels[ii] for ii in idxs]
            rows.append(cols)
        save_results(rows)
        create_dup_imgs(approximates, self.vecs, self.labels)
        log("end")

def main():
    x = EnumApproximate()
    x.exec()

if __name__ == '__main__':
    create_vector_dump(r"O:\picture\Versenden Sie diese")
    main()

Über die Ausführung

Erstellen Sie einen Ordner mit dem Namen vector und duplizieren Sie ihn in derselben Hierarchie wie die Quelle

create_vector_dump(r"O:\picture\Versenden Sie diese")

Durch Ausführen dieser einen Zeile wird ein CSV-Vektorbild im Vektorordner erstellt. Führen Sie main aus, wenn die Vektorisierung abgeschlossen ist. Sie können beide gleichzeitig ausführen.

Nach Abschluss der Ausführung werden eine CSV-ähnliche Datei mit dem Namen result.csv und ein Bild erstellt, in dem doppelte Bilder mit dem doppelten Ordner verbunden sind.

43164116_big_p1.png

Nur zu finden, bedeutet nicht, Duplikate zu löschen. Wenn Sie also etwas von dort aus tun möchten, können Sie ein Skript schreiben, das auf result.csv basiert.

Recommended Posts

Programm zur Suche nach demselben Bild
Python-Programm, das nach demselben Dateinamen sucht
Hashing-Algorithmus zur Bestimmung des gleichen Bildes
[Python] Ein Programm, das die Partitur rundet
Ein Shell-Programm, das eine Fibonacci-Sequenz anzeigt
Erstellt ein Narrbild für das Modell der Untertitelgenerierung
[Python] Ein Programm, das die Anzahl der Täler zählt
[Python] Ein Programm, das die Positionen von Kängurus vergleicht.
Das Bild ist Namekuji
Eine Geschichte über die Verbesserung des Programms zum teilweisen Füllen von binärisierten 3D-Bilddaten
Probieren Sie die ähnliche Suche von Image Search mit Python SDK [Search] aus.
Ein Programm, das nur die Esc-Taste drückt und loslässt
[Python] Ein Programm, das die häufigsten Vogeltypen findet
[Golang] Ein Programm, das die Runde mit Zufallszahlen bestimmt
Ich habe ein Skript geschrieben, das das Bild in zwei Teile teilt
Ein Programm, das die für iOS-App-Symbole in Python erforderliche Bildgröße automatisch ändert
Die Geschichte des Exportierens eines Programms
Schreiben wir ein einfaches Simulationsprogramm für das "Monty Hall Problem"
[Ev3dev] Erstellen Sie ein Programm, das das LCD (Bildschirm) mit Python erfasst
Schreiben Sie ein Programm, das das Programm missbraucht und 100 E-Mails sendet
Ein Programm, das einige Fragen beantwortet und die nächste Antwort vorhersagt
Ich habe ein Programm erstellt, das den Tierkreis mit tkinter automatisch berechnet
[Python] Ein Programm, das den Inhalt der Liste nach links dreht
Versuchen Sie, mit DCGAN + ein Death Metal-ähnliches Jackenbild zu erzeugen, und kratzen Sie die Metalldatenbank-Site dafür ab
Verstehen Sie die Wahrscheinlichkeiten und Statistiken, die für das Fortschrittsmanagement mit einem Python-Programm verwendet werden können
Laden Sie die Top-n-Google-Bildsuche herunter
Geben Sie das Know-how bekannt, das einen ähnlichen Bildsuchdienst für AV-Schauspielerinnen durch tiefes Lernen durch Chainer geschaffen hat
[Python] Ein Programm, das Treppen mit # erstellt
[Python] Ein Programm, das die Anzahl der Schokoladensegmente berechnet, die die Bedingungen erfüllen
Wenn Sie ein Programm erstellen, das die Überprüfungsumgebung für Pull-Anforderungen automatisch startet / beendet, wird die Überprüfung fortgesetzt.
Klasse, die die API von DMM trifft
Finde die Daten des verrückten Turniers heraus
[Python] Ein Programm, das die Anzahl der gepaarten Socken berechnet
Latein lernen zum Schreiben eines lateinischen Satzanalyseprogramms (Teil 1)
Ändern Sie die Liste in der for-Anweisung
Ein Programm, das alle Nachrichtenüberschriften sanft wiederherstellt
Ein Python-Programm, das die Größe eines Videos ändert und es in ein Bild verwandelt
Ein Programm, das Python zum Abspielen von Junk verwendet
Richten Sie einen Server ein, der mehrere Verbindungen gleichzeitig verarbeitet
Ich habe einen LINE BOT erstellt, der mithilfe der Flickr-API ein Bild von Reis-Terroristen zurückgibt
Eine einfache Problemumgehung für Bots, um zu versuchen, Tweets mit demselben Inhalt zu veröffentlichen
Suchen Sie in Google Earth nach einem Gebäude, das der Höhe von Shin Godzilla entspricht
[Python] Ein Programm, das die minimalen und maximalen Werte ohne Verwendung von Methoden findet
Lassen Sie uns eine einfache Vorlage anzeigen, die ideal für den ersten Django ist
[Python] Ein Programm, das die Differenz zwischen diagonalen Gesamtwerten berechnet
[Python] Ein Programm, das die Anzahl der Aktualisierungen der höchsten und niedrigsten Datensätze berechnet
Drehen Sie in Python mehrere Listen mit for-Anweisung gleichzeitig
Ein Modell, das die Gitarre mit fast.ai identifiziert
Erstellt einen Python-Wrapper für die Qiita-API
Nogizaka46 Ein Programm, das Blog-Bilder automatisch speichert
Machen Sie vorerst ein Histogramm (matplotlib)
Ein Programm, das doppelte Anweisungen in Python entfernt
Python: Bereiten Sie einen Serializer für die Klasseninstanz vor:
Bildverarbeitung? Die Geschichte, Python für zu starten
Erkennen Sie Ordner mit demselben Bild in ImageHash
Ein Programm, das den Betriebszustand von vollautomatischen Anlagenfotografieanlagen mitteilt
Ein Python-Skript, das die Anzahl der Jobs für eine bestimmte Bedingung von Indeed.com abruft
Ein Programm, das ein paar Kilogramm BMI und Standardgewicht verlangt [Python]