2 डी, लाखों पिक्सेल के साथ बिना बॉक्स वाले पिक्सेल सरणियों के लिए हास्केल प्रतिनिधित्व की क्या सिफारिश की गई है?


117

मैं हास्केल में कुछ इमेज-प्रोसेसिंग समस्याओं से निपटना चाहता हूं। मैं बिटकॉइन (बिटमैप) और लाखों पिक्सेल के साथ रंगीन चित्र दोनों के साथ काम कर रहा हूं। मेरे पास कई प्रश्न हैं:

  1. किस आधार पर मैं के बीच चयन करना चाहिए Vector.Unboxedऔर UArray? वे दोनों अनबॉक्स्ड एरेज़ हैं, लेकिन Vectorएब्सट्रैक्ट भारी रूप से विज्ञापित लगता है, विशेष रूप से लूप फ़्यूज़न के आसपास। क्या Vectorहमेशा बेहतर होता है? यदि नहीं, तो मुझे किस प्रतिनिधित्व का उपयोग करना चाहिए?

  2. रंग छवियों के लिए मैं 16-बिट पूर्णांक या एकल-सटीक फ़्लोटिंग-पॉइंट संख्याओं के त्रिगुणों को संग्रहीत करना चाहूंगा। इस उद्देश्य के लिए, Vectorया तो UArrayउपयोग करना आसान है या नहीं ? अधिक प्रदर्शन करने वाला?

  3. बिटोनल छवियों के लिए मुझे प्रति पिक्सेल केवल 1 बिट स्टोर करने की आवश्यकता होगी। क्या कोई पूर्वनिर्धारित डेटाटाइप है जो एक शब्द में कई पिक्सेल पैक करके मेरी मदद कर सकता है, या मैं अपने दम पर हूँ?

  4. अंत में, मेरे सरणियाँ दो-आयामी हैं। मुझे लगता है कि मैं एक प्रतिनिधित्व "सरणी के सरणी" (या वैक्टर के वेक्टर) के रूप में एक अतिरिक्त द्वारा लगाए गए अतिरिक्त अप्रत्यक्षता से निपट सकता हूं, लेकिन मैं एक अमूर्त पसंद करूंगा जिसमें सूचकांक-मैपिंग समर्थन है। क्या कोई मानक पुस्तकालय से या हैकेज से कुछ भी सुझा सकता है?

मैं एक कार्यात्मक प्रोग्रामर हूं और म्यूटेशन की कोई आवश्यकता नहीं है :-)


2
मुझे लगता है कि केवल रेपा ही है जो नंबर 4 से मिलता है, cse.unsw.edu.au/~chak/papers/repa.pdf देखें ।
स्टीफन टेटली

5
@stephen: मानक Arrayइंटरफ़ेस बहुआयामी सरणियों का समर्थन करता है। आप बस इंडेक्स के लिए एक टपल का उपयोग कर सकते हैं।
जॉन एल

13
यह तथ्य कि यह प्रश्न अत्यधिक उत्थानित है और इसके पक्ष में है (मेरे सहित) यह दर्शाता है कि सरणियों के हास्केल हैंडलिंग बहुत अच्छी तरह से प्रलेखित नहीं है।
अलेक्जेंड्रे सी।

2
@ अलेक्सांड्रे सी .: बुनियादी रोजमर्रा की सरणियों से निपटना अच्छी तरह से प्रलेखित है; म्यूटेबल डेटा रखने वाले मेमोरी के बड़े ब्लॉक्स को हैंडल करना उतना ही सीधा है जितना कि C में होगा; संभव के रूप में कुशलता से बड़े अपरिवर्तनीय बहुआयामी सरणियों को संभालना कुछ हद तक कम स्पष्ट है। यह प्रदर्शन के बारे में है, जहां सूक्ष्म, कम-अच्छी तरह से प्रलेखित विवरण किसी भी भाषा में एक मुद्दा होगा।
सीए मैक्कैन

