image-processing समय चित्र संग्रह में छवि मिलान करना



विवाह के लिए कुंडली मिलान भविष्यवाणी (4)

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

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

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


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

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

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

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

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

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


नई विधि!

ऐसा लगता है कि निम्न इमेजमेजिक कमांड, या शायद इसकी विविधता, आपकी छवियों के अधिक से अधिक चयन को देखते हुए, आपके कार्ड के शीर्ष पर शब्दों को निकालेगा

convert aggressiveurge.jpg -crop 80%x10%+10%+10% crop.png

जो आपकी छवि का शीर्ष 10% और चौड़ाई का 80% (शीर्ष बाएं कोने से 10% से शुरू होता है और इसे crop.png में crop.png है) निम्नानुसार है:

और यदि आपके रन tessseract माध्यम से tessseract माध्यम से tessseract है:

tesseract crop.png agg

आपको agg.txt नामक फाइल प्राप्त agg.txt जिसमें:

E‘ Aggressive Urge \L® E

जिसे आप साफ करने के लिए grep माध्यम से चला सकते हैं, केवल ऊपरी और लोअर केस अक्षरों के लिए एक दूसरे के निकट लग रहे हैं:

grep -Eo "\<[A-Za-z]+\>" agg.txt

लेना

Aggressive Urge

:-)


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

#!/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