it-swarm-ko.tech

유사한 이미지를 찾기위한 알고리즘

두 개의 이미지가 '유사한 지'여부를 결정하고 유사한 색상, 밝기, 모양 등의 패턴을 인식 할 수있는 알고리즘이 필요합니다. 인간의 두뇌가 이미지를 '카테고리 화'하는 데 사용하는 매개 변수에 대한 포인터가 필요할 수 있습니다. ..

나는 hausdorff 기반의 매칭을 보았지만 주로 변형 된 객체와 모양의 패턴을 일치시키는 것으로 보입니다.

76
kitsune

wavelet transform 을 사용하여 이미지를 서명으로 분해하여 비슷한 작업을 수행했습니다.

내 접근 방식은 변환 된 각 채널에서 가장 중요한 n 계수를 선택하고 해당 위치를 기록하는 것이 었습니다. 이것은 abs (power)에 따라 (power, location) 튜플 목록을 정렬하여 수행되었습니다. 비슷한 이미지는 같은 장소에서 중요한 계수를 갖기 때문에 유사성을 공유합니다.

이미지에서 YUV 형식으로 변환하는 것이 가장 좋으며 모양 (Y 채널)과 색상 (UV 채널)의 가중치 유사성을 효과적으로 허용합니다.

mactorii 에서 위의 구현을 찾을 수 있습니다. 불행히도 :-)만큼 노력하지 않았습니다.

내 친구들이 놀랍게도 좋은 결과를 낸 또 다른 방법은 단순히 이미지 크기를 4x4 픽셀로 줄이고 이미지를 저장하는 것입니다. 해당 픽셀을 사용하여 두 이미지 사이의 Manhattan distance 를 계산하여 유사한 2 개의 이미지를 얼마나 정확하게 채점 할 수 있습니까? 크기 조정을 수행 한 방법에 대한 세부 정보가 없으므로 해당 작업에 적합한 다양한 알고리즘을 사용하여 적절한 알고리즘을 찾아야 할 수도 있습니다.

55
freespace

pHash 관심이 있으실 것입니다.

지각 해시 n. 오디오, 비디오 또는 이미지 파일의 지문으로, 그 안에 포함 된 오디오 또는 시각적 컨텐츠를 수학적으로 기반으로합니다. 출력의 급격한 변화로 이어지는 입력의 작은 변화의 눈사태 효과에 의존하는 암호화 해시 함수와 달리, 입력이 시각적으로 또는 청각 적으로 유사한 경우 지각 해시는 서로 "가까이"있습니다.

43
Alvis

SIFT 를 사용하여 다른 이미지에서 동일한 물체를 다시 감지했습니다. 실제로 강력하지만 다소 복잡하며 과도 할 수 있습니다. 이미지가 매우 유사하다고 가정하면 두 이미지의 차이를 기반으로 한 간단한 매개 변수가 상당히 알 수 있습니다. 일부 포인터 :

  • 이미지를 정규화합니다. 예를 들어 특히 색깔.
  • 채널당 정규화 된 이미지와 색상 차이의 합입니다.
  • 이미지에서 가장자리를 찾고 두 이미지에서 가장자리 픽셀 사이의 거리를 측정합니다. (형상 용)
  • 이미지를 일련의 개별 영역으로 나누고 각 영역의 평균 색상을 비교하십시오.
  • 이미지를 한 수준 (또는 일련의 수준)으로 임계 값으로 만들고 결과 흑백 이미지가 다른 픽셀 수를 계산합니다.
12
jilles de wit

지각 적 이미지 차이

지각 메트릭을 사용하여 두 이미지를 비교하는 명령 줄 유틸리티입니다. 즉, 인간 시각 시스템의 계산 모델을 사용하여 두 이미지가 시각적으로 다른지 여부를 결정하므로 픽셀의 사소한 변경은 무시됩니다. 또한 난수 생성, OS 또는 시스템 아키텍처 차이의 차이로 인한 오 탐지 수를 크게 줄입니다.

5
Alejandro Bologna

실험실에서도이 문제를 해결해야했고 Tensorflow를 사용했습니다. 다음은 이미지 유사성을 시각화하기위한 full app 구현입니다.

유사도 계산을 위해 이미지를 벡터화하는 방법에 대한 자습서는 this page 를 참조하십시오. 다음은 Python입니다 (다시 말하면 전체 워크 플로에 대한 게시물 참조).

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

