image processing 편집기 이미지를 이미지 컬렉션에 매치




vb net listview imagelist (4)

나는 카드 이미지의 큰 collecton 및 특정 카드의 한 사진 있습니다. 내 이미지와 가장 유사한 컬렉션 이미지를 찾기 위해 어떤 도구를 사용할 수 있습니까?

다음은 컬렉션 샘플입니다.

여기 내가 찾는 것을 시도하고있다 :


이미지 데이터를 벡터로 배열하고 컬렉션 이미지 벡터와 검색된 이미지 벡터 사이의 내적을 취하여이 작업을 시도했습니다. 가장 유사한 벡터는 가장 높은 내부 제품을 제공합니다. 동일한 크기의 벡터를 얻기 위해 모든 이미지의 크기를 조정하므로 내부 제품을 사용할 수 있습니다. 이 크기 조정은 내부 제품 계산 비용을 추가로 줄이고 실제 이미지의 대략적인 근사값을 제공합니다.

Matlab 또는 Octave를 사용하여이를 빠르게 확인할 수 있습니다. 아래는 Matlab / Octave 스크립트입니다. 거기에 의견을 추가했습니다. 나는 변수 mult 를 1에서 8로 변화 시키려고 노력했다. (정수 값을 시도 할 수있다.) 모든 경우에 대해 이미지 Demystify는 카드 이미지로 가장 높은 내부 제품을 제공했다. mult = 8의 경우 Matlab에서 다음과 같은 ip 벡터를 얻습니다.

ip =

683007892

558305537

604013365

보시다시피, 이미지 Demystify에 대해 683007892의 가장 높은 내부 제품을 제공합니다.

% load images
imCardPhoto = imread('0.png');
imDemystify = imread('1.jpg');
imAggressiveUrge = imread('2.jpg');
imAbundance = imread('3.jpg');

% you can experiment with the size by varying mult
mult = 8;
size = [17 12]*mult;

% resize with nearest neighbor interpolation
smallCardPhoto = imresize(imCardPhoto, size);
smallDemystify = imresize(imDemystify, size);
smallAggressiveUrge = imresize(imAggressiveUrge, size);
smallAbundance = imresize(imAbundance, size);

% image collection: each image is vectorized. if we have n images, this
% will be a (size_rows*size_columns*channels) x n matrix
collection = [double(smallDemystify(:)) ...
    double(smallAggressiveUrge(:)) ...
    double(smallAbundance(:))];

% vectorize searched image. this will be a (size_rows*size_columns*channels) x 1
% vector
x = double(smallCardPhoto(:));

% take the inner product of x and each image vector in collection. this
% will result in a n x 1 vector. the higher the inner product is, more similar the
% image and searched image(that is x)
ip = collection' * x;

편집하다

나는 또 다른 접근법을 시도했다. 기본적으로 참조 이미지와 카드 이미지 사이의 유클리드 거리 (12 표준)를 취해서 테스트 카드 이미지를위한이 링크 에서 찾은 많은 참조 이미지 (383 이미지)로 매우 좋은 결과를 얻었다.

여기에서는 전체 이미지를 촬영하는 대신 이미지가 포함 된 윗부분을 추출하여 비교에 사용했습니다.

다음 단계에서 모든 학습 이미지와 테스트 이미지는 처리를 수행하기 전에 사전 정의 된 크기조정됩니다 .

  • 학습 이미지로부터 이미지 영역 추출
  • 거친 근사값을 얻기 위해이 이미지들에 형태학적인 클로저를 수행하십시오 (이 단계는 필요하지 않을 수도 있음)
  • 이러한 이미지를 벡터화하고 트레이닝 세트에 저장하십시오 (이 방법에서는 트레이닝이 없어도 트레이닝 세트라고합니다)
  • 테스트 카드 이미지로드, 이미지 관심 영역 (ROI) 추출, 닫기 적용, 벡터화
  • 각각의 기준 이미지 벡터와 테스트 이미지 벡터 사이의 유클리드 거리를 계산한다.
  • 최소 거리 항목 (또는 첫 번째 k 항목)을 선택하십시오.

OpenCV를 사용하여 C ++에서이 작업을 수행했습니다. 나는 또한 다른 저울을 사용하여 몇 가지 테스트 결과를 포함하고 있습니다.

#include <opencv2/opencv.hpp>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <windows.h>

using namespace cv;
using namespace std;

#define INPUT_FOLDER_PATH       string("Your test image folder path")
#define TRAIN_IMG_FOLDER_PATH   string("Your training image folder path")

