it-swarm-eu.dev

Algorithmus zum Auffinden ähnlicher Bilder

Ich brauche einen Algorithmus, der bestimmen kann, ob zwei Bilder "ähnlich" sind und ähnliche Muster von Farbe, Helligkeit, Form usw. erkennt. Ich brauche möglicherweise einige Hinweise, welche Parameter das menschliche Gehirn verwendet, um Bilder zu "kategorisieren". ..

Ich habe mir hausdorffbasiertes Matching angesehen, aber das scheint hauptsächlich für das Matching von transformierten Objekten und Formmustern zu gelten.

76
kitsune

Ich habe etwas Ähnliches getan, indem ich Bilder mit Wavelet-Transformation in Signaturen zerlegt habe.

Mein Ansatz bestand darin, die signifikantesten n Koeffizienten aus jedem transformierten Kanal auszuwählen und deren Position aufzuzeichnen. Dies geschah, indem die Liste der Tupel (Potenz, Ort) nach abs (Potenz) sortiert wurde. Ähnliche Bilder haben insofern Ähnlichkeiten, als sie an denselben Stellen signifikante Koeffizienten aufweisen.

Ich fand es am besten, das Bild in das YUV-Format zu transformieren, wodurch Sie Ähnlichkeiten in Form (Y-Kanal) und Farbe (UV-Kanäle) effektiv gewichten können.

Sie finden meine Implementierung des oben genannten in mactorii , woran ich leider nicht so viel gearbeitet habe, wie ich sollte :-)

Eine andere Methode, die einige meiner Freunde mit überraschend guten Ergebnissen angewendet haben, besteht darin, die Größe Ihres Bilds einfach auf ein 4 × 4-Pixel zu verkleinern und das Bild zu speichern, das Ihre Signatur ist. Wie ähnlich 2 Bilder sind, kann beispielsweise durch Berechnen des Manhattan-Abstands zwischen den 2 Bildern unter Verwendung entsprechender Pixel bewertet werden. Ich habe keine Details darüber, wie sie die Größenänderung durchgeführt haben, daher müssen Sie möglicherweise mit den verschiedenen Algorithmen spielen, die für diese Aufgabe verfügbar sind, um einen geeigneten zu finden.

55
freespace

pHash könnte Sie interessieren.

wahrnehmungs-Hash Ein Fingerabdruck einer Audio-, Video- oder Bilddatei, der mathematisch auf dem darin enthaltenen Audio- oder visuellen Inhalt basiert. Im Gegensatz zu kryptografischen Hash-Funktionen, die auf dem Lawineneffekt kleiner Änderungen der Eingabe beruhen, die zu drastischen Änderungen der Ausgabe führen, sind Wahrnehmungs-Hashes "nah" beieinander, wenn die Eingaben visuell oder auditiv ähnlich sind.

43
Alvis

Ich habe SIFT verwendet, um das gleiche Objekt in verschiedenen Bildern wiederzuerkennen. Es ist wirklich mächtig, aber ziemlich komplex und könnte übertrieben sein. Wenn die Bilder ziemlich ähnlich sein sollen, können einige einfache Parameter, die auf dem Unterschied zwischen den beiden Bildern basieren, Ihnen einiges sagen. Einige Hinweise:

  • Normalisieren Sie die Bilder, dh stellen Sie die durchschnittliche Helligkeit beider Bilder gleich ein, indem Sie die durchschnittliche Helligkeit beider Bilder berechnen und die hellste entsprechend der Ration verkleinern (um ein Beschneiden auf der höchsten Ebene zu vermeiden), insbesondere wenn Sie mehr an Form als an Form interessiert sind Farbe.
  • Summe der Farbunterschiede zum normalisierten Bild pro Kanal.
  • finden Sie Kanten in den Bildern und messen Sie den Abstand zwischen den Kantenpixeln in beiden Bildern. (für Form)
  • Teilen Sie die Bilder in mehrere separate Regionen auf und vergleichen Sie die durchschnittliche Farbe jeder Region.
  • Setzen Sie einen Schwellenwert für die Bilder auf einer (oder mehreren) Ebene (n) und zählen Sie die Anzahl der Pixel, bei denen sich die resultierenden Schwarzweißbilder unterscheiden.