어려운 문제입니다! 그것은 얼마나 정확한가에 달려 있으며, 어떤 종류의 이미지로 작업하고 있는지에 달려 있습니다. 히스토그램을 사용하여 색상을 비교할 수 있지만 이미지 내에서 해당 색상의 공간 분포 (예 : 모양)를 고려하지는 않습니다. 가장자리 감지 다음에 일종의 분할 (예 : 도형 선택)이 다른 이미지와 일치하는 패턴을 제공 할 수 있습니다. coocurence 행렬을 사용하여 이미지를 픽셀 값의 행렬로 간주하고 해당 행렬을 비교하여 텍스처를 비교할 수 있습니다. 이미지 매칭과 머신 비전에 관한 좋은 책이 있습니다. 아마존을 검색하면 찾을 수 있습니다.

도움이 되었기를 바랍니다!

4
Ben

일부 이미지 인식 소프트웨어 솔루션은 실제로 순수 알고리즘 기반은 아니지만 대신 neural network 개념을 사용합니다. http://en.wikipedia.org/wiki/Artificial_neural_network 및 흥미로운 샘플을 포함하는 NeuronDotNet을 확인하십시오. http://neurondotnet.freehostia.com/index.html =

3
petr k.

Kohonen 신경망/자체 구성지도를 사용한 관련 연구가 있습니다

더 많은 아카데믹 시스템 (Google for PicSOM) 또는 더 적은 아카데믹
( http://www.generation5.org/content/2004/aiSomPic.asp , (일부 작업 환경에 적합하지 않을 수 있음)) 프레젠테이션이 있습니다.

3
EPa

크게 축소 된 버전 (예 : 6x6 픽셀)의 픽셀 색상 값 차이의 제곱의 합을 계산하면 효과적입니다. 동일한 이미지는 0을 생성하고 유사한 이미지는 작은 숫자를 생성하고 다른 이미지는 큰 이미지를 생성합니다.

위의 다른 사람들은 YUV 첫 소리에 흥미를 느끼는 아이디어를 얻었습니다. 제 아이디어는 훌륭하지만, 이미지가 "다른"것으로 계산되어 컬러 블라인드 옵저버의 관점에서도 올바른 결과를 얻을 수 있기를 바랍니다.

3
chris

이것은 시력 문제처럼 들립니다. Burns Line Extraction 알고리즘뿐만 아니라 Adaptive Boosting도 살펴볼 수 있습니다. 이 두 가지 개념은이 문제에 접근하는 데 도움이됩니다. 엣지 감지는 기본 알고리즘을 설명하는 비전 알고리즘을 처음 사용하는 경우 시작하기에 훨씬 간단한 장소입니다.

분류를위한 매개 변수까지 :

  • 색상 팔레트 및 위치 (그라디언트 계산, 색상 히스토그램)
  • 포함 된 모양 (Ada. Boosting/Training)
2
willasaywhat

필요한 정확한 결과에 따라 이미지를 n x n 픽셀 블록으로 나누고 분석 할 수 있습니다. 첫 번째 블록에서 다른 결과를 얻는 경우 처리를 중지 할 수 없으므로 성능이 약간 향상됩니다.

사각형을 분석하기 위해 예를 들어 색상 값의 합계를 얻을 수 있습니다.

2
JValente

토론 후반에 참여한 것에 대해 사과드립니다.

ORB 방법론을 사용하여 두 이미지 사이의 유사한 특징점을 감지 할 수도 있습니다. 다음 링크는 파이썬에서 ORB를 직접 구현합니다.

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

OpenCV조차도 ORB를 직접 구현했습니다. 자세한 내용은 아래의 연구 기사를 따르십시오.

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

1
Vivek Srinivasan

이 기사가 어떻게 작동하는지 설명하는 데 매우 도움이되었습니다.

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

1
andi

두 이미지 사이에 일종의 블록 매칭 모션 추정을 수행하고 비디오 엔코더에서와 같이 잔차 및 모션 벡터 비용의 총합을 측정 할 수 있습니다. 이것은 움직임을 보상합니다. 보너스 포인트의 경우 아핀 변환 모션 추정을 수행합니다 (확대 및 스트레칭 등을 보상합니다). 겹치는 블록이나 광학 흐름을 수행 할 수도 있습니다.

1
Dark Shikari

첫 번째 단계로 컬러 히스토그램을 사용해 볼 수 있습니다. 그러나 문제 영역을 좁혀 야합니다. 일반 이미지 일치는 매우 어려운 문제입니다.

1
Dima

이것에 대한 다른 스레드에는 좋은 대답이 있지만 스펙트럼 분석과 관련된 것이 효과가 있는지 궁금합니다. 즉, 이미지를 위상 및 진폭 정보로 분류하고 비교하십시오. 자르기, 변형 및 강도 차이와 관련된 문제를 피할 수 있습니다. 어쨌든, 이것은 흥미로운 문제처럼 보이기 때문에 단지 추측입니다. http://scholar.google.com 을 검색 한 경우 여기에 몇 가지 논문을 제시 할 수있을 것입니다.

0
dbrien