2010-11-11 10 views
6

में decompressing मैं वर्तमान में एक जावा प्रोग्राम में निम्नलिखित सरणी,जावा में एक बाइट सरणी को संपीड़ित और सी

byte[] data = new byte[800]; 

है और मैं बॉड एक माइक्रोकंट्रोलर के लिए यह धारावाहिक से अधिक भेजने से पहले यह सेक करना चाहते हैं (115200)। मैं फिर सी में माइक्रोकंट्रोलर पर सरणी को डिक्रॉप करना चाहता हूं। हालांकि, मुझे पूरा यकीन नहीं है कि ऐसा करने का सबसे अच्छा तरीका क्या है। प्रदर्शन एक मुद्दा है क्योंकि माइक्रोकंट्रोलर सिर्फ एक आर्डिनो है इसलिए यह बहुत मेमोरी/सीपीयू गहन नहीं हो सकता है। डेटा और अधिक या कम यादृच्छिक है (संपादित मुझे लगता है कि यह वास्तव में है कि यादृच्छिक नहीं है, नीचे संपादन देखें) मैं कहना चाहता हूँ, क्योंकि यह हर 16 बिट के लिए एक आरजीबी रंग मूल्य का प्रतिनिधित्व करता।

क्या सबसे अच्छा तरीका यह डेटा संपीड़ित करने के लिए हो सकता है? कोई विचार है कि मैं संभवतः कितना संपीड़न प्राप्त कर सकता हूं?

संपादित

जानकारी की कमी के बारे में क्षमा करें। मुझे संपीड़न को लापरवाह होने की आवश्यकता है और मैं केवल एक समय में 800 बाइट भेजने का इरादा रखता हूं। मेरी समस्या यह है कि 800 बाइट्स 115200 बॉड की दर से पर्याप्त तेज़ी से स्थानांतरित नहीं होंगे जो मैं उपयोग कर रहा हूं। मैं उम्मीद कर रहा था कि मैं गति को बेहतर बनाने के लिए आकार को छोटा कर सकता हूं।

हर दो बाइट्स लगता है:

0RRRRRGGGGGBBBBB

जहां R जी और बी बिट्स, लाल, हरे और नीले रंग क्रमशः चैनलों के लिए मूल्यों का प्रतिनिधित्व। प्रत्येक दो बाइट तब 20x20 ग्रिड पर एक व्यक्तिगत एलईडी है। मैं कल्पना करता हूं कि दो बाइट्स के कई सेट समान होंगे क्योंकि मैं अक्सर कई एल ई डी में एक ही रंग कोड असाइन करता हूं। यह भी मामला हो सकता है कि आरजीबी मूल्य अक्सर> 15 होते हैं क्योंकि जब मैं कर सकता हूं तो आमतौर पर चमकदार रंगों का उपयोग करता हूं (हालांकि, यह एक महत्वपूर्ण बिंदु हो सकता है क्योंकि वे सभी आम तौर पर नहीं होते हैं> 15 एक बार में)।

+1

800 बाइट्स डेटा का एक बहुत नहीं है ... वह यह है कि सिर्फ उदाहरण के लिए, या कि सभी आप कभी भी भेजने के लिए जा रहे है? – Rooke

+3

अच्छा संपीड़न उस डेटा की विशेषताओं पर निर्भर करता है जो आप संपीड़ित करने के लिए कर रहे हैं।यदि आप डेटा के कुछ प्रतिनिधि नमूने से लिंक कर सकते हैं, तो आपको बहुत बेहतर उत्तर मिलेंगे। – caf

+0

समझदारी से इस प्रश्न का उत्तर देने के लिए पर्याप्त जानकारी के पास कहीं भी नहीं है। यदि आपका डेटा वास्तव में यादृच्छिक है, तो यह असम्पीडित है। यदि आपका डेटा किसी प्रकार की छवियों का प्रतिनिधित्व करता है, तो आप भाग्य में हो सकते हैं। लेकिन आपने यह निर्दिष्ट नहीं किया है कि किस तरह की छवि, न ही आप हानि सहन करने के लिए तैयार हैं, आदि –

उत्तर

6

डेटा "कम या ज्यादा यादृच्छिक" है तो आप बहुत किस्मत यह संपीड़ित करने के लिए नहीं होगा, मुझे डर लग रहा।

अद्यतन