12
jilles de wit

Sie könnten Perceptual Image Diff verwenden

Es ist ein Befehlszeilenprogramm, das zwei Bilder anhand einer Wahrnehmungsmetrik vergleicht. Das heißt, es wird ein Rechenmodell des menschlichen visuellen Systems verwendet, um zu bestimmen, ob zwei Bilder visuell unterschiedlich sind, sodass geringfügige Änderungen der Pixel ignoriert werden. Außerdem wird die Anzahl der Fehlalarme, die durch Unterschiede bei der Zufallsgenerierung, dem Betriebssystem oder der Maschinenarchitektur verursacht werden, drastisch reduziert.

5

Mein Labor musste auch dieses Problem lösen, und wir verwendeten Tensorflow. Hier ist eine vollständige App Implementierung zur Visualisierung der Bildähnlichkeit.

Ein Tutorial zum Vektorisieren von Bildern für die Ähnlichkeitsberechnung finden Sie unter diese Seite . Hier ist das Python (den vollständigen Workflow finden Sie im Beitrag):

from __future__ import absolute_import, division, print_function

"""

This is a modification of the classify_images.py
script in Tensorflow. The original script produces
string labels for input images (e.g. you input a picture
of a cat and the script returns the string "cat"); this
modification reads in a directory of images and 
generates a vector representation of the image using
the penultimate layer of neural network weights.

Usage: python classify_images.py "../image_dir/*.jpg"

"""

# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.Apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================

"""Simple image classification with Inception.

Run image classification with Inception trained on ImageNet 2012 Challenge data
set.

This program creates a graph from a saved GraphDef protocol buffer,
and runs inference on an input JPEG image. It outputs human readable
strings of the top 5 predictions along with their probabilities.

Change the --image_file argument to any jpg image to compute a
classification of that image.

Please see the tutorial and website for a detailed description of how
to use this script to perform image recognition.

https://tensorflow.org/tutorials/image_recognition/
"""

import os.path
import re
import sys
import tarfile
import glob
import json
import psutil
from collections import defaultdict
import numpy as np
from six.moves import urllib
import tensorflow as tf

FLAGS = tf.app.flags.FLAGS

# classify_image_graph_def.pb:
#   Binary representation of the GraphDef protocol buffer.
# imagenet_synset_to_human_label_map.txt:
#   Map from synset ID to a human readable string.
# imagenet_2012_challenge_label_map_proto.pbtxt:
#   Text representation of a protocol buffer mapping a label to synset ID.
tf.app.flags.DEFINE_string(
    'model_dir', '/tmp/imagenet',
    """Path to classify_image_graph_def.pb, """
    """imagenet_synset_to_human_label_map.txt, and """
    """imagenet_2012_challenge_label_map_proto.pbtxt.""")
tf.app.flags.DEFINE_string('image_file', '',
                           """Absolute path to image file.""")
tf.app.flags.DEFINE_integer('num_top_predictions', 5,
                            """Display this many predictions.""")

# pylint: disable=line-too-long
DATA_URL = 'http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz'
# pylint: enable=line-too-long


