मैं दो छवियों के बीच अंतर कैसे निर्धारित कर सकता हूं?


179

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

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

मुझे लगता है कि अंतर को निर्धारित करने का कोई तरीका है, और मुझे अनिवार्य रूप से एक सीमा निर्धारित करनी होगी।

मैं पूर्णता के बजाय सादगी की तलाश कर रहा हूं। मैं अजगर का उपयोग कर रहा हूं।


जवाबों:


269

सामान्य विचार

विकल्प 1: दोनों छवियों को सरणियों के रूप में लोड करें ( scipy.misc.imread) और एक तत्व-वार (पिक्सेल-बाय-पिक्सेल) अंतर की गणना करें। अंतर के मान की गणना करें।

विकल्प 2: दोनों छवियों को लोड करें। उनमें से प्रत्येक के लिए कुछ विशेषता वेक्टर की गणना करें (जैसे हिस्टोग्राम)। छवियों के बजाय फ़ीचर वैक्टर के बीच की दूरी की गणना करें।

हालाँकि, पहले करने के लिए कुछ निर्णय हैं।

प्रशन

आपको पहले इन सवालों का जवाब देना चाहिए:

  • क्या एक ही आकार और आयाम के चित्र हैं?

    यदि नहीं, तो आपको उनका आकार बदलने या फसल करने की आवश्यकता हो सकती है। पीआईएल लाइब्रेरी इसे पायथन में करने में मदद करेगी।

    यदि उन्हें समान सेटिंग्स और समान डिवाइस के साथ लिया जाता है, तो वे संभवतः समान हैं।

  • क्या छवियाँ अच्छी तरह से संरेखित हैं?

    यदि नहीं, तो आप पहले सबसे अच्छा संरेखण खोजने के लिए, पहले क्रॉस-सहसंबंध चलाना चाहते हैं। SciPy के पास इसे करने के लिए कार्य हैं।

    यदि कैमरा और दृश्य अभी भी हैं, तो चित्र अच्छी तरह से संरेखित होने की संभावना है।

  • क्या छवियों का प्रदर्शन हमेशा समान होता है? (लपट / इसके विपरीत है?)

    यदि नहीं, तो आप छवियों को सामान्य करना चाह सकते हैं ।

    लेकिन सावधान रहें, कुछ स्थितियों में यह अच्छे से अधिक गलत कर सकता है। उदाहरण के लिए, एक अंधेरे पृष्ठभूमि पर एक एकल उज्ज्वल पिक्सेल सामान्यीकृत छवि को बहुत अलग कर देगा।

  • क्या रंग की जानकारी महत्वपूर्ण है?

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

  • क्या छवि में अलग-अलग किनारे हैं? क्या उनके स्थानांतरित होने की संभावना है?

    यदि हाँ, आप पहले एज डिटेक्शन एल्गोरिथ्म लागू कर सकते हैं (जैसे कि सोबेल या प्रीविट ट्रांसफ़ॉर्म के साथ ढाल की गणना करें, कुछ सीमा लागू करें), फिर पहली छवि पर किनारों की तुलना दूसरे पर किनारों से करें।

  • क्या छवि में शोर है?

    सभी सेंसर शोर की कुछ मात्रा के साथ छवि को प्रदूषित करते हैं। कम लागत वाले सेंसर में अधिक शोर होता है। आप छवियों की तुलना करने से पहले कुछ शोर कम करने की इच्छा कर सकते हैं। ब्लर यहां सबसे सरल (लेकिन सबसे अच्छा नहीं) दृष्टिकोण है।

  • आप किस तरह के बदलाव नोटिस करना चाहते हैं?

    यह छवियों के बीच अंतर के लिए उपयोग करने के लिए आदर्श की पसंद को प्रभावित कर सकता है।

    मैनहट्टन मानदंड (निरपेक्ष मानों का योग) या शून्य मानदंड (शून्य के बराबर तत्वों की संख्या) का उपयोग करने पर विचार करें कि छवि कितनी बदल गई है। पूर्व आपको बताएगा कि छवि कितनी बंद है, बाद वाला केवल यह बताएगा कि कितने पिक्सेल अलग हैं।

उदाहरण

मुझे लगता है कि आपकी छवियों को अच्छी तरह से संरेखित किया गया है, एक ही आकार और आकार, संभवतः विभिन्न जोखिम के साथ। सादगी के लिए, मैं उन्हें ग्रेस्केल में परिवर्तित करता हूं, भले ही वे रंग (आरजीबी) के चित्र हों।

आपको इन आयातों की आवश्यकता होगी:

import sys

from scipy.misc import imread
from scipy.linalg import norm
from scipy import sum, average

मुख्य कार्य, दो चित्र पढ़ें, ग्रेस्केल में कनवर्ट करें, परिणाम की तुलना करें और प्रिंट करें:

def main():
    file1, file2 = sys.argv[1:1+2]
    # read images as 2D arrays (convert to grayscale for simplicity)
    img1 = to_grayscale(imread(file1).astype(float))
    img2 = to_grayscale(imread(file2).astype(float))
    # compare
    n_m, n_0 = compare_images(img1, img2)
    print "Manhattan norm:", n_m, "/ per pixel:", n_m/img1.size
    print "Zero norm:", n_0, "/ per pixel:", n_0*1.0/img1.size

तुलना कैसे करें। img1और img22 डी SciPy सरणियों यहाँ हैं:

def compare_images(img1, img2):
    # normalize to compensate for exposure difference, this may be unnecessary
    # consider disabling it
    img1 = normalize(img1)
    img2 = normalize(img2)
    # calculate the difference and its norms
    diff = img1 - img2  # elementwise for scipy arrays
    m_norm = sum(abs(diff))  # Manhattan norm
    z_norm = norm(diff.ravel(), 0)  # Zero norm
    return (m_norm, z_norm)

यदि फ़ाइल एक रंगीन छवि है, तो imreadतीव्रता प्राप्त करने के लिए एक 3 डी सरणी, औसत आरजीबी चैनल (अंतिम सरणी अक्ष) लौटाता है। ग्रेस्केल छवियों के लिए इसे करने की आवश्यकता नहीं है (उदाहरण के लिए .pgm):

def to_grayscale(arr):
    "If arr is a color image (3D array), convert it to grayscale (2D array)."
    if len(arr.shape) == 3:
        return average(arr, -1)  # average over the last axis (color channels)
    else:
        return arr

सामान्यीकरण तुच्छ है, आप [0,255] के बजाय [0,1] को सामान्य करने का विकल्प चुन सकते हैं। arrयहाँ एक SciPy सरणी है, इसलिए सभी ऑपरेशन तत्व-वार हैं:

def normalize(arr):
    rng = arr.max()-arr.min()
    amin = arr.min()
    return (arr-amin)*255/rng

mainफ़ंक्शन चलाएँ :

if __name__ == "__main__":
    main()

अब आप यह सब एक स्क्रिप्ट में डाल सकते हैं और दो छवियों के खिलाफ चला सकते हैं। यदि हम छवि की खुद से तुलना करते हैं, तो कोई अंतर नहीं है:

$ python compare.py one.jpg one.jpg
Manhattan norm: 0.0 / per pixel: 0.0
Zero norm: 0 / per pixel: 0.0

यदि हम छवि को धुंधला करते हैं और मूल की तुलना करते हैं, तो कुछ अंतर होता है:

$ python compare.py one.jpg one-blurred.jpg 
Manhattan norm: 92605183.67 / per pixel: 13.4210411116
Zero norm: 6900000 / per pixel: 1.0

PS संपूर्ण तुलना । स्क्रिप्ट।

अद्यतन: प्रासंगिक तकनीक

जैसा कि प्रश्न एक वीडियो अनुक्रम के बारे में है, जहां फ़्रेम लगभग समान होने की संभावना है, और आप कुछ असामान्य की तलाश करते हैं, मैं कुछ वैकल्पिक दृष्टिकोणों का उल्लेख करना चाहता हूं जो प्रासंगिक हो सकते हैं:

  • पृष्ठभूमि घटाव और विभाजन (अग्रभूमि वस्तुओं का पता लगाने के लिए)
  • विरल ऑप्टिकल प्रवाह (गति का पता लगाने के लिए)
  • चित्र के बजाय हिस्टोग्राम या कुछ अन्य आँकड़ों की तुलना करना

मैं दृढ़ता से "OpenCV सीखना" पुस्तक, अध्याय 9 (छवि भागों और विभाजन) और 10 (ट्रैकिंग और गति) पर एक नज़र डालने की सलाह देता हूं। पूर्व पृष्ठभूमि घटाव विधि का उपयोग करना सिखाता है, उत्तरार्द्ध ऑप्टिकल प्रवाह विधियों पर कुछ जानकारी देता है। सभी विधियाँ OpenCV पुस्तकालय में कार्यान्वित की जाती हैं। यदि आप पायथन का उपयोग करते हैं, तो मेरा सुझाव है कि ओपनसीवी and 2.3, और इसके cv2पायथन मॉड्यूल का उपयोग करें।

