रेखापुंज भिन्न: अगर छवियों के समान मूल्य हैं तो कैसे जांचें?


10

क्या यह देखने के लिए जाँच करने का कोई साधन है कि क्या किसी भी 2 रास्टर परतों में समान सामग्री है ?

हमें अपने कॉरपोरेट शेयर्ड स्टोरेज वॉल्यूम पर एक समस्या है: अब यह इतना बड़ा हो गया है कि इसे पूरा बैकअप लेने में 3 दिन का समय लगता है। प्रारंभिक जांच से पता चलता है कि सबसे बड़ी जगह लेने वाले दोषियों में से एक / बंद चूहों पर है जिन्हें वास्तव में CCITT संपीड़न के साथ 1-बिट परतों के रूप में संग्रहीत किया जाना चाहिए।

एक विशिष्ट वर्तमान / नहीं-वर्तमान रेखापुंज

यह नमूना छवि वर्तमान में 2bit (इसलिए 3 संभावित मान) और LZW संपीड़ित टिफ़, फ़ाइल सिस्टम में 11 एमबी के रूप में सहेजी गई है। 1bit (इसलिए 2 संभावित मान) में परिवर्तित होने और CCITT ग्रुप 4 कंप्रेशन को लागू करने के बाद, हम इसे 1.3 एमबी तक घटा देते हैं, लगभग बचत के परिमाण का एक पूरा क्रम।

(यह वास्तव में बहुत अच्छी तरह से व्यवहार किया गया नागरिक है, वहाँ अन्य लोगों को 32 बिट फ्लोट के रूप में संग्रहीत किया जाता है!)

यह शानदार खबर है! हालाँकि इसे लागू करने के लिए लगभग 7,000 चित्र हैं। उन्हें संपीड़ित करने के लिए स्क्रिप्ट लिखना सीधा होगा:

for old_img in [list of images]:
    convert_to_1bit_and_compress(old_img)
    remove(old_img)
    replace_with_new(old_img, new_img)

... लेकिन यह एक महत्वपूर्ण परीक्षा याद आ रही है: क्या नया संकुचित संस्करण सामग्री-समान है?

  if raster_diff(old_img, new_img) == "Identical":
      remove(old_img)
      rename(new_img, old_img)

क्या कोई उपकरण या विधि है जो स्वचालित रूप से (डिस) साबित कर सकती है कि छवि-ए की सामग्री छवि-बी की सामग्री के समान है?

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

एक बहुत बुरा परिणाम

अद्यतन: सबसे बड़े अपराधी 32bit फ़्लोट्स हैं जो कि एक साइड में 100,000px तक होते हैं, इसलिए ~ 30GB असम्पीडित होते हैं।


1
लागू करने का एक तरीका यह raster_diff(old_img, new_img) == "Identical"जांचना होगा कि अंतर के पूर्ण मान का जोनल अधिकतम 0 के बराबर है, जहां पूरे ग्रिड हद तक ज़ोन लिया गया है। क्या यह उस तरह का समाधान है जिसकी आप तलाश कर रहे हैं? (यदि हां, तो यह परिष्कृत करने की जांच करने के लिए है कि किसी भी NoData मूल्यों के अनुरूप भी हैं की आवश्यकता होगी।)
whuber

1
NoDataबातचीत में उचित संचालन सुनिश्चित करने के लिए @whuber धन्यवाद ।
मैट विल्की

यदि आप इसकी जांच कर सकते हैं len(numpy.unique(yourraster)) == 2, तो आप जानते हैं कि इसके 2 अद्वितीय मूल्य हैं और आप सुरक्षित रूप से ऐसा कर सकते हैं।
रेमकोगर्लिच

@Remco अंतर्निहित एल्गोरिथ्म numpy.uniqueअधिक कम्प्यूटेशनल रूप से महंगा होने वाला है (समय और स्थान दोनों के संदर्भ में) अधिकांश अन्य तरीकों की तुलना में यह जांचने के लिए कि अंतर एक स्थिर है। जब दो बहुत बड़े फ्लोटिंग पॉइंट रस्टर्स के बीच अंतर होता है, जो कई अंतरों को प्रदर्शित करता है (जैसे कि एक ओरिजिनल की तुलना एक हानिपूर्ण संपीड़ित संस्करण से) तो यह हमेशा के लिए नीचे गिर जाएगा या पूरी तरह विफल हो जाएगा।
whuber