class NodeLookup(object):
  """Converts integer node ID's to human readable labels."""

  def __init__(self,
               label_lookup_path=None,
               uid_lookup_path=None):
    if not label_lookup_path:
      label_lookup_path = os.path.join(
          FLAGS.model_dir, 'imagenet_2012_challenge_label_map_proto.pbtxt')
    if not uid_lookup_path:
      uid_lookup_path = os.path.join(
          FLAGS.model_dir, 'imagenet_synset_to_human_label_map.txt')
    self.node_lookup = self.load(label_lookup_path, uid_lookup_path)

  def load(self, label_lookup_path, uid_lookup_path):
    """Loads a human readable English name for each softmax node.

    Args:
      label_lookup_path: string UID to integer node ID.
      uid_lookup_path: string UID to human-readable string.

    Returns:
      dict from integer node ID to human-readable string.
    """
    if not tf.gfile.Exists(uid_lookup_path):
      tf.logging.fatal('File does not exist %s', uid_lookup_path)
    if not tf.gfile.Exists(label_lookup_path):
      tf.logging.fatal('File does not exist %s', label_lookup_path)

    # Loads mapping from string UID to human-readable string
    proto_as_ascii_lines = tf.gfile.GFile(uid_lookup_path).readlines()
    uid_to_human = {}
    p = re.compile(r'[n\d]*[ \S,]*')
    for line in proto_as_ascii_lines:
      parsed_items = p.findall(line)
      uid = parsed_items[0]
      human_string = parsed_items[2]
      uid_to_human[uid] = human_string

    # Loads mapping from string UID to integer node ID.
    node_id_to_uid = {}
    proto_as_ascii = tf.gfile.GFile(label_lookup_path).readlines()
    for line in proto_as_ascii:
      if line.startswith('  target_class:'):
        target_class = int(line.split(': ')[1])
      if line.startswith('  target_class_string:'):
        target_class_string = line.split(': ')[1]
        node_id_to_uid[target_class] = target_class_string[1:-2]

    # Loads the final mapping of integer node ID to human-readable string
    node_id_to_name = {}
    for key, val in node_id_to_uid.items():
      if val not in uid_to_human:
        tf.logging.fatal('Failed to locate: %s', val)
      name = uid_to_human[val]
      node_id_to_name[key] = name

    return node_id_to_name

  def id_to_string(self, node_id):
    if node_id not in self.node_lookup:
      return ''
    return self.node_lookup[node_id]


def create_graph():
  """Creates a graph from saved GraphDef file and returns a saver."""
  # Creates graph from saved graph_def.pb.
  with tf.gfile.FastGFile(os.path.join(
      FLAGS.model_dir, 'classify_image_graph_def.pb'), 'rb') as f:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())
    _ = tf.import_graph_def(graph_def, name='')


def run_inference_on_images(image_list, output_dir):
  """Runs inference on an image list.

  Args:
    image_list: a list of images.
    output_dir: the directory in which image vectors will be saved

  Returns:
    image_to_labels: a dictionary with image file keys and predicted
      text label values
  """
  image_to_labels = defaultdict(list)

  create_graph()

  with tf.Session() as sess:
    # Some useful tensors:
    # 'softmax:0': A tensor containing the normalized prediction across
    #   1000 labels.
    # 'pool_3:0': A tensor containing the next-to-last layer containing 2048
    #   float description of the image.
    # 'DecodeJpeg/contents:0': A tensor containing a string providing JPEG
    #   encoding of the image.
    # Runs the softmax tensor by feeding the image_data as input to the graph.
    softmax_tensor = sess.graph.get_tensor_by_name('softmax:0')

    for image_index, image in enumerate(image_list):
      try:
        print("parsing", image_index, image, "\n")
        if not tf.gfile.Exists(image):
          tf.logging.fatal('File does not exist %s', image)

        with tf.gfile.FastGFile(image, 'rb') as f:
          image_data =  f.read()

          predictions = sess.run(softmax_tensor,
                          {'DecodeJpeg/contents:0': image_data})

          predictions = np.squeeze(predictions)

          ###
          # Get penultimate layer weights
          ###

          feature_tensor = sess.graph.get_tensor_by_name('pool_3:0')
          feature_set = sess.run(feature_tensor,
                          {'DecodeJpeg/contents:0': image_data})
          feature_vector = np.squeeze(feature_set)        
          outfile_name = os.path.basename(image) + ".npz"
          out_path = os.path.join(output_dir, outfile_name)
          np.savetxt(out_path, feature_vector, delimiter=',')

          # Creates node ID --> English string lookup.
          node_lookup = NodeLookup()

          top_k = predictions.argsort()[-FLAGS.num_top_predictions:][::-1]
          for node_id in top_k:
            human_string = node_lookup.id_to_string(node_id)
            score = predictions[node_id]
            print("results for", image)
            print('%s (score = %.5f)' % (human_string, score))
            print("\n")

            image_to_labels[image].append(
              {
                "labels": human_string,
                "score": str(score)
              }
            )

        # close the open file handlers
        proc = psutil.Process()
        open_files = proc.open_files()

        for open_file in open_files:
          file_handler = getattr(open_file, "fd")
          os.close(file_handler)
      except:
        print('could not process image index',image_index,'image', image)

  return image_to_labels