पृष्ठभूमि घटाव का सबसे सरल संस्करण:

  • पृष्ठभूमि के प्रत्येक पिक्सेल के लिए औसत मान μ और मानक विचलन सीखें
  • (pixel-2 μ, μ + 2 or) या (μ-μ, μ + σ) की श्रेणी के वर्तमान पिक्सेल मूल्यों की तुलना करें

अधिक उन्नत संस्करण हर पिक्सेल के लिए खाते की समय श्रृंखला में ले जाते हैं और गैर-स्थिर दृश्यों (जैसे कि पेड़ या घास) को संभालते हैं।

ऑप्टिकल फ्लो का विचार दो या अधिक फ्रेम लेना है, और प्रत्येक पिक्सेल (घने ऑप्टिकल प्रवाह) या उनमें से कुछ (विरल ऑप्टिकल प्रवाह) को वेग वेक्टर आवंटित करना है। विरल ऑप्टिकल प्रवाह का अनुमान लगाने के लिए, आप लुकास-कनाडे विधि का उपयोग कर सकते हैं (यह OpenCV में भी लागू किया गया है)। जाहिर है, अगर बहुत अधिक प्रवाह (वेग क्षेत्र के अधिकतम मूल्यों पर उच्च औसत) है, तो कुछ फ्रेम में आगे बढ़ रहा है, और बाद की छवियां अधिक भिन्न हैं।

हिस्टोग्राम की तुलना लगातार फ्रेम के बीच अचानक बदलाव का पता लगाने में मदद कर सकती है। इस दृष्टिकोण का उपयोग कोर्टबन एट अल, 2010 में किया गया था :

निरंतर फ्रेम की समानता। दो लगातार फ्रेम के बीच की दूरी को मापा जाता है। यदि यह बहुत अधिक है, तो इसका मतलब है कि दूसरा फ्रेम दूषित है और इस प्रकार छवि समाप्त हो गई है। Kullback-Leibler दूरी , या आपसी एन्ट्रापी, दो फ्रेम के हिस्टोग्राम पर:

$ $ d (p, q) = \ sum_i p (i) \ log (p (i) / q (i)) $ $

जहाँ p और q तख्ते के हिस्टोग्राम होते हैं। दहलीज 0.2 पर तय की गई है।


मुझे एक RuntimeWarning: invalid value encountered in double_scalarsलाइन ४४ ( return (arr-amin)*255/rng) और एक ValueError: array must not contain infs or NaNsलाइन ३० पर z_norm = norm(diff.ravel(), 0)
मिलती है

@BioGeek जो rngशून्य के बराबर है। बस एक चेक जोड़ें और सेट करेंrng = 1
हाईसी

76

एक सरल उपाय:

एक जेपीईजी के रूप में छवि को एनकोड करें और फाइलों में पर्याप्त बदलाव देखें ।

मैंने वीडियो थंबनेल के साथ कुछ इसी तरह लागू किया है, और इसमें बहुत सफलता और मापनीयता थी।


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

पसंद है। यद्यपि अन्य समाधान भी काम करते हैं, लेकिन एक सामान्य स्थिति के लिए यह एक बड़ा लाभ है: क्या होगा यदि आप "आधार" छवि को सहेजना नहीं चाहते हैं? बस एक हैश के रूप में फ़ाइलों को बचाने और फिर घटाव के साथ बस संख्या की तुलना करें। मेरे मामले में मेरे पास 4 चित्र हैं, उनमें से एक बहुत सीमिलर है और अन्य 3 बिल्कुल अलग हैं। बस एक ही आयाम के लिए, jpg करने के लिए और स्थानापन्न। बहुत अच्छे।
डिएगो आंद्रेस डिआज़ एस्पिनोज़ा

60

आप पीआईएल से कार्यों का उपयोग करके दो छवियों की तुलना कर सकते हैं ।

import Image
import ImageChops

im1 = Image.open("splash.png")
im2 = Image.open("splash2.png")

diff = ImageChops.difference(im2, im1)

डिफरेंट ऑब्जेक्ट एक ऐसी छवि है जिसमें प्रत्येक पिक्सेल पहली छवि से दूसरी छवि में उस पिक्सेल के रंग मूल्यों के घटाव का परिणाम है। भिन्न छवि का उपयोग करके आप कई काम कर सकते हैं। सबसे सरल एक diff.getbbox()फ़ंक्शन है। यह आपको न्यूनतम आयत बताएगा जिसमें आपकी दो छवियों के बीच सभी परिवर्तन हैं।

