무한 이미지를 찾기위한 알고리즘
두 이미지가 '유사한 지'여인지 판단하고 패턴의 색상, 밝기, 모양 등을 인식 할 수있는 알고리즘이 필요합니다. 인간의 뇌가 이미지를 '분류'하기 위해 사용하는 변수에 대한 포인터가 필요할 수 있습니다. ..
hausdorff 기반 매칭을 보면 봤지만 주로 변형 된 형태와 모양의 패턴을 매칭하는 것입니다.
wavelet transform을 사용하여 이미지를 서명으로 분해하여 작업을 수행했습니다 .
내 접근 방식은 변환 된 각 채널 에서 가장 중요한 n 개의 계수 를 선택 하고 위치를 기록하는 것이 었습니다. abs (힘)에 따라 (힘, 위치) 튜플 목록을 정렬하여 수행합니다. 동일한 이미지는 동일한 장소에서 중요한 계수를 말하는 점에서 유사성을 공유합니다.
이미지를 YUV 형식으로 변환하는 것이 가장 좋습니다. 이렇게하면 모양 (Y 채널)과 색상 (UV 채널)의 유사성을 적용 할 수 있습니다.
mactorii 에서 위의 구현을 사용할 수 있습니다. 안타깝게도 내가 가져야 할만 큼 많이 작업하지 않습니다. :-)
제 친구들이 놀랍도록 좋은 결과를내는 또 다른 방법은 이미지 크기와 당신의 인 저장소를 만드는 것입니다. 픽셀을 사용하여 두 이미지 사이의 맨해튼 거리 를 계산하여 두 이미지가 얼마나 일치하는지 점수를 매길 수 있습니다 . 크기 조정을 수행 한 방법에 대한 세부 정보가있는 해당 작업에 사용할 수있는 다양한 알고리즘을 사용하여 알고리즘을 찾아야 할 수 있습니다.
pHash 가 관심을 가질 수 있습니다.
지각 해시 n. 포함 된 오디오 또는 오디오 콘텐츠를 수학적으로 기반으로하는 오디오, 비디오 또는 이미지 파일의 지문. 입력의 작은 변화로 인한 눈사태 효과에 의존하여 출력의 급격한 변화에 의존하는 암호화 해시 함수와 달리, 입력이로 또는 청각 적으로도 경우 지각 해시는 서로 "가이"있습니다.
SIFT 를 사용 하여 다시 감지했습니다. 정말 강력하지만 다소 복잡하고 과잉 일 수 있습니다. 이미지가 매우 유사해야한다면 두 가지 이미지의 차이를 기반으로 한 몇 가지 간단한 것을 통해 많은 것을 알 수 있습니다. 몇 가지 지침 :
- 이미지를 정규화합니다. 즉, 두 이미지의 평균 밝기를 계산하고 비율에 따라 가장 밝게 조정하여 두 이미지의 평균 밝기를 동일하게 만듭니다 (최고 수준에서 수준을 방지하기 위해). 특히 모양에 더 관심이있는 경우 색깔.
- 채널당 정규화 된 이미지에 대한 색상 차이의 전체입니다.
- 이미지에서 가장자리를 찾고 두 이미지에서 가장자리 픽셀 사이의 거리를 측정합니다. (모양 용)
- 이미지를 불연속 영역 세트로 나누고 각 영역의 평균 색상을 비교합니다.
- 하나 (또는 세트) 수준에서 이미지를 임계 값으로 설정하고 결과 흑백 이미지가 다른 픽셀 수를 계산합니다.
Perceptual Image Diff를 사용할 수 있습니다.
두 이미지를 비교하는 명령 줄 유틸리티입니다. 즉, 인간 시각 시스템의 계산 모델을 사용하여 두 이미지가 사소한 것으로 변경됩니다. 또한 난수 생성, OS 또는 시스템 아키텍처 차이의 차이로 발생하는 오 탐지 수를 대폭 줄입니다.
제 연구실 도이 문제를 해결해야하고 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()
어려운 문제입니다! 얼마나 정확해야하는지에 따라 다르며 작업중인 이미지의 종류에 따라 다릅니다. 히스토그램을 사용하여 색상을 비교할 수 있지만 이미지 내에서 해당 색상의 공간적 분포 (즉, 모양)를 고려하지 않은 것은 분명합니다. 가장자리 감지에 이어 어떤 종류의 분할 (즉, 모양 선택)이 다른 이미지와 일치하는 패턴을 제공 할 수 있습니다. 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 , (모든 작업 환경에 적합하지 않을 수 있음)) 프레젠테이션이 모두 존재합니다.
대폭 축소 된 버전 (예 : 6x6 픽셀)의 픽셀 색상 값 차이 제곱의 합을 계산하는 것은 잘 작동합니다. 동일한 이미지는 0, 비슷한 이미지는 작은 수를, 다른 이미지는 큰 이미지를 생성합니다.
위의 다른 사람들이 먼저 YUV에 침입하려는 아이디어는 흥미로워 들립니다. 제 아이디어는 훌륭하게 작동하지만 색맹 관찰자의 관점에서도 올바른 결과를 얻을 수 있도록 내 이미지가 "다른"것으로 계산되기를 바랍니다.
이것은 시력 문제처럼 들립니다. Burns Line Extraction 알고리즘뿐만 아니라 Adaptive Boosting을 살펴볼 수 있습니다. 이 두 개념은이 문제에 접근하는 데 도움이 될 것입니다. 에지 감지는 비전 알고리즘을 처음 접하는 경우 기본 사항을 설명하므로 시작하기 훨씬 더 간단한 곳입니다.
범주화를위한 매개 변수 :
- 색상 팔레트 및 위치 (그라데이션 계산, 색상 히스토그램)
- 포함 된 도형 (Ada. 부스팅 / 형상 감지 훈련)
얼마나 정확한 결과가 필요한지에 따라 이미지를 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 을 검색했다면 이에 대한 몇 가지 논문을 생각해 낼 수있을 것입니다.
참고 URL : https://stackoverflow.com/questions/75891/algorithm-for-finding-similar-images
'ProgramingTip' 카테고리의 다른 글
이니셜 라이저는 비 정적 필드, 메서드 또는 속성을 참조 할 수 없습니다. (0) | 2020.10.14 |
---|---|
Babel 6.x에서 기본 내보내기 값을 필요로합니다. (0) | 2020.10.14 |
Selenium RC로 Google 크롬을 실행하는 방법은 무엇입니까? (0) | 2020.10.14 |
'diff'(또는 기타)를 사용하여 텍스트 파일 보관 문자 수준 차이 가져 오기 오기 (0) | 2020.10.14 |
헤드리스 Linux의 "android update sdk" (0) | 2020.10.14 |