मैं कैसे आकलन कर सकता हूं कि OpenCV के साथ दो समान चित्र कैसे हैं?


141

क्या OpenCV दो छवियों की तुलना का समर्थन करता है, कुछ मूल्य (शायद एक प्रतिशत) लौटाता है जो दर्शाता है कि ये चित्र समान कैसे हैं? जैसे यदि एक ही छवि को दो बार पारित किया गया था, तो 100% लौटा दी जाएगी, यदि चित्र पूरी तरह से अलग थे, तो 0% वापस किया जाएगा।

मैं पहले से ही StackOverflow पर इसी तरह के बहुत से विषयों को पढ़ता हूँ। मैंने काफी कुछ गोगलिंग भी किया। अफसोस की बात है कि मैं संतोषजनक जवाब नहीं दे पाया।


जवाब भी देखें stackoverflow.com/questions/4196453/…
B.

जवाबों:


208

यह एक बहुत बड़ा विषय है, जिसमें 3 लाइनों से लेकर संपूर्ण शोध पत्रिकाओं तक के जवाब हैं।

मैं इस तरह की सबसे आम तकनीकों और उनके परिणामों की रूपरेखा तैयार करूंगा।

हिस्टोग्राम की तुलना करना

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

नकारात्मक पक्ष: यह बहुत सरल है। एक केला और एक समुद्र तट एक जैसा दिखेगा, क्योंकि दोनों पीले हैं।

OpenCV विधि: तुलना ()

टेम्पलेट मिलान

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

डाउनसाइड्स: यह केवल समान छवियों, समान आकार और अभिविन्यास के साथ अच्छे परिणाम देता है।

OpenCV विधि: matchTemplate ()

फ़ीचर मिलान

छवि खोज करने के सबसे कुशल तरीकों में से एक माना जाता है। एक छवि से कई विशेषताओं को निकाला जाता है, एक ही तरह से गारंटी देता है कि घुमाए जाने, स्केल किए जाने या तिरछी होने पर भी समान सुविधाओं को फिर से पहचाना जाएगा। इस तरह से निकाले गए फीचर्स को अन्य इमेज फीचर सेट के खिलाफ मैच किया जा सकता है। एक और छवि जिसमें पहले से मेल खाते सुविधाओं का एक उच्च अनुपात है, उसी दृश्य को चित्रित करने के लिए माना जाता है।

बिंदुओं के दो सेटों के बीच की होमोग्राफी खोजने से आप मूल चित्रों या ओवरलैपिंग की मात्रा के बीच शूटिंग कोण में सापेक्ष अंतर भी पा सकेंगे।

इस पर कई OpenCV ट्यूटोरियल / नमूने हैं, और यहां एक अच्छा वीडियो है । एक पूरा OpenCV मॉड्यूल (features2d) इसके लिए समर्पित है।

डाउनसाइड्स: यह धीमा हो सकता है। यह सही नहीं है।


कम ऑन ओवर OpenCV क्यू एंड ए साइट मैं सुविधा वर्णनकर्ता, जो महान जब पूरे छवियों और बनावट वर्णनकर्ता, जो मानव चेहरे या एक छवि में कारों की तरह वस्तुओं की पहचान करने के लिए इस्तेमाल कर रहे हैं की तुलना कर रहे हैं के बीच अंतर के बारे में बात कर रहा हूँ।


इसी तरह की छवियों की तुलना करने कि केवल कुछ अलग छवियों (जैसे एक नई वस्तु अन्यथा एक ही दृश्य में चले गए) आप भी साथ काम कर सकते absdiff codota.com/code/java/methods/org.opencv.core.Core/absdiff थ्रेशोल्डिंग परिणाम एक मुखौटा बनाता है जो आपको उन क्षेत्रों को उजागर करने की अनुमति देता है जो दृश्य से दृश्य में बदल गए थे।
मैक्स एफ।

34

यदि समान चित्रों के मिलान के लिए (समान आकार / अभिविन्यास)