आप संभवतः पीआईएल के कार्यों का उपयोग करते हुए यहां बताए गए अन्य सामान के अनुमानों को लागू कर सकते हैं।


2
मैं अंतर छवि को बचाना चाहता हूं। अलग वस्तु का मतलब है जो छवियों का अंतर रखती है। अरे मैं इसे बचा सकता हूँ?
सागर

2
@ एंथनी आप छवि नाम निर्दिष्ट करने वाली अलग वस्तु पर सेव () कॉल कर सकते हैं। इस तरह: diff.save ("diff.png") यह आपके लिए अंतर छवि को बचाएगा।
सागर

20

दो लोकप्रिय और अपेक्षाकृत सरल तरीके हैं: (ए) पहले से सुझाए गए यूक्लिडियन दूरी, या (बी) सामान्यीकृत क्रॉस-सहसंबंध। सामान्य क्रॉस-सह-संबंध सामान्य क्रॉस-सह-संबंध की तुलना में प्रकाश परिवर्तनों में अधिक मजबूत होते हैं। विकिपीडिया सामान्यीकृत क्रॉस-सहसंबंध के लिए एक सूत्र देता है । अधिक परिष्कृत तरीके भी मौजूद हैं, लेकिन उन्हें बहुत अधिक काम करने की आवश्यकता है।

सुन्न की तरह सिंटैक्स का उपयोग करना,

dist_euclidean = sqrt (राशि ((i1 - i2) ^ 2)) / i1.size

dist_manhattan = sum (abs (i1 - i2)) / i1.size