1
@Aaron, मैं अन्य चीजों को करने के लिए परियोजना से दूर हो गया। इसका एक कारण यह था कि विकास का समय बढ़ता रहा: स्वचालित रूप से संभालने के लिए बहुत सारे किनारे मामले, इसलिए समस्या को ठीक करने के बजाय छवियों को उत्पन्न करने वाले लोगों पर वापस फेंकने का निर्णय लिया गया। (उदाहरण के लिए "आपका डिस्क कोटा एक्स है। आप सीखते हैं कि इसके अंदर कैसे काम करना है।") हालांकि gdalcompare.pyमहान वादा दिखाया ( जवाब देखें )
मैट विल्की

जवाबों:


8

अपने रैस्टर्स को सुन्न सरणियों में परिवर्तित करने का प्रयास करें और फिर यह देखने के लिए जांचें कि क्या उनके पास समान आकार और तत्व array_equal हैं । यदि वे समान हैं, तो परिणाम Trueनिम्न होना चाहिए :

ArcGIS:

import arcpy, numpy

raster1 = r'C:\path\to\raster.tif'
raster2 = r'C:\path\to\raster.tif'

r1 = arcpy.RasterToNumPyArray(raster1)
r2 = arcpy.RasterToNumPyArray(raster2)

d = numpy.array_equal(r1,r2)

if d == False:
    print "They differ"

else:
    print "They are the same"

GDAL:

import numpy
from osgeo import gdal        

raster1 = r'C:\path\to\raster.tif'
raster2 = r'C:\path\to\raster.tif'

ds1 = gdal.Open(raster1)
ds2 = gdal.Open(raster2)

r1 = numpy.array(ds1.ReadAsArray())
r2 = numpy.array(ds2.ReadAsArray())

d = numpy.array_equal(r1,r2)

if d == False:
    print "They differ"

else:
    print "They are the same"

जो मीठा और सरल लगता है। मैं दो विवरणों के बारे में उत्सुक हूं (जो तकनीकी हैं, हालांकि वे महत्वपूर्ण हैं, महत्वपूर्ण हो सकते हैं)। सबसे पहले, क्या यह समाधान NoData मानों को सही ढंग से संभालता है? दूसरा, ग्रिड की तुलना के लिए निर्मित कार्यों जैसे ज़ोनल सारांश के साथ इसकी गति की तुलना कैसे की जाती है?
व्हिबर

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

1
@whuber NoDataहैंडलिंग के बारे में , RasterToNumPyArrayडिफ़ॉल्ट रूप से इनपुट रेखापुंज के NoData मान से असाइन करता है। उपयोगकर्ता एक अलग मूल्य निर्दिष्ट कर सकता है, हालांकि यह मैट के मामले में लागू नहीं होगा। गति के बारे में, स्क्रिप्ट के लिए 6210 कॉलम और 7650 पंक्तियों (DOQQ हद) के साथ 2 4-बिट रैस्टर की तुलना करने में 4.5 सेकंड का समय लगा। मैंने किसी भी जोनल सारांश की विधि की तुलना नहीं की है।
आरोन

1
मैं गदल के बराबर में मुड़ा, gis.stackexchange.com/questions/32995/… से अनुकूलित
मैट

4

आपके पास gdalcompare.py स्क्रिप्ट http://www.gdal.org/gdalcompare.html के साथ एक प्रयास हो सकता है । स्क्रिप्ट का स्रोत कोड http://trac.osgeo.org/gdal/browser/trunk/gdal/swig/python/scripts/gdalcompare.py पर है और क्योंकि यह एक पायथन स्क्रिप्ट है जिसे अनावश्यक को हटाना आसान होना चाहिए परीक्षण और अपनी मौजूदा जरूरतों के अनुरूप नए जोड़े। लगता है कि स्क्रिप्ट पिक्सेल द्वारा पिक्सेल की तुलना दो पिक्चर्स बैंड से इमेज डेटा पढ़कर पिक्सेल की तुलना में कर रही है और यह संभवतः काफी तेज़ और पुन: प्रयोज्य विधि है।


1
पेचीदा, मुझे गदल से प्यार है, इस स्क्रिप्ट के बारे में नहीं पता था। परिणाम की व्याख्या करने के लिए डॉक्स; हालांकि; गैर-मौजूद नहीं हैं। मेरे प्रारंभिक परीक्षण में यह रंग व्याख्या और पैलेट में अंतर की रिपोर्ट करता है, जिसका अर्थ है कि यह मेरी वर्तमान जरूरतों के लिए बहुत विशिष्ट है। मैं अभी भी इसे खोज रहा हूँ। (ध्यान दें: यह उत्तर यहां एक अच्छा फिट होने के लिए बहुत छोटा है, लिंक केवल उत्तर हतोत्साहित करते हैं, कृपया इसे समाप्त करने पर विचार करें)।
मैट विल्की

1

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