void search()
{
    WIN32_FIND_DATA ffd;
    HANDLE hFind = INVALID_HANDLE_VALUE;

    vector<Mat> images;
    vector<string> labelNames;
    int label = 0;
    double scale = .2;  // you can experiment with scale
    Size imgSize(200*scale, 285*scale); // training sample images are all 200 x 285 (width x height)
    Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(3, 3));

    // get all training samples in the directory
    hFind = FindFirstFile((TRAIN_IMG_FOLDER_PATH + string("*")).c_str(), &ffd);
    if (INVALID_HANDLE_VALUE == hFind) 
    {
        cout << "INVALID_HANDLE_VALUE: " << GetLastError() << endl;
        return;
    } 
    do
    {
        if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
        {
            Mat im = imread(TRAIN_IMG_FOLDER_PATH+string(ffd.cFileName));
            Mat re;
            resize(im, re, imgSize, 0, 0);  // resize the image

            // extract only the upper part that contains the image
            Mat roi = re(Rect(re.cols*.1, re.rows*35/285.0, re.cols*.8, re.rows*125/285.0));
            // get a coarse approximation
            morphologyEx(roi, roi, MORPH_CLOSE, kernel);

            images.push_back(roi.reshape(1)); // vectorize the roi
            labelNames.push_back(string(ffd.cFileName));
        }

    }
    while (FindNextFile(hFind, &ffd) != 0);

    // load the test image, apply the same preprocessing done for training images
    Mat test = imread(INPUT_FOLDER_PATH+string("0.png"));
    Mat re;
    resize(test, re, imgSize, 0, 0);
    Mat roi = re(Rect(re.cols*.1, re.rows*35/285.0, re.cols*.8, re.rows*125/285.0));
    morphologyEx(roi, roi, MORPH_CLOSE, kernel);
    Mat testre = roi.reshape(1);

    struct imgnorm2_t
    {
        string name;
        double norm2;
    };
    vector<imgnorm2_t> imgnorm;
    for (size_t i = 0; i < images.size(); i++)
    {
        imgnorm2_t data = {labelNames[i], 
            norm(images[i], testre) /* take the l2-norm (euclidean distance) */};
        imgnorm.push_back(data); // store data
    }

    // sort stored data based on euclidean-distance in the ascending order
    sort(imgnorm.begin(), imgnorm.end(), 
        [] (imgnorm2_t& first, imgnorm2_t& second) { return (first.norm2 < second.norm2); });
    for (size_t i = 0; i < imgnorm.size(); i++)
    {
        cout << imgnorm[i].name << " : " << imgnorm[i].norm2 << endl;
    }
}

결과 :

scale = 1.0;

demystify.jpg : 10989.6, sylvan_basilisk.jpg : 11990.7, scathe_zombies.jpg : 12307.6

scale = .8;

demystify.jpg : 8572.84, sylvan_basilisk.jpg : 9440.18, steel_golem.jpg : 9445.36

scale = .6;

demystify.jpg : 6226.6, steel_golem.jpg : 6887.96, sylvan_basilisk.jpg : 7013.05

scale = .4;

demystify.jpg : 4185.68, steel_golem.jpg : 4544.64, sylvan_basilisk.jpg : 4699.67

scale = .2;

demystify.jpg : 1903.05, steel_golem.jpg : 2154.64, sylvan_basilisk.jpg : 2277.42


내가 너를 정확하게 이해한다면 너는 그걸 사진으로 비교할 필요가있다. 아주 간단하지만 효과적인 솔루션이 하나 있습니다. Sikuli 입니다.

내 이미지와 가장 유사한 컬렉션 이미지를 찾기 위해 어떤 도구를 사용할 수 있습니까?

이 도구는 이미지 처리에 매우 효과적이며 카드 (이미지)가 이미 패턴으로 정의 된 것과 유사한 지 찾을 수있을뿐만 아니라 부분 이미지 콘텐츠 (소위 직사각형 )를 검색 할 수 있습니다.

기본적으로 Python을 통해 기능을 확장 할 수 있습니다. 모든 ImageObject는 similarity_pattern을 백분율로 허용하도록 설정할 수 있으므로 찾고있는 것을 정확하게 찾을 수 있습니다.

이 도구의 또 다른 큰 이점은 언젠가는 기본을 배울 수 있다는 것입니다.

희망이 도움이됩니다.


또한 다음과 같이 이미지와 카드의 정규화 된 상호 상관을 시도했습니다.

#!/bin/bash
size="300x400!"
convert card.png -colorspace RGB -normalize -resize $size card.jpg
for i in *.jpg
do 
   cc=$(convert $i -colorspace RGB -normalize -resize $size JPG:- | \
   compare - card.jpg -metric NCC null: 2>&1)
   echo "$cc:$i"
done | sort -n

이 출력물을 (일치 품질별로 정렬하여) 얻었습니다.

0.453999:abundance.jpg
0.550696:aggressive.jpg
0.629794:demystify.jpg

카드가 demystify.jpg 와 가장 관련이 있음을 보여줍니다.

모든 이미지의 크기를 같은 크기로 조정하고 대비를 표준화하여 쉽게 비교할 수 있고 대비의 차이로 인한 결과를 최소화 할 수 있습니다. 그것들을 더 작게 만들면 상관 관계에 필요한 시간도 줄어 듭니다.