def maybe_download_and_extract():
  """Download and extract model tar file."""
  dest_directory = FLAGS.model_dir
  if not os.path.exists(dest_directory):
    os.makedirs(dest_directory)
  filename = DATA_URL.split('/')[-1]
  filepath = os.path.join(dest_directory, filename)
  if not os.path.exists(filepath):
    def _progress(count, block_size, total_size):
      sys.stdout.write('\r>> Downloading %s %.1f%%' % (
          filename, float(count * block_size) / float(total_size) * 100.0))
      sys.stdout.flush()
    filepath, _ = urllib.request.urlretrieve(DATA_URL, filepath, _progress)
    print()
    statinfo = os.stat(filepath)
    print('Succesfully downloaded', filename, statinfo.st_size, 'bytes.')
  tarfile.open(filepath, 'r:gz').extractall(dest_directory)


def main(_):
  maybe_download_and_extract()
  if len(sys.argv) < 2:
    print("please provide a glob path to one or more images, e.g.")
    print("python classify_image_modified.py '../cats/*.jpg'")
    sys.exit()

  else:
    output_dir = "image_vectors"
    if not os.path.exists(output_dir):
      os.makedirs(output_dir)

    images = glob.glob(sys.argv[1])
    image_to_labels = run_inference_on_images(images, output_dir)

    with open("image_to_labels.json", "w") as img_to_labels_out:
      json.dump(image_to_labels, img_to_labels_out)

    print("all done")
if __== '__main__':
  tf.app.run()
5
duhaime

Es ist ein schwieriges Problem! Dies hängt davon ab, wie genau Sie arbeiten müssen und mit welchen Bildern Sie arbeiten. Sie können Histogramme zum Vergleichen von Farben verwenden, dies berücksichtigt jedoch offensichtlich nicht die räumliche Verteilung dieser Farben innerhalb der Bilder (d. H. Der Formen). Kantenerkennung, gefolgt von einer Art Segmentierung (d. H. Auswählen der Formen), kann ein Muster zum Abgleichen mit einem anderen Bild liefern. Sie können Coocurence-Matrizen zum Vergleichen von Texturen verwenden, indem Sie die Bilder als Matrizen von Pixelwerten betrachten und diese Matrizen vergleichen. Es gibt einige gute Bücher über Bildanpassung und Bildverarbeitung - Eine Suche bei Amazon wird einige finden.

Hoffe das hilft!

4
Ben

Einige Bilderkennungssoftwarelösungen basieren nicht ausschließlich auf Algorithmen, sondern verwenden stattdessen das Konzept eines neuronalen Netzwerks . Check out http://en.wikipedia.org/wiki/Artificial_neural_network und zwar NeuronDotNet, das auch interessante Beispiele enthält: http://neurondotnet.freehostia.com/index.html =

3
petr k.

Es gibt verwandte Forschungen unter Verwendung von neuronalen Netzen/selbstorganisierenden Karten von Kohonen