1
@Alexandre C .: अधिकांश अनुप्रयोगों के लिए, यह निर्बाध है। और यह वास्तव में मुद्दे पर खुद हास्केल नहीं है, यह पुस्तकालय और संकलक है। एस के एक UArrayट्यूल द्वारा अनुक्रमित एक सादा के Intसाथ काम करने के लिए सरल है और अक्सर पर्याप्त रूप से अच्छा है, लेकिन यहां तक ​​कि जीएचसी का गहरा जादू अपने न्यूनतम एपीआई का उपयोग करके कोड को ऑप्टिमाइज़ करने के लिए नहीं जा रहा है, जो तेजी से समानांतर बल्क डेटा प्रोसेसिंग के लिए एक लाइब्रेरी के साथ प्रतिस्पर्धा में है।
सीए मैककैन

जवाबों:


89

बहुआयामी सरणियों के लिए, हास्केल का वर्तमान सबसे अच्छा विकल्प, मेरे विचार में, रेपा है

रेपा उच्च प्रदर्शन, नियमित, बहुआयामी, आकृति बहुरूपी समानांतर सरणियाँ प्रदान करता है। सभी संख्यात्मक डेटा को अनबॉक्स में संग्रहीत किया जाता है। रेपा कॉम्बिनेटर के साथ लिखे गए कार्य स्वचालित रूप से समानांतर होते हैं बशर्ते आप प्रोग्राम चलाते समय कमांड लाइन पर + RTS -Nhateverever आपूर्ति करें।

हाल ही में, इसका उपयोग कुछ इमेज प्रोसेसिंग समस्याओं के लिए किया गया है:

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

Repa-कब पैकेज पढ़ने और .bmp छवि फ़ाइलों लेखन, हालांकि अधिक स्वरूपों के लिए समर्थन की जरूरत है के लिए समर्थन शामिल है।

अपने विशिष्ट प्रश्नों को संबोधित करते हुए, यहां एक ग्राफिक चर्चा के साथ है:


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


वेक्टर के बीच मुझे किस आधार पर चुनना चाहिए। Unboxed और UArray?

उनके पास लगभग एक ही अंतर्निहित प्रतिनिधित्व है, हालांकि, प्राथमिक अंतर वैक्टर के साथ काम करने के लिए एपीआई की चौड़ाई है: उनके पास लगभग सभी ऑपरेशन हैं जिन्हें आप सामान्य रूप से सूचियों के साथ जोड़ेंगे (एक संलयन-संचालित अनुकूलन ढांचे के साथ), जबकि UArrayलगभग है कोई एपीआई नहीं।

रंग छवियों के लिए मैं 16-बिट पूर्णांक या एकल-सटीक फ़्लोटिंग-पॉइंट संख्याओं के त्रिगुणों को संग्रहीत करना चाहूंगा।

UArrayबहु-आयामी डेटा के लिए बेहतर समर्थन है, क्योंकि यह अनुक्रमण के लिए मनमाने ढंग से डेटा प्रकारों का उपयोग कर सकता है। हालांकि यह संभव है Vector( UAअपने तत्व प्रकार के लिए एक उदाहरण लिखकर ), यह Vector- का प्राथमिक लक्ष्य नहीं है - इसके बजाय, यह वह जगह है जहां यह Repaकदम है, जो एक कुशल तरीके से संग्रहीत कस्टम डेटा प्रकारों का उपयोग करना बहुत आसान बनाता है, आकार अनुक्रमण के लिए धन्यवाद ।

में Repa, शॉर्ट्स के अपने ट्रिपल प्रकार होगा:

Array DIM3 Word16

वह है, Word16s का एक 3D सरणी।

बिटोनल छवियों के लिए मुझे प्रति पिक्सेल केवल 1 बिट स्टोर करने की आवश्यकता होगी।

