image-processing - समय - विवाह के लिए कुंडली मिलान भविष्यवाणी




चित्र संग्रह में छवि मिलान करना (4)

कुछ फ़ोटो पोस्ट करने के लिए धन्यवाद।

मैंने एक एल्गोरिथ्म को कोडित किया है जिसका नाम 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

मेरे पास कार्ड छवियों का एक बड़ा संग्रह है, और विशेष कार्ड की एक तस्वीर है। संग्रह का कौन सा चित्र मेरे लिए सबसे अधिक समान है, यह जानने के लिए मैं कौन से टूल का उपयोग कर सकता हूं?

यहाँ संग्रह नमूना है:

यहां मैं क्या ढूंढने की कोशिश कर रहा हूं:


मैंने आपके प्रत्येक चित्र का सामान्यीकृत क्रॉस-सहसंबंध कार्ड के साथ करने की भी कोशिश की, जैसे:

#!/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 साथ सबसे बेहतर संबंध है।

ध्यान दें कि मैंने सभी छवियों को एक ही आकार में बदल दिया है और उनके विपरीत सामान्यीकृत किया है ताकि वे आसानी से तुलना कर सकें और इनके विपरीत मतभेद के परिणामस्वरूप प्रभाव कम हो जाएंगे उन्हें छोटे बनाने से सहसंबंध के लिए आवश्यक समय कम होता है।


मैंने छवि डेटा को सदिश के रूप में व्यवस्थित करके और संग्रह छवि वैक्टर और खोजा गई छवि वेक्टर के बीच के आंतरिक उत्पाद को लेकर यह कोशिश की। वैक्टर जो सबसे अधिक समान हैं वे उच्चतम आंतरिक-उत्पाद देंगे। मैं समान आकार में सभी छवियों का आकार बदलता हूं, ताकि मैं समान-लंबाई वाले वैक्टर मिल सकूं, ताकि मैं आंतरिक उत्पाद ले सकूं। इस रीसाइजिंग में आंतरिक उत्पाद कम्प्यूटेशनल लागत को भी कम किया जाएगा और वास्तविक छवि का एक मोटे सन्निकटन होगा।

आप इसे जल्दी से Matlab या Octave के साथ देख सकते हैं नीचे मटैब / ओक्टेव स्क्रिप्ट है मैंने वहां टिप्पणी को जोड़ा है मैंने 1 से 8 तक चर बहु को बदलने की कोशिश की (आप किसी भी पूर्णांक मान की कोशिश कर सकते हैं), और उन सभी मामलों के लिए, छवि डेमिस्टिव ने कार्ड की छवि के साथ उच्चतम आंतरिक उत्पाद दिया। बहु = 8 के लिए, मुझे Matlab में निम्नलिखित आईपी वेक्टर प्राप्त होता है:

ip =

683007892

558305537

604013365

जैसा कि आप देख सकते हैं, यह 6830078 9 की छवि डेमिस्टिफ़िक के लिए सबसे अधिक आंतरिक उत्पाद देता है।

% 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;

संपादित करें

मैंने एक अन्य दृष्टिकोण की कोशिश की, मूलतः संदर्भ छवियों और कार्ड की छवि के बीच इयूक्लिडियन दूरी (एल 2 आदर्श) लेते हुए और यह मुझे आपके टेस्ट कार्ड की छवि के लिए इस लिंक पर मिली संदर्भ छवियों (383 छवियों) के बड़े संग्रह के साथ बहुत अच्छे परिणाम दिए

यहां पूरी छवि लेने के बजाय, मैंने उस ऊपरी भाग को निकाला है जिसमें छवि है और इसे तुलना के लिए उपयोग किया है

निम्न चरणों में, किसी भी प्रसंस्करण करने से पहले सभी प्रशिक्षण छवियों और परीक्षण छवि को पूर्वनिर्धारित आकार में बदल दिया जाता है

  • प्रशिक्षण छवियों से छवि क्षेत्रों को निकालें
  • एक मोटे सन्निकटन प्राप्त करने के लिए इन छवियों पर morphological समापन करें (यह चरण आवश्यक नहीं हो सकता है)
  • इन चित्रों को वेक्टर करें और प्रशिक्षण सेट में स्टोर करें (मैं इसे प्रशिक्षण सेट करता हूं, भले ही इस दृष्टिकोण में कोई प्रशिक्षण नहीं है)
  • टेस्ट कार्ड की छवि लोड करें, छवि क्षेत्र-के-ब्याज (आरओआई) को निकालने के लिए, बंद करें, फिर वेक्टर कीजिए
  • प्रत्येक संदर्भ छवि वेक्टर और परीक्षण छवि वेक्टर के बीच यूक्लिडियन दूरी की गणना करें
  • न्यूनतम दूरी वस्तु चुनें (या पहले कश्मीर आइटम)

मैंने इसे सी ++ में OpenCV का उपयोग किया था मैं विभिन्न परीक्षणों का उपयोग करते हुए कुछ परीक्षण के परिणाम भी शामिल हूं।

#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;
    }
}

परिणाम:

स्केल = 1.0;

डेमिस्टिफ़ी.एजीपी: 10 9 8 9, सिलेवन_बैसिलिस्क। जेपीजी: 119 9 7, स्कैटा_जिम्बीज़। जेपीजी: 12307.6

पैमाने = .8;

डेमीस्टेफ़ेई.जिपी: 8572.84, सिलेवन_बैसिलिस्क। जेपीजी: 9440.18, स्टील_गोम। जेपीजी: 9445.36

स्केल = .6;

डेमिस्टिव। जेपीजी: 6226.6, स्टील_गोमेम। जेपीजी: 6887.96, सिलेवन_बैसिलिस्क। जेपीजी: 7013.05

पैमाने = .4;

डेमीस्टेफ़ेईजी। जेपीजी: 4185.68, स्टील_गोमेम। जेपीजी: 4544.64, सिलेवन_बैसिलिस्क। जेपीजी: 46 99.67

पैमाने = .2;

डेमिस्टिफ़ी.एजीपीजी: 1903.05, स्टील_गोम। जेपीजी: 2154.64, सिल्वेन_बीसिलिस्क। जेपीजी: 2277.42


अगर मैं आपको सही ढंग से समझता हूं तो आपको चित्रों के रूप में उनकी तुलना करना होगा। यहां एक बहुत ही सरल लेकिन प्रभावी समाधान है - इसे सैकुली कहा जाता है

संग्रह का कौन सा चित्र मेरे लिए सबसे अधिक समान है, यह जानने के लिए मैं कौन से टूल का उपयोग कर सकता हूं?

यह उपकरण छवि प्रसंस्करण के साथ बहुत अच्छा काम कर रहा है और केवल यह पता लगाने में सक्षम नहीं है कि आपका कार्ड (छवि) उसी प्रकार जैसा है जिसे आपने पहले ही परिभाषित किया है, लेकिन आंशिक छवि सामग्री (तथाकथित आयत ) भी खोजता है

डिफ़ॉल्ट रूप से आप इसे पायथन के माध्यम से कार्यक्षमता बढ़ा सकते हैं। किसी भी छविऑब्जेक्ट को प्रतिशतता में समानता_पाटन स्वीकार करने के लिए सेट किया जा सकता है और ऐसा करने से आप ठीक से ढूंढ सकते हैं जो आप खोज रहे हैं।

इस उपकरण का एक और बड़ा लाभ यह है कि आप एक दिन में मूल बातें सीख सकते हैं।

उम्मीद है की यह मदद करेगा।





cbir