Sowohl mehr akademische Systeme (Google für PicSOM) oder weniger akademisch
( http://www.generation5.org/content/2004/aiSomPic.asp (möglicherweise nicht für alle Arbeitsumgebungen geeignet)) Präsentationen vorhanden.

3
EPa

Die Berechnung der Summe der Quadrate der Unterschiede der Pixelfarbwerte einer drastisch verkleinerten Version (z. B. 6x6 Pixel) funktioniert gut. Identische Bilder ergeben 0, ähnliche Bilder ergeben kleine Zahlen, unterschiedliche Bilder ergeben große.

Die Idee der anderen oben genannten Typen, in YUV einzubrechen, klingt zunächst faszinierend - während meine Idee großartig funktioniert, möchte ich, dass meine Bilder als "anders" berechnet werden, damit sie ein korrektes Ergebnis liefern - auch aus der Sicht eines farbenblinden Beobachters.

3
chris

Das klingt nach einem Sehproblem. Möglicherweise möchten Sie sich mit Adaptive Boosting und dem Algorithmus zur Extraktion von Verbrennungslinien befassen. Die Konzepte in diesen beiden sollen helfen, dieses Problem anzugehen. Die Kantenerkennung ist ein noch einfacherer Einstieg, wenn Sie mit Bildverarbeitungsalgorithmen noch nicht vertraut sind, da hier die Grundlagen erläutert werden.

So weit Parameter für die Kategorisierung:

  • Farbpalette & Position (Verlaufsberechnung, Histogramm der Farben)
  • Enthaltene Formen (Ada. Boosting/Training zum Erkennen von Formen)
2
willasaywhat

Je nachdem, wie genaue Ergebnisse Sie benötigen, können Sie die Bilder einfach in n x n Pixelblöcke aufteilen und analysieren. Wenn Sie im ersten Block unterschiedliche Ergebnisse erhalten, können Sie die Verarbeitung nicht stoppen, was zu einigen Leistungsverbesserungen führt.

Zur Analyse der Quadrate können Sie beispielsweise die Summe der Farbwerte erhalten.

2
JValente

Entschuldigung für die späte Teilnahme an der Diskussion.

Wir können sogar die ORB-Methode verwenden, um ähnliche Merkmalspunkte zwischen zwei Bildern zu erkennen. Der folgende Link zeigt die direkte Implementierung von ORB in Python

http://scikit-image.org/docs/dev/auto_examples/plot_orb.html

Auch openCV hat ORB direkt implementiert. Wenn Sie weitere Informationen wünschen, folgen Sie dem unten angegebenen Artikel.

https://www.researchgate.net/publication/292157133_Image_Matching_Using_SIFT_SURF_BRIEF_and_ORB_Performance_Comparison_for_Distorted_Images

1

Ich fand diesen Artikel sehr hilfreich, um zu erklären, wie es funktioniert:

http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html

1
andi

Sie könnten eine Art Blockanpassungs-Bewegungsschätzung zwischen den beiden Bildern durchführen und die Gesamtsumme der Residuen und der Bewegungsvektorkosten messen (ähnlich wie bei einem Video-Encoder). Dies würde die Bewegung kompensieren; Führen Sie für Bonuspunkte eine Affintransformations-Bewegungsschätzung durch (gleicht Zooms und Dehnungen und ähnliches aus). Sie können auch überlappende Blöcke oder einen optischen Fluss ausführen.

1
Dark Shikari

In einem ersten Durchgang können Sie versuchen, Farbhistogramme zu verwenden. Sie müssen jedoch Ihre Problemdomäne wirklich eingrenzen. Die generische Bildanpassung ist ein sehr schweres Problem.

1
Dima

Es gibt einige gute Antworten im anderen Thread dazu, aber ich frage mich, ob etwas mit einer Spektralanalyse funktionieren würde. Zerlegen Sie das Bild in Phasen- und Amplitudeninformationen und vergleichen Sie diese. Dies kann einige Probleme mit Zuschneiden, Transformation und Intensitätsunterschieden vermeiden. Jedenfalls spekuliere ich nur, da dies ein interessantes Problem zu sein scheint. Wenn Sie suchten http://scholar.google.com Ich bin sicher, Sie könnten sich mehrere Artikel zu diesem Thema einfallen lassen.

0
dbrien