UArrays बिट्स को बिट्स के रूप में पैक करता है, वेक्टर बूल के लिए उदाहरण का उपयोग करता है जो बिट पैकिंग करता है, बजाय एक प्रतिनिधित्व के आधार पर Word8। होवर, वैक्टर के लिए एक बिट-पैकिंग कार्यान्वयन लिखना आसान है - यहां एक (अप्रचलित) uvector लाइब्रेरी से है। हुड के तहत, Repaका उपयोग करता है Vectors, तो मुझे लगता है कि यह पुस्तकालयों प्रतिनिधित्व विकल्प विरासत में मिला है।

क्या कोई पूर्वनिर्धारित डेटाटाइप है जो एक शब्द में कई पिक्सेल पैक करके मेरी मदद कर सकता है

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

अंत में, मेरे सरणियाँ दो-आयामी हैं

UArray और Repa कुशल बहु-आयामी सरणियों का समर्थन करते हैं। रेपा के पास ऐसा करने के लिए एक समृद्ध इंटरफ़ेस भी है। अपने दम पर वेक्टर नहीं करता है।


उल्लेखनीय उल्लेख:

  • हेमेट्रिक्स , रैखिक बीजगणित पैकेज के लिए व्यापक बाइंडिंग के साथ एक कस्टम सरणी प्रकार। vectorया repaप्रकारों का उपयोग करने के लिए बाध्य होना चाहिए ।
  • ix-आकार देने योग्य , नियमित सरणियों से अधिक लचीली अनुक्रमणिका प्राप्त करना
  • चॉकबोर्ड , 2 डी छवियों में हेरफेर के लिए एंडी गिल की लाइब्रेरी
  • कोडेक-इमेज-डेविल , UArray के लिए विभिन्न छवि प्रारूपों को पढ़ता है और लिखता है

5
इसके अलावा, आप अब रेपा-डेविल की बदौलत कई प्रारूपों में 3 डी रेपा सरणियों की छवि आईओ कर सकते हैं ।
डॉन स्टीवर्ट

2
क्या आप बता सकते हैं कि रेपा सी कोड के साथ कैसे हस्तक्षेप कर सकता है? मुझे Data.Array.Repa के लिए मनमोहक उदाहरण नहीं मिले ...
sastanin

2
संकेत करने के लिए नकल करना संभवत: डेटा के लिए सबसे आसान रास्ता है, लेकिन स्पष्ट रूप से दीर्घकालिक समाधान नहीं है। इसके लिए हमें हूड के तहत स्ट्रांग वैक्टर की आवश्यकता होगी।
डॉन स्टीवर्ट


17

एक बार जब मैंने हास्केल सरणी लाइब्रेरी की सुविधाओं की समीक्षा की जो मेरे लिए मायने रखती है, और एक तुलना तालिका (केवल स्प्रेडशीट: प्रत्यक्ष लिंक ) संकलित की है । तो मैं जवाब देने की कोशिश करूंगा।

वेक्टर के बीच मुझे किस आधार पर चुनना चाहिए। Unboxed और UArray? वे दोनों अनबॉक्स्ड एरेज़ हैं, लेकिन वेक्टर एब्स्ट्रक्शन भारी रूप से विज्ञापित लगता है, विशेष रूप से लूप फ़्यूज़न के आसपास। क्या वेक्टर हमेशा बेहतर होता है? यदि नहीं, तो मुझे किस प्रतिनिधित्व का उपयोग करना चाहिए?

यदि वेक्टर को दो-आयामी या बहुआयामी सरणियों की आवश्यकता हो तो UArray को वेक्टर के ऊपर पसंद किया जा सकता है। लेकिन वेक्टर में हेरफेर के लिए अच्छे एपीआई हैं, अच्छी तरह से वैक्टर। सामान्य तौर पर, वेक्टर बहु-आयामी सरणियों के अनुकरण के लिए अच्छी तरह से अनुकूल नहीं है।

