두 이미지가 '유사한 지'여부를 판단하고 비슷한 패턴의 색상, 밝기, 모양 등을 인식 할 수있는 알고리즘이 필요합니다. 인간의 뇌가 이미지를 '분류'하기 위해 사용하는 매개 변수에 대한 포인터가 필요할 수 있습니다. ..
hausdorff 기반 매칭을 살펴 봤지만 주로 변형 된 물체와 모양의 패턴을 매칭하는 것 같습니다.
두 이미지가 '유사한 지'여부를 판단하고 비슷한 패턴의 색상, 밝기, 모양 등을 인식 할 수있는 알고리즘이 필요합니다. 인간의 뇌가 이미지를 '분류'하기 위해 사용하는 매개 변수에 대한 포인터가 필요할 수 있습니다. ..
hausdorff 기반 매칭을 살펴 봤지만 주로 변형 된 물체와 모양의 패턴을 매칭하는 것 같습니다.
답변:
wavelet transform을 사용하여 이미지를 서명으로 분해하여 비슷한 작업을 수행했습니다 .
내 접근 방식은 변환 된 각 채널에서 가장 중요한 n 개의 계수 를 선택 하고 위치를 기록하는 것이 었습니다. 이것은 abs (power)에 따라 (power, location) 튜플 목록을 정렬하여 수행되었습니다. 유사한 이미지는 동일한 장소에서 중요한 계수를 갖는다는 점에서 유사성을 공유합니다.
이미지를 YUV 형식으로 변환하는 것이 가장 좋다는 것을 알았습니다. 이렇게하면 모양 (Y 채널)과 색상 (UV 채널)에서 가중치 유사성을 효과적으로 사용할 수 있습니다.
mactorii 에서 위의 구현을 찾을 수 있습니다. 안타깝게도 내가 가져야 할만큼 작업하지 않았습니다. :-)
제 친구들이 놀라 울 정도로 좋은 결과를내는 또 다른 방법은 단순히 이미지 크기를 줄여서 4x4 픽셀과 당신의 서명 인 저장소를 만드는 것입니다. 두 이미지 사이의 맨해튼 거리 를 해당 픽셀을 사용하여 계산하여 두 이미지가 얼마나 유사한 지 점수를 매길 수 있습니다 . 크기 조정을 수행 한 방법에 대한 세부 정보가 없으므로 해당 작업에 사용할 수있는 다양한 알고리즘을 사용하여 적합한 알고리즘을 찾아야 할 수 있습니다.
pHash 가 관심을 가질 수 있습니다.
지각 해시 n. 포함 된 오디오 또는 시각적 콘텐츠를 수학적으로 기반으로하는 오디오, 비디오 또는 이미지 파일의 지문. 입력의 작은 변화로 인한 눈사태 효과에 의존하여 출력의 급격한 변화에 의존하는 암호화 해시 함수와 달리, 입력이 시각적으로 또는 청각 적으로 유사한 경우 지각 해시는 서로 "가까이"있습니다.
SIFT 를 사용 하여 다른 이미지에서 동일한 물체를 다시 감지했습니다. 정말 강력하지만 다소 복잡하고 과잉 일 수 있습니다. 이미지가 매우 유사해야한다면 두 이미지의 차이를 기반으로 한 몇 가지 간단한 매개 변수를 통해 꽤 많은 것을 알 수 있습니다. 몇 가지 지침 :
제 연구실에서도이 문제를 해결해야했고 Tensorflow를 사용했습니다. 다음은 이미지 유사성을 시각화하기위한 전체 앱 구현입니다.
유사성 계산을위한 이미지 벡터화에 대한 자습서는 이 페이지를 확인 하십시오 . 다음은 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 __name__ == '__main__':
tf.app.run()
Perceptual Image Diff를 사용할 수 있습니다.
지각 메트릭을 사용하여 두 이미지를 비교하는 명령 줄 유틸리티입니다. 즉, 인간 시각 시스템의 계산 모델을 사용하여 두 이미지가 시각적으로 다른지 확인하므로 픽셀의 사소한 변경은 무시됩니다. 또한 난수 생성, OS 또는 시스템 아키텍처 차이의 차이로 인해 발생하는 오 탐지 수를 대폭 줄입니다.
어려운 문제입니다! 얼마나 정확해야하는지에 따라 다르며 작업중인 이미지의 종류에 따라 다릅니다. 히스토그램을 사용하여 색상을 비교할 수 있지만 이미지 내에서 해당 색상의 공간적 분포 (즉, 모양)를 고려하지 않은 것은 분명합니다. 가장자리 감지에 이어 어떤 종류의 분할 (즉, 모양 선택)이 다른 이미지와 일치하는 패턴을 제공 할 수 있습니다. coocurence 행렬을 사용하여 이미지를 픽셀 값의 행렬로 간주하고 해당 행렬을 비교하여 텍스처를 비교할 수 있습니다. 이미지 매칭과 머신 비전에 대한 좋은 책이 있습니다. Amazon에서 검색하면 일부를 찾을 수 있습니다.
도움이 되었기를 바랍니다!
일부 이미지 인식 소프트웨어 솔루션은 실제로 순수 알고리즘 기반이 아니지만 대신 신경망 개념을 사용합니다. http://en.wikipedia.org/wiki/Artificial_neural_network 및 흥미로운 샘플도 포함 된 NeuronDotNet을 확인하십시오 . http://neurondotnet.freehostia.com/index.html
코호 넨 신경망 / 자체 구성지도를 사용한 관련 연구가 있습니다.
더 많은 학술 시스템 (Google for PicSOM) 또는 덜 학술적
( http://www.generation5.org/content/2004/aiSomPic.asp , (모든 작업 환경에 적합하지 않을 수 있음)) 프레젠테이션이 모두 존재합니다.
얼마나 정확한 결과가 필요한지에 따라 이미지를 nxn 픽셀 블록으로 나누고 분석 할 수 있습니다. 첫 번째 블록에서 다른 결과를 얻는 경우 처리를 중지 할 수 없으므로 성능이 약간 향상됩니다.
사각형을 분석하기 위해 예를 들어 색상 값의 합계를 얻을 수 있습니다.
이 기사가 어떻게 작동하는지 설명하는 데 매우 유용하다는 것을 알았습니다.
http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html
토론 후반에 참여해 주셔서 죄송합니다.
ORB 방법론을 사용하여 두 이미지 사이의 유사한 특징점을 감지 할 수도 있습니다. 다음 링크는 파이썬에서 ORB를 직접 구현합니다.
http://scikit-image.org/docs/dev/auto_examples/plot_orb.html
openCV조차도 ORB를 직접 구현했습니다. 더 많은 정보가 있다면 아래 주어진 연구 기사를 따르십시오.
이것에 대한 다른 스레드에 좋은 답변이 있지만 스펙트럼 분석과 관련된 것이 작동하는지 궁금합니다. 즉, 이미지를 위상 및 진폭 정보로 나누고 비교합니다. 이렇게하면 자르기, 변형 및 강도 차이와 관련된 일부 문제를 피할 수 있습니다. 어쨌든 이것은 흥미로운 문제처럼 보이기 때문에 추측하고 있습니다. http://scholar.google.com 을 검색 하면 이에 대한 몇 가지 논문이 나올 것입니다.