사진을 게시 해 주셔서 감사합니다.

Neal Krawetz 박사가 발견 한 Perceptual Hashing 알고리즘을 코딩했습니다. 귀하의 이미지를 카드와 비교할 때 다음과 같은 유사성 백분율 측정을 얻습니다.

Card vs. Abundance 79%
Card vs. Aggressive 83%
Card vs. Demystify 85%

그래서, 그것은 당신의 이미지 유형에 대한 이상적인 판별자가 아니지만 다소 일종의 작품입니다. 유스 케이스에 맞추기 위해 주위를 놀고 싶을 수도 있습니다.

한 번에 하나씩 컬렉션의 각 이미지에 대한 해시를 계산하고 각 이미지의 해시를 한 번만 저장합니다. 그런 다음 새 카드를 받으면 해시를 계산하여 저장된 카드와 비교합니다.

#!/bin/bash
################################################################################
# Similarity
# Mark Setchell
#
# Calculate percentage similarity of two images using Perceptual Hashing
# See article by Dr Neal Krawetz entitled "Looks Like It" - www.hackerfactor.com
#
# Method:
# 1) Resize image to black and white 8x8 pixel square regardless
# 2) Calculate mean brightness of those 64 pixels
# 3) For each pixel, store "1" if pixel>mean else store "0" if less than mean
# 4) Convert resulting 64bit string of 1's and 0's, 16 hex digit "Perceptual Hash"
#
# If finding difference between Perceptual Hashes, simply total up number of bits
# that differ between the two strings - this is the Hamming distance.
#
# Requires ImageMagick - www.imagemagick.org
#
# Usage:
#
# Similarity image|imageHash [image|imageHash]
# If you pass one image filename, it will tell you the Perceptual hash as a 16
# character hex string that you may want to store in an alternate stream or as
# an attribute or tag in filesystems that support such things. Do this in order
# to just calculate the hash once for each image.
#
# If you pass in two images, or two hashes, or an image and a hash, it will try
# to compare them and give a percentage similarity between them.
################################################################################
function PerceptualHash(){

   TEMP="tmp$$.png"

   # Force image to 8x8 pixels and greyscale
   convert "$1" -colorspace gray -quality 80 -resize 8x8! PNG8:"$TEMP"

   # Calculate mean brightness and correct to range 0..255
   MEAN=$(convert "$TEMP" -format "%[fx:int(mean*255)]" info:)

   # Now extract all 64 pixels and build string containing "1" where pixel > mean else "0"
   hash=""
   for i in {0..7}; do
      for j in {0..7}; do
         pixel=$(convert "${TEMP}"[1x1+${i}+${j}] -colorspace gray text: | grep -Eo "\(\d+," | tr -d '(,' )
         bit="0"
         [ $pixel -gt $MEAN ] && bit="1"
         hash="$hash$bit"
      done
   done
   hex=$(echo "obase=16;ibase=2;$hash" | bc)
   printf "%016s\n" $hex
   #rm "$TEMP" > /dev/null 2>&1
}

function HammingDistance(){
   # Convert input hex strings to upper case like bc requires
   STR1=$(tr '[a-z]' '[A-Z]' <<< $1)
   STR2=$(tr '[a-z]' '[A-Z]' <<< $2)

   # Convert hex to binary and zero left pad to 64 binary digits
   STR1=$(printf "%064s" $(echo "obase=2;ibase=16;$STR1" | bc))
   STR2=$(printf "%064s" $(echo "obase=2;ibase=16;$STR2" | bc))

   # Calculate Hamming distance between two strings, each differing bit adds 1
   hamming=0
   for i in {0..63};do
      a=${STR1:i:1}
      b=${STR2:i:1}
      [ $a != $b ] && ((hamming++))
   done

   # Hamming distance is in range 0..64 and small means more similar
   # We want percentage similarity, so we do a little maths
   similarity=$((100-(hamming*100/64)))
   echo $similarity
}

function Usage(){
   echo "Usage: Similarity image|imageHash [image|imageHash]" >&2
   exit 1
}

################################################################################
# Main
################################################################################
if [ $# -eq 1 ]; then
   # Expecting a single image file for which to generate hash
   if [ ! -f "$1" ]; then
      echo "ERROR: File $1 does not exist" >&2
      exit 1
   fi
   PerceptualHash "$1" 
   exit 0
fi

if [ $# -eq 2 ]; then
   # Expecting 2 things, i.e. 2 image files, 2 hashes or one of each
   if [ -f "$1" ]; then
      hash1=$(PerceptualHash "$1")
   else
      hash1=$1
   fi
   if [ -f "$2" ]; then
      hash2=$(PerceptualHash "$2")
   else
      hash2=$2
   fi
   HammingDistance $hash1 $hash2
   exit 0
fi

Usage




cbir