नई जानकारी को देखते हुए, मैं शर्त लगा सकता है कि आप अपने एलईडी डिस्प्ले पर 32k रंग की जरूरत नहीं है। मुझे लगता है कि 1024- या 256-रंग पैलेट पर्याप्त हो सकता है। इसलिए आप एक छोटी संपीड़न योजना से दूर हो सकते हैं (बस प्रत्येक शब्द को लुकअप टेबल के माध्यम से मैप करें, या संभवतः प्रत्येक घटक के एलएसबीएस को छोड़ दें), जो पूरी तरह से असंबद्ध पिक्सेल मानों के लिए भी काम करेगा।

+0

डाउनवॉटर: समझाओ, कृपया? यह जवाब पूरी तरह से गंभीर है; अधिकांश अन्य उत्तरों अनुमानों के आधार पर प्रस्ताव हैं कि डेटा में कुछ संरचना है। –

+0

मैं आगे बढ़ गया और बस एलएसबी गिरा दिया लेकिन दुर्भाग्य से कि आखिरी बिट बल्कि ध्यान देने योग्य था (पिंक सीधे लाल, आदि समाप्त हो गया)। मैं आगे बढ़ूंगा और रंगों की संख्या सीमित करने की कोशिश करूंगा, शायद इसके साथ मुझे बेहतर भाग्य मिलेगा। – Anon

+1

@ विलियम: यह अजीब है। मैं 1 से बदलते मूल्यों की उम्मीद नहीं करता, प्रति चैनल 32 रंगों के साथ एक उल्लेखनीय अंतर होगा! (इसे एमएस पेंट या कुछ में आज़माएं ...) आपके डिस्प्ले में अजीब गामा वक्र होना चाहिए। –

2

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

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

संपादित

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

#define NBR_16BIT_WORDS 400 
typedef unsigned short uint16_t; 

// Return number of words written to dst (always 
// less than or equal to NBR_16BIT_WORDS) 
uint16_t compress(uint16_t *src, uint16_t *dst) 
{ 
    uint16_t *end = (src+NBR_16BIT_WORDS); 
    uint16_t *dst_begin = dst; 
    while(src < end) 
    { 
     uint16_t *temp; 
     uint16_t count=1; 
     for(temp=src+1; temp<end; temp++) 
     { 
      if(*src == *temp) 
       count++; 
      else 
       break; 
     } 
     if(count < 3) 
      *dst++ = *src++; 
     else 
     { 
      *dst++ = (*src)|0x8000; 
      *dst++ = count; 
      *src += count; 
     } 
    } 
    return dst-dst_begin; 
} 

void decompress(uint16_t *src, uint16_t *dst) 
{ 
    uint16_t *end_src = (src+NBR_16BIT_WORDS); 
    uint16_t *end_dst = (dst+NBR_16BIT_WORDS); 
    while(src<end_src && dst<end_dst) 
    { 
     data = *src++; 
     if((data&0x8000) == 0) 
      *dst++ = data; 
     else 
     { 
      data &= 0x7fff; 
      uint16_t count = *src++; 
      while(dst<end_dst && count--) 
       *dst++ = data; 
     } 
    } 
} 
+1

रन-लम्बाई एन्कोडिंग 16 बिट छवि डेटा के लिए बहुत उपयोगी होने की संभावना नहीं है, जब तक कि छवि स्वयं कंप्यूटर उत्पन्न न हो। – caf

+0

+1 .. अतिरिक्त संपीड़न के लिए: 16 बिट 'उच्च-रंग' पिक्सल को आर, जी, बी घटकों में विभाजित करें। फिर प्रति घटक एक सरल पहला ऑर्डर पूर्वानुमान करें और रन-लम्बाई प्रत्येक घटक को अपने आप पर एन्कोड करें। इससे आपको तीन बिट-स्ट्रीम मिलेंगे जो डिकंप्रेस करने के लिए तुच्छ हैं। –

+0

@caf मैंने पहले कुछ डेटा एकत्र करके कहकर मेरी सिफारिश को अर्हता प्राप्त की। आपके सामने कुछ डेटा के साथ यह कहना आसान है कि रन लम्बाई एन्कोडिंग सार्थक है या नहीं। असल में मैं प्रश्न पर आपकी टिप्पणी से सहमत हूं। –

0

LZ77/78 अपेक्षाकृत http://en.wikipedia.org/wiki/LZ77_and_LZ78

लिखना आसान हालांकि डेटा की एक छोटी राशि आप ट्रांसफर कर रहे हैं को देखते हुए इसकी शायद सब पर यह संपीड़ित करने के लायक नहीं हैं।

2