// Compare two images by getting the L2 error (square-root of sum of squared error).
double getSimilarity( const Mat A, const Mat B ) {
if ( A.rows > 0 && A.rows == B.rows && A.cols > 0 && A.cols == B.cols ) {
    // Calculate the L2 relative error between images.
    double errorL2 = norm( A, B, CV_L2 );
    // Convert to a reasonable scale, since L2 error is summed across all pixels of the image.
    double similarity = errorL2 / (double)( A.rows * A.cols );
    return similarity;
}
else {
    //Images have a different size
    return 100000000.0;  // Return a bad value
}

स्रोत


12

सैम का घोल पर्याप्त होना चाहिए। मैंने दोनों हिस्टोग्राम अंतर और टेम्पलेट मिलान के संयोजन का उपयोग किया है, क्योंकि कोई विधि मेरे लिए 100% बार काम नहीं कर रही थी। मैंने हालांकि हिस्टोग्राम विधि को कम महत्व दिया है। यहाँ बताया गया है कि मैंने सरल अजगर लिपि में कैसे लागू किया है।

import cv2

class CompareImage(object):

    def __init__(self, image_1_path, image_2_path):
        self.minimum_commutative_image_diff = 1
        self.image_1_path = image_1_path
        self.image_2_path = image_2_path

    def compare_image(self):
        image_1 = cv2.imread(self.image_1_path, 0)
        image_2 = cv2.imread(self.image_2_path, 0)
        commutative_image_diff = self.get_image_difference(image_1, image_2)

        if commutative_image_diff < self.minimum_commutative_image_diff:
            print "Matched"
            return commutative_image_diff
        return 10000 //random failure value

    @staticmethod
    def get_image_difference(image_1, image_2):
        first_image_hist = cv2.calcHist([image_1], [0], None, [256], [0, 256])
        second_image_hist = cv2.calcHist([image_2], [0], None, [256], [0, 256])

        img_hist_diff = cv2.compareHist(first_image_hist, second_image_hist, cv2.HISTCMP_BHATTACHARYYA)
        img_template_probability_match = cv2.matchTemplate(first_image_hist, second_image_hist, cv2.TM_CCOEFF_NORMED)[0][0]
        img_template_diff = 1 - img_template_probability_match

        # taking only 10% of histogram diff, since it's less accurate than template method
        commutative_image_diff = (img_hist_diff / 10) + img_template_diff
        return commutative_image_diff


    if __name__ == '__main__':
        compare_image = CompareImage('image1/path', 'image2/path')
        image_difference = compare_image.compare_image()
        print image_difference

मैं अच्छी तरह से अजगर को नहीं समझता। लेकिन 'commutative_image_diff' प्रकार क्या है? cv.Mat या डबल। यदि यह cv.Mat है, तो 'commutative_image_diff <self.minimum_commutative_image_diff' की तुलना करें कि यह कैसे काम करता है या इस तुलना का उद्देश्य क्या है। क्या आप मेरे लिए समझा सकते हैं?
बुलेटिन

1

थोडा थोडा विषय लेकिन उपयोगी पाइथोनिक numpyदृष्टिकोण है। इसकी मजबूत और तेज लेकिन सिर्फ पिक्सल की तुलना करती है न कि वस्तुओं या डेटा की जिसमें तस्वीर होती है (और इसमें समान आकार और आकार की छवियों की आवश्यकता होती है):

OpenCV के बिना ऐसा करने के लिए एक बहुत ही सरल और तेज़ दृष्टिकोण और कंप्यूटर दृष्टि के लिए किसी भी पुस्तकालय द्वारा चित्र सरणियों को आदर्श बनाना है

import numpy as np
picture1 = np.random.rand(100,100)
picture2 = np.random.rand(100,100)
picture1_norm = picture1/np.sqrt(np.sum(picture1**2))
picture2_norm = picture2/np.sqrt(np.sum(picture2**2))

दोनों आदर्शित चित्रों (या मैट्रिसेस) को परिभाषित करने के बाद आप उन चित्रों के गुणन पर योग कर सकते हैं जिनकी आप तुलना करना चाहते हैं:

1) यदि आप समान चित्रों की तुलना करते हैं तो राशि 1 वापस आ जाएगी:

In[1]: np.sum(picture1_norm**2)
Out[1]: 1.0

2) यदि वे समान नहीं हैं, तो आपको 0 और 1 के बीच एक मूल्य मिलेगा (यदि आप 100 से गुणा करते हैं तो प्रतिशत):

In[2]: np.sum(picture2_norm*picture1_norm)
Out[2]: 0.75389941124629822

कृपया ध्यान दें कि यदि आपके पास रंगीन चित्र हैं, तो आपको इसे सभी 3 आयामों में करना होगा या केवल एक संक्षिप्त संस्करण की तुलना करना होगा। मुझे अक्सर भारी मात्रा में चित्रों की मनमानी सामग्री के साथ तुलना करनी पड़ती है और ऐसा करने का वास्तव में तेज़ तरीका है।


2
नमस्ते, मैं आपके कदम का अनुसरण करता हूं, लेकिन मैंने पाया कि सामान्यीकृत भाग को उचित परिणाम नहीं मिल सकता है। अंतिम परिणाम 1.0 से बहुत अधिक है। कोई उपाय?
G_cy
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.