Vector.Unboxed का उपयोग समानांतर रणनीतियों के साथ नहीं किया जा सकता है। मुझे संदेह है कि UArray का उपयोग न तो किया जा सकता है, लेकिन कम से कम UArray से बॉक्सिंग ऐरे में स्विच करना बहुत आसान है और देखें कि क्या समानांतरकरण से बॉक्सिंग लागत का लाभ मिलता है।

रंग छवियों के लिए मैं 16-बिट पूर्णांक या एकल-सटीक फ़्लोटिंग-पॉइंट संख्याओं के त्रिगुणों को संग्रहीत करना चाहूंगा। इस प्रयोजन के लिए, या तो वेक्टर या UArray का उपयोग करना आसान है? अधिक प्रदर्शन करने वाला?

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

सरणी के साथ मेरी प्रमुख समस्या यह थी कि यह केवल यादृच्छिक अभिगम भंडारण प्रदान करता है, लेकिन यह सरणी एल्गोरिदम के निर्माण के कई साधन प्रदान नहीं करता है और न ही सरणी दिनचर्या के पुस्तकालयों का उपयोग करने के लिए तैयार नहीं है (रैखिक बीजगणित के साथ इंटरफेस नहीं करता है, doesn 'विश्वास व्यक्त करने की अनुमति नहीं है, fft और अन्य परिवर्तन)।

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

STUArray मेरी मदद कर सकता था, लेकिन मुझे STUArray के साथ बहुरूपी कोड लिखने के लिए आवश्यक गूढ़ प्रकार की त्रुटियों और प्रयासों से लड़ना पसंद नहीं था ।

इसलिए एरे के साथ समस्या यह है कि वे संख्यात्मक अभिकलन के लिए अच्छी तरह से अनुकूल नहीं हैं। हैमेट्रिक्स 'Data.Packed.Vector और Data.Packed.Matrix इस संबंध में बेहतर हैं, क्योंकि वे एक ठोस मैट्रिक्स लाइब्रेरी (ध्यान: GPL लाइसेंस) के साथ आते हैं। मैट्रिक्स गुणा पर प्रदर्शन-वार, हेट्रिक्स पर्याप्त रूप से तेज़ था ( केवल ऑक्टेव की तुलना में थोड़ा धीमा ), लेकिन बहुत मेमोरी-भूख (पायथन / SciPy की तुलना में कई गुना अधिक खपत)।

मेट्रिसेस के लिए ब्लास लाइब्रेरी भी है, लेकिन यह जीएचसी 7 पर नहीं बनती है।

मेरे पास अभी तक रेपा के साथ बहुत अनुभव नहीं था, और मैं रेपा कोड को अच्छी तरह से नहीं समझता। जो कुछ मैं देख रहा हूं, उसमें मैट्रिक्स और ऐरे एल्गोरिदम का उपयोग करने के लिए बहुत सीमित रेंज है जो इसके ऊपर लिखा है, लेकिन लाइब्रेरी के माध्यम से कम से कम महत्वपूर्ण एल्गोरिदम को व्यक्त करना संभव है। उदाहरण के लिए, पहले से ही मैट्रिक्स गुणन के लिए और रेपा-एल्गोरिदम में कन्वेंशन के लिए रूटीन हैं । दुर्भाग्य से, ऐसा लगता है कि सजा अब 7 × 7 गुठली तक सीमित है (यह मेरे लिए पर्याप्त नहीं है, लेकिन कई उपयोगों के लिए पर्याप्त होना चाहिए)।

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

बिटोनल छवियों के लिए मुझे प्रति पिक्सेल केवल 1 बिट स्टोर करने की आवश्यकता होगी। क्या कोई पूर्वनिर्धारित डेटाटाइप है जो एक शब्द में कई पिक्सेल पैक करके मेरी मदद कर सकता है, या मैं अपने दम पर हूँ?

जहां तक ​​मुझे पता है, बूलों के अनबॉक्स्ड एरेज बिट वैक्टर पैकिंग और अनपैकिंग का ख्याल रखते हैं। मुझे याद है कि अन्य पुस्तकालयों में बूलों के सरणियों के कार्यान्वयन को देखते हुए, और यह कहीं और नहीं देखा।

अंत में, मेरे सरणियाँ दो-आयामी हैं। मुझे लगता है कि मैं एक प्रतिनिधित्व "सरणी के सरणी" (या वैक्टर के वेक्टर) के रूप में एक अतिरिक्त द्वारा लगाए गए अतिरिक्त अप्रत्यक्षता से निपट सकता हूं, लेकिन मैं एक अमूर्त पसंद करूंगा जिसमें सूचकांक-मैपिंग समर्थन है। क्या कोई मानक पुस्तकालय से या हैकेज से कुछ भी सुझा सकता है?

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


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

@aleator हाँ, मैं समझता हूँ कि यह वास्तव में एक व्यक्ति के लिए बहुत बड़ा काम है। BTW, यदि आप एक अनुचर हैं, तो क्या आप हडॉक डॉक्स को कहीं प्रकाशित कर सकते हैं, इसलिए स्थानीय स्तर पर स्थापित किए बिना लाइब्रेरी और बाइंडिंग के कवरेज का मूल्यांकन करना संभव था? (डॉक्स एक बिल्ड एरर के कारण हैकेज पर उपलब्ध नहीं हैं; और यह मेरे लिए न तो GHC 6.12.1 और न ही GHC 7.0.2 M_PIअघोषित होने के कारण नहीं बना है )।
sastanin

@jextee अरे, टिप के लिए धन्यवाद! मैंने एक नया संस्करण अपलोड किया है जो दोनों मुद्दों को ठीक कर सकता है।
शाम

@aleator धन्यवाद, अब यह साफ-सुथरा बनाता है।
sastanin

5

हालाँकि, यह आपके प्रश्न का बिल्कुल जवाब नहीं देता है और वास्तव में भी ऐसा नहीं किया गया है, मैं हैक पर CV या CV-combinators पुस्तकालयों को देखने की सलाह दूंगा। वे opencv-Library से कई बल्कि उपयोगी छवि प्रसंस्करण और दृष्टि ऑपरेटरों को बांधते हैं और मशीन दृष्टि समस्याओं के साथ बहुत तेजी से काम कर रहे हैं।

यह बहुत अच्छा होगा यदि कोई यह पता लगाए कि कैसे रेपा या इस तरह के कुछ ऐरे लाइब्रेरी का उपयोग सीधे opencv के साथ किया जा सकता है।


0

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

  • मनमाना परिशुद्धता के साथ 2 डी अनुक्रमण और unboxed पिक्सल ( Double, Float, Word16, आदि ..)
  • सभी आवश्यक कार्यों की तरह map, fold, zipWith, traverse...
  • विभिन्न रंग स्थानों के लिए समर्थन: RGB, HSI, ग्रे स्केल, Bi-tonal, Complex, आदि।
  • सामान्य छवि प्रसंस्करण कार्यक्षमता:
    • बाइनरी आकृति विज्ञान
    • कनवल्शन
    • प्रक्षेप
    • फुरियर रूपांतरण
    • हिस्टोग्राम प्लॉटिंग
    • आदि।
  • पिक्सेल और छवियों को नियमित संख्या के रूप में व्यवहार करने की क्षमता।
  • JuicyPixels लाइब्रेरी के माध्यम से आम छवि प्रारूप पढ़ना और लिखना

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

एक चीज जो यह नहीं करती है वह एक में कई बाइनरी पिक्सल की पैकिंग कर रही है Word, इसके बजाय यह Wordप्रति बाइनरी पिक्सेल का उपयोग करती है , शायद भविष्य में ...

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