पहले चीजें हैं जो आदेश पर YUV, या YCrCb, या कुछ और करने के लिए आरजीबी से कन्वर्ट करने के लिए किया जाएगा करने के लिए में से एक। ऐसा करने के बाद, आप आम तौर पर यू और वी (या सीआर/सीबी) चैनलों को आधा संकल्प के उप-नमूनाकरण से दूर कर सकते हैं। अधिकांश प्रकार की छवियों में यह काफी आम है (उदा।, जेपीईजी, और एमपीईजी दोनों इसे करते हैं, और इसलिए अधिकांश डिजिटल कैमरों में सेंसर करते हैं)।

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

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

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

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

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

1

डेटा कम या ज्यादा यादृच्छिक है क्योंकि मैं कहूंगा क्योंकि यह प्रत्येक 16 बिट्स के लिए आरजीबी रंग मान का प्रतिनिधित्व करता है।

क्या सबसे अच्छा तरीका यह डेटा संपीड़ित करने के लिए हो सकता है? कोई विचार है कि मैं संभवतः कितना संपीड़न प्राप्त कर सकता हूं?

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

1

निश्चित रूप से ओली चार्ल्सवर्थ के जवाब पर विचार करें। 20x20 ग्रिड पर, मुझे नहीं पता कि आपको एक पूर्ण 32k रंग पैलेट की आवश्यकता है या नहीं।

इसके अलावा, में अपने पहले question, तुमने कहा था कि तुम एक 20ms अवधि (50 हर्ट्ज) पर इस चलाने के लिए कोशिश कर रहे थे। क्या आपको वास्तव में इस प्रदर्शन के लिए बहुत तेज गति की आवश्यकता है? 115200 bps पर, आप संचारित कर सकते हैं ~ 11520 बाइट्स/सेकंड - फोन यह सुरक्षा के अंतर के लिए 10kbps (जैसे कि आपका सूक्ष्म बाइट्स के बीच भी विलंब हो सकता है, आप को देखने के लिए क्या 'असली' बैंडविड्थ है कुछ प्रयोग करना चाहिए)। 50 हर्ट्ज पर, यह आपको केवल 200 बाइट प्रति पैकेट की अनुमति देता है - आप 75% से अधिक संपीड़न अनुपात की तलाश में हैं, जो कि किसी भी परिस्थिति में उपलब्ध नहीं हो सकता है। आप अपनी आवश्यकताओं के साथ बहुत विवाहित लगते हैं, लेकिन यह एक अजीब चैट के लिए समय हो सकता है।

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

संपादित करें: यह 115200 परे सीरियल पोर्ट गति को बढ़ाने के लिए संभव है? अमेज़ॅन में यह USB-serial adapter कहता है कि यह 1 एमबीपीएस तक पहुंच जाता है (शायद वास्तव में 921600 बीपीएस)। आपके हार्डवेयर और पर्यावरण के आधार पर, आपको खराब डेटा के बारे में चिंता करनी पड़ सकती है, लेकिन यदि आप पर्याप्त गति बढ़ाते हैं, तो आप शायद चेकसम जोड़ सकते हैं, और शायद त्रुटि सुधार भी सीमित कर सकते हैं।

मैं Arduino से परिचित नहीं हूँ, लेकिन मैं एक 8 बिट फ्रीस्केल HCS08 मैं 1.25 एमबीपीएस पर ड्राइव मिल गया है, हालांकि बस वास्तव में RS-485 चल रहा है, नहीं 232 रुपये (485 का उपयोग करता है अंतर के लिए संकेत बेहतर शोर प्रदर्शन), और मुझे शोर त्रुटियों के साथ कोई समस्या नहीं है। यदि आप अपने Arduino से तार कर सकते हैं तो आप एक यूएसबी आरएस -485 एडाप्टर पर भी विचार कर सकते हैं (आपको Arduino के स्तर पर 485 सिग्नल बदलने के लिए रूपांतरण हार्डवेयर की आवश्यकता होगी)।

संपादित करें 2: इस USB-SPI/I2C adapter पर विचार हो सकता है, यदि आप एक उपलब्ध I2C या SPI इंटरफेस है, और आप तारों संभाल कर सकते हैं। यह कहता है कि यह 400 केएचजेड आई 2 सी या 200 केएचजेड एसपीआई तक जा सकता है, जो अभी भी काफी नहीं है, लेकिन आप एसपीआई/आई 2 सी और सीरियल लिंक के बीच डेटा को विभाजित कर सकते हैं।

संबंधित मुद्दे