dist_ncc = sum ((i1 - mean (i1)) * (i2 - mean (i2)) / / (
  (i1.size - 1) * stdev (i1) * stdev (i2))

यह सोचते हैं कि i1और i22 डी ग्रेस्केल छवि सरणियों कर रहे हैं।


3
छवि क्रॉस-सहसंबंध फ़ंक्शन SciPy ( docs.scipy.org/doc/scipy/reference/generated/… ) में बनाए गए हैं , और FFT का उपयोग करके एक तेज़ संस्करण stsci python ( stsci.edu/resources/software_hardware/pyraf/ पर उपलब्ध है। stsci_python )
एंडोलिथ

14

कोशिश करने के लिए एक तुच्छ चीज़:

दोनों छवियों को छोटे थंबनेल (जैसे 64 x 64) पर फिर से सेट करें और थंबनेल की पिक्सेल-बाय-पिक्सेल की तुलना एक निश्चित सीमा के साथ करें। यदि मूल चित्र लगभग समान हैं, तो resamped थंबनेल बहुत समान या बिल्कुल समान होंगे। यह विधि शोर का ध्यान रखती है जो विशेष रूप से कम रोशनी वाले दृश्यों में हो सकती है। यह बेहतर हो सकता है अगर आप ग्रेस्केल पर जाएं।


लेकिन आप पिक्सल की तुलना कैसे करेंगे?
वाहक

एक बार जब आपके पास थंबनेल होते हैं, तो आप बस एक-एक करके पिक्सल की तुलना कर सकते हैं। यदि आप ग्रेस्केल में हैं, तो आप आरजीबी मूल्यों की "दूरी" की गणना करेंगे, यदि आप रंग में काम कर रहे हैं या ग्रे टन के बीच का अंतर है।
एटल गोराल

1
"पिक्सल की एक-एक करके तुलना करें"। इसका क्या मतलब है? क्या परीक्षण में विफल होना चाहिए यदि 64 ^ 2 पिक्सेल-प्रति-पिक्सेल परीक्षणों में से एक विफल हो जाता है?
फ़ेडरिको ए। रामपोनी

"थ्रू पिक्सेल-बाय-पिक्सेल की तुलना एक निश्चित सीमा के साथ" करने से मेरा क्या मतलब है, पिक्सल की तुलना करने के लिए एक फजी एल्गोरिथ्म के साथ आना है। यदि परिकलित अंतर (आपके फ़ज़ी एल्गोरिथम पर निर्भर करता है) एक निश्चित सीमा से अधिक है, तो चित्र "समान नहीं" हैं।
एटल गोराल

1
बहुत ही सरल उदाहरण, "फजी एल्गोरिथ्म" बिना: प्रत्येक पिक्सेल के माध्यम से समानांतर लूप (पिक्सेल # तुलना n छवि के # 1 पिक्सेल # करने के लिए n छवि # 2 की), और एक चर के मूल्य में अंतर को जोड़ने
mk12

7

मैं विशेष रूप से इस सवाल को संबोधित कर रहा हूं कि अगर वे "अलग पर्याप्त" हैं तो गणना कैसे करें। मुझे लगता है कि आप एक-एक करके पिक्सल को घटा सकते हैं।

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

फिर "वास्तविक" परीक्षा के लिए, आप इस तरह एक मानदंड चाहते हैं:

  • वही अगर P पिक्सेल से भिन्न होता है तो E से अधिक नहीं होता है।

तो, शायद, अगर ई = 0.02, पी = 1000, इसका मतलब (लगभग) होगा कि यह "अलग" होगा यदि ~ 5 इकाइयों (8-बिट छवियों को मानकर) या 1000 से अधिक होने पर कोई भी एकल पिक्सेल बदलता है पिक्सल में कोई भी त्रुटि थी।

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

मैं एक ओपन सोर्स प्रोजेक्ट OpenImageIO चलाता हूं , जिसमें "आइडीएफ" नामक एक उपयोगिता है जो थ्रेसहोल्ड के साथ मतभेदों की तुलना करता है (यहां तक ​​कि अधिक विस्तृत, वास्तव में)। यहां तक ​​कि अगर आप इस सॉफ़्टवेयर का उपयोग नहीं करना चाहते हैं, तो आप स्रोत को देखने के लिए देखना चाहते हैं कि हमने यह कैसे किया। इसका व्यावसायिक रूप से काफी उपयोग किया जाता है और इस थ्रॉल्डिंग तकनीक को विकसित किया गया ताकि हम "रेफ़रेंस इमेजेस" के साथ रेंडरिंग और इमेज प्रोसेसिंग सॉफ्टवेयर के लिए एक टेस्ट सूट कर सकें, जिसमें प्लेटफॉर्म-टू-प्लेटफॉर्म से छोटे अंतर हो सकते हैं या जैसा कि हमने मामूली बदलाव किया है। था एल्गोरिदम, इसलिए हम "सहनशीलता के भीतर मैच" ऑपरेशन चाहते थे।


6

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

https://github.com/nicolashahn/diffimg

जो समान आकार की छवियों पर काम करता है, और प्रति-पिक्सेल स्तर पर, प्रत्येक चैनल पर मूल्यों के अंतर को मापता है: आर, जी, बी (ए, ए), उन चैनलों के औसत अंतर को लेता है, और फिर अंतर को औसत करता है। सभी पिक्सेल, और एक अनुपात लौटाते हैं।

उदाहरण के लिए, सफेद पिक्सेल की 10x10 छवि के साथ, और एक ही छवि लेकिन एक पिक्सेल लाल रंग में बदल गया है, उस पिक्सेल का अंतर 1/3 या 0.33 है ... (RGB 0,0,0 बनाम 255,0,0) ) और अन्य सभी पिक्सल्स में 0. 100 पिक्सल के साथ 0.33 ... / 100 = ~ ~ 0.33% का अंतर है।

मेरा मानना ​​है कि यह ओपी के प्रोजेक्ट के लिए पूरी तरह से काम करेगा (मुझे एहसास है कि यह अब बहुत पुरानी पोस्ट है, लेकिन भविष्य के स्टैकऑवरफ्लॉवर के लिए पोस्टिंग जो भी अजगर में छवियों की तुलना करना चाहते हैं)।


5

दिए गए अधिकांश उत्तर प्रकाश के स्तर से नहीं निपटेंगे।

मैं तुलना करने से पहले पहले एक मानक प्रकाश स्तर तक छवि को सामान्य करूंगा।


यदि आप आवधिक छवियां ले रहे हैं और आसन्न जोड़े को अलग कर रहे हैं, तो आप संभवत: किसी को रोशनी चालू करने के बाद पहले वाले को रखने का खर्च उठा सकते हैं।
वॉकिटाल्की

5

दो छवियों के बीच समानता को मापने का एक और अच्छा, सरल तरीका:

import sys
from skimage.measure import compare_ssim
from skimage.transform import resize
from scipy.ndimage import imread

# get two images - resize both to 1024 x 1024
img_a = resize(imread(sys.argv[1]), (2**10, 2**10))
img_b = resize(imread(sys.argv[2]), (2**10, 2**10))

# score: {-1:1} measure of the structural similarity between the images
score, diff = compare_ssim(img_a, img_b, full=True)
print(score)

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


3
हां, skimageइस एप्लिकेशन के लिए उपयोग करना वास्तव में अच्छा है। मैं from skimage.measure import compare_ssim, compare_mseबहुत उपयोग करता हूं । skimage.measure डॉक्स
ximiki

3

क्या आपने इसी तरह के चित्र प्रश्न खोजने के लिए एल्गोरिथम देखा है ? सुझाव देखने के लिए इसे देखें।

मैं आपके तख्ते के तरंग परिवर्तन का सुझाव दूंगा (मैंने हर परिवर्तन का उपयोग करते हुए इसके लिए एक C विस्तार लिखा है); फिर, दो चित्रों के बीच सबसे बड़े (आनुपातिक) तरंगिका कारकों के अनुक्रमितों की तुलना करते हुए, आपको एक संख्यात्मक समरूपता प्राप्त करनी चाहिए।


2

अगर इसका उत्तर देने में बहुत देर हो जाती है तो मैं माफी मांगता हूं, लेकिन जब से मैं कुछ ऐसा कर रहा हूं मुझे लगा कि मैं किसी तरह योगदान दे सकता हूं।

शायद OpenCV के साथ आप टेम्पलेट मिलान का उपयोग कर सकते हैं। जैसा कि आपने कहा कि आप एक वेबकैम का उपयोग कर रहे हैं मान लें:

  1. छवियों को सरल करें (थ्रेशोल्डिंग शायद?)
  2. टेम्पलेट मिलान लागू करें और minMaxLoc के साथ max_val जांचें

युक्ति: max_val (या उपयोग की गई विधि के आधार पर min_val) आपको संख्याएँ, बड़ी संख्याएँ देगा। प्रतिशत में अंतर प्राप्त करने के लिए, उसी छवि के साथ मेल खाने वाले टेम्पलेट का उपयोग करें - परिणाम आपका 100% होगा।

उदाहरण के लिए छद्म कोड:

previous_screenshot = ...
current_screenshot = ...

# simplify both images somehow

# get the 100% corresponding value
res = matchTemplate(previous_screenshot, previous_screenshot, TM_CCOEFF)
_, hundred_p_val, _, _ = minMaxLoc(res)

# hundred_p_val is now the 100%

res = matchTemplate(previous_screenshot, current_screenshot, TM_CCOEFF)
_, max_val, _, _ = minMaxLoc(res)

difference_percentage = max_val / hundred_p_val

# the tolerance is now up to you

आशा करता हूँ की ये काम करेगा।


1

पृथ्वी मूवर्स की दूरी ठीक वही हो सकती है जो आपको चाहिए। यह हो सकता है abit हालांकि वास्तविक समय में लागू करने के लिए भारी।


मैं वास्तव में इस जवाब को अच्छी तरह से महसूस नहीं करता हूं: "मैं पूर्णता के बजाय सादगी की तलाश कर रहा हूं। मैं अजगर का उपयोग कर रहा हूं।"
पिलौपिली

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

1

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


1

मैं (1) एक बहुत तिपाई पर एक ही कैमरे के साथ लिया jpg छवियों के साथ किस्मत का एक बहुत कुछ किया गया है (जैसे कि 3000 पिक्सल से 100 पिक्सल चौड़ा या उससे भी कम) (2) एक एकल में एक jpg सरणी समतल (2) वेक्टर (3) जोड़ीदार सहसंबंधी छवियों को सहसंबंधी सहसंबंधी एल्गोरिथ्म के साथ सहसंबंध गुणांक प्राप्त करने के लिए (4) वर्ग सहसंबंध गुणांक आर-वर्ग प्राप्त करने के लिए (यानी एक छवि में परिवर्तनशीलता का अंश अगले में भिन्नता द्वारा समझाया गया) (5) आम तौर पर मेरे आवेदन में अगर आर-वर्ग <0.9, मैं कहता हूं कि दो छवियां अलग हैं और बीच में कुछ हुआ है।

यह मेरे कार्यान्वयन में मजबूत और तेज़ है (गणितज्ञ 7)

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

मुझे नहीं पता कि पायथन का उपयोग कैसे किया जाए, लेकिन मुझे यकीन है कि यह सहसंबंध भी करता है, नहीं?


1

आप दोनों चित्रों के हिस्टोग्राम की गणना कर सकते हैं और फिर भट्टाचार्य गुणांक की गणना कर सकते हैं , यह एक बहुत तेज़ एल्गोरिथ्म है और मैंने इसका उपयोग क्रिकेट वीडियो में शॉट परिवर्तन का पता लगाने के लिए किया है (सी में ओपनसीवी का उपयोग करके)


क्या आप स्वयं छवियों पर गुणांक की गणना कर सकते हैं?
एंडोलिथ

आपको छवियों के लिए हिस्टोग्राम की गणना करनी होगी (आवश्यकताओं के अनुसार हिस्टोग्राम के बिन आकार के साथ)।
vishalv2050

1

जाँच करें कि कैसे हाकर वेवलेट्स को इस्क-डेमन द्वारा कार्यान्वित किया जाता है । आप छवियों के बीच अंतर की गणना करने के लिए imgdb C ++ कोड का उपयोग कर सकते हैं:

isk-daemon एक खुला स्रोत डेटाबेस सर्वर है जो किसी भी छवि से संबंधित वेबसाइट या सॉफ़्टवेयर में सामग्री-आधारित (विज़ुअल) छवि जोड़ने में सक्षम है।

यह तकनीक किसी भी छवि-संबंधित वेबसाइट या सॉफ़्टवेयर के उपयोगकर्ताओं को एक विजेट पर स्केच करने की अनुमति देती है, जिस छवि को वे ढूंढना चाहते हैं और वेबसाइट पर उन्हें सबसे अधिक समान छवियों के लिए उत्तर देते हैं या प्रत्येक छवि विवरण पृष्ठ पर अधिक समान फ़ोटो के लिए अनुरोध करते हैं।


1

मेरे पास एक ही समस्या थी और एक साधारण अजगर मॉड्यूल लिखा था जो एक काले / सफेद रंग की छवि बनाने के लिए तकिया के ImageChops का उपयोग करते हुए दो समान आकार की छवियों की तुलना करता है और हिस्टोग्राम मूल्यों को समेटता है।

आप इस स्कोर को सीधे प्राप्त कर सकते हैं, या एक पूर्ण काले बनाम सफेद अंतर की तुलना में प्रतिशत मान।

इसमें एक साधारण is_equal फ़ंक्शन भी होता है, जिसमें छवि को गुजरने वाली (और शामिल) छवि के बराबर होने की संभावना होती है।

दृष्टिकोण बहुत विस्तृत नहीं है, लेकिन शायद इसी मुद्दे से जूझ रहे अन्य लोगों के लिए उपयोग का है।

https://pypi.python.org/pypi/imgcompare/


1

कुछ हद तक प्रिंसिपिल्ड दृष्टिकोण, चित्रों की तुलना करने के लिए एक वैश्विक विवरणक का उपयोग करना है, जैसे कि GIST या CENTRIST। एक हैश फ़ंक्शन, जैसा कि यहां वर्णित है , एक समान समाधान भी प्रदान करता है।


1
import os
from PIL import Image
from PIL import ImageFile
import imagehash
  
#just use to the size diferent picture
def compare_image(img_file1, img_file2):
    if img_file1 == img_file2:
        return True
    fp1 = open(img_file1, 'rb')
    fp2 = open(img_file2, 'rb')

    img1 = Image.open(fp1)
    img2 = Image.open(fp2)

    ImageFile.LOAD_TRUNCATED_IMAGES = True
    b = img1 == img2

    fp1.close()
    fp2.close()

    return b





#through picturu hash to compare
def get_hash_dict(dir):
    hash_dict = {}
    image_quantity = 0
    for _, _, files in os.walk(dir):
        for i, fileName in enumerate(files):
            with open(dir + fileName, 'rb') as fp:
                hash_dict[dir + fileName] = imagehash.average_hash(Image.open(fp))
                image_quantity += 1

    return hash_dict, image_quantity

def compare_image_with_hash(image_file_name_1, image_file_name_2, max_dif=0):
    """
    max_dif: The maximum hash difference is allowed, the smaller and more accurate, the minimum is 0.
    recommend to use
    """
    ImageFile.LOAD_TRUNCATED_IMAGES = True
    hash_1 = None
    hash_2 = None
    with open(image_file_name_1, 'rb') as fp:
        hash_1 = imagehash.average_hash(Image.open(fp))
    with open(image_file_name_2, 'rb') as fp:
        hash_2 = imagehash.average_hash(Image.open(fp))
    dif = hash_1 - hash_2
    if dif < 0:
        dif = -dif
    if dif <= max_dif:
        return True
    else:
        return False


def compare_image_dir_with_hash(dir_1, dir_2, max_dif=0):
    """
    max_dif: The maximum hash difference is allowed, the smaller and more accurate, the minimum is 0.

    """
    ImageFile.LOAD_TRUNCATED_IMAGES = True
    hash_dict_1, image_quantity_1 = get_hash_dict(dir_1)
    hash_dict_2, image_quantity_2 = get_hash_dict(dir_2)

    if image_quantity_1 > image_quantity_2:
        tmp = image_quantity_1
        image_quantity_1 = image_quantity_2
        image_quantity_2 = tmp

        tmp = hash_dict_1
        hash_dict_1 = hash_dict_2
        hash_dict_2 = tmp

    result_dict = {}

    for k in hash_dict_1.keys():
        result_dict[k] = None

    for dif_i in range(0, max_dif + 1):
        have_none = False

        for k_1 in result_dict.keys():
            if result_dict.get(k_1) is None:
                have_none = True

        if not have_none:
            return result_dict

        for k_1, v_1 in hash_dict_1.items():
            for k_2, v_2 in hash_dict_2.items():
                sub = (v_1 - v_2)
                if sub < 0:
                    sub = -sub
                if sub == dif_i and result_dict.get(k_1) is None:
                    result_dict[k_1] = k_2
                    break
    return result_dict


def main():
    print(compare_image('image1\\815.jpg', 'image2\\5.jpg'))
    print(compare_image_with_hash('image1\\815.jpg', 'image2\\5.jpg', 7))
    r = compare_image_dir_with_hash('image1\\', 'image2\\', 10)
    for k in r.keys():
        print(k, r.get(k))


if __name__ == '__main__':
    main()
  • उत्पादन:

    झूठी
    सच
    Image2 \ 5.jpg Image1 \ 815.jpg
    Image2 \ 6.jpg Image1 \ 819.jpg
    Image2 \ 7.jpg Image1 \ 900.jpg
    Image2 \ 8.jpg Image1 \ 998.jpg
    Image2 \ 9.jpg Image1 \ 1012 .jpg

  • उदाहरण चित्र:

    • 815.jpg
      815.jpg

    • 5.jpg
      5.jpg


0

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


0

मूल्यांकन के लिए वहाँ कई मैट्रिक्स हैं कि क्या दो चित्र दिखते हैं / वे कितने दिखते हैं।

मैं यहां किसी भी कोड में नहीं जाऊंगा, क्योंकि मुझे लगता है कि यह एक तकनीकी समस्या के अलावा एक वैज्ञानिक समस्या होनी चाहिए।

आम तौर पर, सवाल छवियों पर मानव की धारणा से संबंधित है, इसलिए प्रत्येक एल्गोरिथ्म में मानव दृश्य प्रणाली लक्षण पर इसका समर्थन है।

क्लासिक दृष्टिकोण हैं:

दर्शनीय अंतर भविष्यवक्ता: छवि निष्ठा के मूल्यांकन के लिए एक एल्गोरिथ्म ( https://www.spiedigitallibrary.org/conference-proceedings-of-spie/1666/0000/Vouble-differences-predictor--an-al एल्गोरिदम-for-the- / 10.1117 / 12.135952.short का मूल्यांकन-SSO = 1 )

छवि गुणवत्ता मूल्यांकन: त्रुटि की दृश्यता से संरचनात्मक समानता ( http://www.cns.nyu.edu/pub/lcv/wang03-reprint.pdf )

FSIM: छवि गुणवत्ता मूल्यांकन के लिए एक विशेषता समानता सूचकांक ( https://www4.comp.polyu.edu.hk/~cslzhang/IQA/TIP_IQA_FSIM.pdf )

उनमें से, SSIM (इमेज क्वालिटी असेसमेंट: एरर विजिबिलिटी से स्ट्रक्चरल समानता तक) गणना करने में सबसे आसान है और इसका ओवरहेड भी छोटा है, जैसा कि एक अन्य पेपर "ग्रेडिएंट समानता के आधार पर इमेज क्वालिटी असेसमेंट" ( https: //www.santanticscholar) में बताया गया है .org / पेपर / इमेज-क्वालिटी-एसेसमेंट-बेस्ड-ग्रैडिएंट-लियू-लिन / 2b819bef80c02d5d4cb56f27b202535e119df988 )।

कई अन्य दृष्टिकोण हैं। Google स्कॉलर पर एक नज़र डालें और "विज़ुअल डिफरेंस", "इमेज क्वालिटी असेसमेंट" आदि जैसी चीज़ों की तलाश करें, अगर आप रुचि रखते हैं / वास्तव में कला के बारे में परवाह करते हैं।


0

मतलब चुकता त्रुटि की गणना करके सुपी का उपयोग करते हुए एक सरल और तेज़ समाधान है:

before = np.array(get_picture())
while True:
    now = np.array(get_picture())
    MSE = np.mean((now - before)**2)

    if  MSE > threshold:
        break

    before = now
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.