क्या यह 32-बिट फ़्लोट्स के साथ काम करेगा? क्या दो तालिकाओं के अंतर के मूल्यों की जांच करने की तुलना में दो तालिकाओं का निर्माण और तुलना वास्तव में कोई तेज़ (या आसान) होगी (जो सिद्धांत रूप में सिर्फ शून्य और NoData होना चाहिए)?
whuber

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

@radouxju की छवियां 100,000px तक एक साइड तक हैं, इसलिए ~ 30GB असम्पीडित हैं। हमारे पास इतने राम के साथ मशीन नहीं है (हालांकि शायद आभासी के साथ ...)
मैट विल्की

ऐसा लगता है कि RAM एक मुद्दा नहीं होगा बशर्ते कि आप ArcGIS देशी ऑपरेशन के साथ रहें। ग्रिड के प्रसंस्करण के दौरान रैम के उपयोग के साथ यह बहुत अच्छा है: आंतरिक रूप से यह प्रसंस्करण पंक्ति-दर-पंक्ति, पंक्तियों के समूहों और आयताकार खिड़कियों द्वारा कर सकता है। एक ग्रिड से दूसरे ग्रिड को घटाना जैसे स्थानीय संचालन आवश्यक रूप से इनपुट और आउटपुट की गति से काम कर सकते हैं, प्रत्येक इनपुट डेटासेट के लिए केवल एक (अपेक्षाकृत छोटे) बफर की आवश्यकता होती है। एक विशेषता तालिका के निर्माण के लिए एक अतिरिक्त हैश तालिका की आवश्यकता होती है - जो कि केवल एक या दो मानों को दिखाने पर ऋणात्मक हो जाएगी, लेकिन मनमानी ग्रिड के लिए भारी हो सकती है।
whuber

numpy 2 * 30Go सरणियों के साथ बहुत अधिक स्वैपिंग करेगा, यह अब आर्कगिस नहीं है। मैंने प्रिंटस्क्रीन के आधार पर माना कि चित्र वर्गीकृत चित्र हैं (केवल कुछ ही मूल्यों के साथ), इसलिए आप इतने सारे वर्गों की अपेक्षा नहीं करते हैं।
राडोक्सु

0

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

mean_obj = arcpy.GetRasterProperties(input_raster, 'MEAN')
mean = float(mean_obj.getOutput(0))
if round(mean, 4) != 0.2010:
    print("raster differs from expected mean.")

std_obj = arcpy.GetRasterProperties(input_raster, 'STD')
std = float(std_obj.getOutput(0))
if round(std, 4) != 0.0161:
    print("raster differs from expected standard deviation.")

2
इन आँकड़ों को मूर्ख बनाने का एक बहुत बड़ा तरीका यह होगा कि सेल सामग्री (जो हो सकती है, और तब होती है, जब छवि आयाम बिलकुल सही न हों)। बहुत बड़े रैयतों पर न तो एसडी और न ही माध्य मज़बूती से बिखरे हुए कुछ छोटे बदलावों का पता लगाएगा (विशेषकर अगर कुछ पिक्सेल गिरा दिए गए थे)। वैचारिक रूप से वे ग्रिड के एक थोक पुनरुत्पादन का पता नहीं लगाते हैं, या तो, बशर्ते घन दृढ़ संकल्प का उपयोग किया गया था (जो कि माध्य और एसडी को संरक्षित करने का इरादा है)। यह ग्रिड के अंतर के एसडी की तुलना शून्य की तुलना में विवेकपूर्ण प्रतीत होगा।
whuber

0

सबसे आसान तरीका एक रैस्टर को दूसरे से घटाना है, यदि परिणाम 0 है, तो दोनों चित्र समान हैं। इसके अलावा आप परिणाम द्वारा रंग द्वारा हिस्टोग्राम या प्लॉट देख सकते हैं।


तुलना करने के लिए घटाव एक अच्छा तरीका है। हालांकि, मेरा मानना ​​है कि हिस्टोग्राम नोडाटा मूल्यों के साथ समस्याओं का पता लगाने में बहुत उपयोगी नहीं होगा। उदाहरण के लिए, मान लीजिए कि संपीड़न प्रक्रिया ने ग्रिड के चारों ओर एक-पिक्सेल सीमा समाप्त कर दी (ऐसा हो सकता है!), लेकिन अन्यथा सटीक था: सभी अंतर अभी भी शून्य होंगे। इसके अलावा, क्या आपने देखा कि ओपी को 7000 रैस्टर डेटा सेट के साथ ऐसा करने की आवश्यकता है? मुझे यकीन नहीं है कि वह 7000 भूखंडों की जांच करेगा।
व्हिबर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.