2009-07-20 12 views
10

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

दीवार 10 'एक्स 10' है, और कैमरे केवल 640x480 तो मैं के रूप में यहां बताए गए एक पट्टी वक्र का उपयोग सब-पिक्सेल माप उपयोग करने का प्रयास कर रहा हूँ है: (8 tpub.com

कैमरा 120fps में चलाता है -बीटी), तो मेरा सब प्रश्न यह है कि सबपिक्सल लेजर डॉट सेंटर को ढूंढने का सबसे तेज़ तरीका है। वर्तमान में मैं स्पलीन इंटरपोलेशन करने से पहले छवि (0 - 254) पर सबसे तेज पिक्सेल खोजने के लिए एक ब्रूट फोर्स 2 डी खोज का उपयोग कर रहा हूं। यह विधि बहुत तेज़ नहीं है और प्रत्येक फ्रेम कंप्यूटर में आने से अधिक समय लेता है।

संपादित करें: अंत में, मेरे कैमरे के डेटा को पिक्सेल चमक का संकेत देने वाले 2 डी सरणी बाइट्स द्वारा दर्शाया जाता है।

मैं क्या करना चाहते हैं मेरे लिए क्या छवि का उपयोग करना चाहते एक XNA शेडर का उपयोग करें। क्या यह व्यावहारिक है? जो मैं समझता हूं, वहां वास्तव में एक पिक्सेल शेडर में निरंतर चर रखने का कोई तरीका नहीं है जैसे कि कुल योग, औसत इत्यादि।

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

मैं अपने एक्सएनए बॉक्स के बाहर सुझावों के लिए भी खुला हूं, चाहे वह डीएक्स 10/डीएक्स 11 हो, शायद कुछ प्रकार का एफपीजीए, आदि। मुझे इस तरह से डेटा को क्रंच करने के तरीकों के साथ वास्तव में बहुत अधिक अनुभव नहीं है। मुझे लगता है कि अगर वे 2 एए बैटरी का उपयोग करके Wii-Mote पर ऐसा कुछ कर सकते हैं, तो शायद मैं इस गलत तरीके से जा रहा हूं।

कोई विचार?

+0

क्या धीमा है, स्कैन कर रहा है या बाद में स्पलीन इंटरपोलेशन कर रहा है? – Nosredna

+0

स्पेललाइन इंटरपोलेशन इसका सबसे धीमा घटक है, इस पर निर्भर करता है कि मैं किस डेल्टा के साथ स्पलीन का मूल्यांकन करता हूं। इस मामले में, मुझे 0.1px सटीकता चाहिए। – bufferz

+0

मुझे यह जोड़ना चाहिए कि यदि मेरे पास 20 लेजर हैं, तो स्पिनलाइन गणना बहुत महंगा सीपीयू बुद्धिमान हो जाएगी। – bufferz

उत्तर

3

यदि आप उप-पिक्सेल सटीकता चाहते हैं तो आप कुछ सुंदर जटिल गणित से निपट रहे हैं। मुझे लगता है कि this paper कुछ विचार करने के लिए है। दुर्भाग्यवश, आपको उस साइट का उपयोग करके इसे देखने के लिए भुगतान करना होगा। यदि आपके पास उपयुक्त लाइब्रेरी तक पहुंच है, तो वे आपके लिए इसे पकड़ सकेंगे।

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

एक्स = राशि/राशि (f (x n))

जहां x मतलब है, एक्स n x- अक्ष और f (x n) के पास एक बिंदु बिंदु एक्स n में मूल्य है। तो इस के लिए:

  * 
     * * 
     * * 
     * * 
     * * 
     * * 
     * * * 
    * * * * 
    * * * * 
* * * * * * 
------------------ 
2 3 4 5 6 7 

देता है:

राशि (एक्स n करें.एफ़ (एक्स n)) = 1 * 2 + 3 * 3 + 4 * 9 + 5 * 10 + 6 * 4 + 7 * 1

राशि (f (x n)) = 1 + 3 + 9 + 10 + 4 + 1

एक्स = 128/28 = 4,57

और वाई-अक्ष के लिए दोहराना।

+0

यह बहुत अच्छी तरह से काम करता है। यह मेरे स्पलीन कार्यान्वयन की तुलना में मेरे लिए बहुत तेज़ चलता है। यह बहुत वास्तविक समय है! सुझाव के लिए धन्यवाद। – bufferz

+0

लिंक के बारे में: बस शीर्षक खोजें। शीर्ष हिट: http://groups.mrl.illinois.edu/granick/Publications/pdf%20files/2009/stephen_2009_image%20analysis%20with%20rapid%20and%20accurate%202d%20gaussian%20fit.pdf – jnm2

5

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

[http://www.codeproject.com/KB/cs/Intel_OpenCV.aspx][1]

OpenCV भी मदद कर सकते हैं आसानी से बिंदु केन्द्रों खोजने के लिए और प्रत्येक अंक पर नज़र रखने के।

वहाँ एक कारण है कि आप एक 120fps कैमरे का उपयोग कर रहे हैं? आप जानते हैं कि मानव आंख केवल 30 एफपीएस सही देख सकती है? मुझे लगता है कि यह बहुत तेज़ लेजर आंदोलनों का पालन करना है ... आप इसे नीचे लाने पर विचार करना चाहेंगे, क्योंकि 120fps की रीयल-टाइम प्रोसेसिंग बहुत मुश्किल होगी।

4

उच्चतम बाइट एक एमएस के भीतर चलाना चाहिए खोजने के लिए 640 * 480 बाइट्स के माध्यम से चल रहा है। धीमी प्रोसेसर पर भी। शेडर्स का मार्ग लेने की जरूरत नहीं है।

मैं अपने पाश अनुकूलन करने के लिए सलाह होगा।उदाहरण के लिए : यह वास्तव में धीमी है (क्योंकि यह हर सरणी देखने के साथ एक गुणा करता है):

byte highest=0; 
foundX=-1, foundY=-1; 
for(y=0; y<480; y++) 
{ 
    for(x=0; x<640; x++) 
    { 
     if(myBytes[x][y] > highest) 
     { 
      highest = myBytes[x][y]; 
      foundX = x; 
      foundY = y; 
     } 
    } 
} 

इस तेज हो गया है:

byte [] myBytes = new byte[640*480]; 
//fill it with your image 

byte highest=0; 
int found=-1, foundX=-1, foundY=-1; 
int len = 640*480; 
for(i=0; i<len; i++) 
{ 
    if(myBytes[i] > highest) 
    { 
     highest = myBytes[i]; 
     found = i; 
    } 
} 
if(found!=-1) 
{ 
    foundX = i%640; 
    foundY = i/640; 
} 

इस के लिए खेद है मेरे सिर के ऊपर से है त्रुटियां; ^)

3

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

मुझे लगता है कि सबसे बड़ा मुद्दा यह है कि आप उस डेटा को GPU को पर्याप्त तेज़ी से ले जा सकते हैं या नहीं।

+0

मैं GPU में फ्रेम पर एकल उच्चतम पिक्सेल को कैसे ट्रैक कर सकता हूं? क्या मैं इस सही को समझ रहा हूं कि गूंगा कोर स्मृति को इस तरह से साझा नहीं कर सकता है जिससे उन्हें पिक्सेल की तुलना पिछले चमकदार पिक्सेल से मिल सके? – bufferz

+1

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

+1

आपके मामले में, आप * तत्काल * पिछले चमकदार पिक्सेल की तुलना नहीं कर सकते हैं, क्योंकि इनमें से कोई भी (128 कहता है) 128 कोरों को एक उज्ज्वल पिक्सेल मिल सकता है। इसके बजाए, प्रत्येक कोर पर ध्यान केंद्रित करने की कोशिश करें, अपनी लाइन पर - लाइन में सबसे तेज पिक्सेल ढूंढें (एक साथ 128 लाइनों को प्रोसेस करना)। एक बार जब छवि में रेखाएं प्रभावी रूप से उस रेखा में सबसे चमकीले पिक्सेल के रूप में सारांशित की गई हैं, तो आप एक धारावाहिक तरीके से समग्र चमकदार पा सकते हैं। – David

1

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

(फोकस कैमरा से बाहर मामूली मदद मिलेगी सिर्फ प्रतिभाशाली अंक मिलता है और झूठे सकारात्मक को कम करता है, तो आप एक व्यस्त सतह है ... निश्चित रूप से यह मानते हुए कि आप एक चिकनी/सपाट सतह की शूटिंग नहीं कर रहे हैं) एक और अनुकूलन

2

विचार करने के लिए: यदि आप चित्रकारी कर रहे हैं, तो पॉइंटर का वर्तमान स्थान शायद पॉइंटर का अंतिम स्थान बंद कर देता है। फ्रेम के बीच सूचक की आखिरी दर्ज स्थिति याद रखें, और केवल उस स्थिति के करीब एक क्षेत्र को स्कैन करें ... 1'x1 'क्षेत्र कहें। केवल तभी जब उस क्षेत्र में पॉइंटर नहीं मिलता है तो क्या आप पूरी सतह को स्कैन कर सकते हैं।

जाहिर है, आपके प्रोग्राम को कितनी तेज़ी से स्कैन कर सकते हैं, और कैमरे को "खोने" से पहले कितनी जल्दी आप माउस को स्थानांतरित करने में सक्षम होंगे और धीमे, पूर्ण-छवि पर जाना होगा स्कैन। थोड़ा प्रयोग शायद इष्टतम मूल्य प्रकट करेगा।

कूल परियोजना, वैसे भी।

+0

क्यों केवल 1x1। क्यों आकार 1^2 वृद्धि नहीं है। तो यदि 1x1 में नहीं मिला तो यह 2x2, 4x4 इत्यादि की जांच करेगा। थोड़ी सी देखभाल और आप उस क्षेत्र में आगे बढ़ सकते हैं जिसे आपने पहले ही चेक कर लिया है। –

+0

मैंने इसके बारे में भी सोचा। लेकिन उसके पास कई लेजर हो सकते हैं, इसलिए उसे हर पिक्सेल को देखना होगा। एक लेजर बिना किसी सूचना के क्षेत्र को चालू या पुन: पेश कर सकता है। – Nosredna

1

ब्लैक आउटपुट बफर के साथ प्रारंभ करें। अभी के लिए उप-पिक्सेल भूल जाओ। प्रत्येक फ्रेम, प्रत्येक पिक्सेल, यह करें:

आउटबफ = अधिकतम (आउटबफ, इनबफ);

जब आप छवि के साथ काम करते हैं तो उप-पिक्सेल को तीसरे "साफ" बफर पर फ़िल्टर करना करें। या रीयल टाइम में एक समय में एक खंड या स्क्रीन की एक पंक्ति करें। लाभ: ड्राइंग के वास्तविक समय "मोटे" दृश्य, जब आप जाते हैं तो साफ हो जाता है।

जब आप किसी न किसी आउटपुट बफर से "साफ" तीसरे बफर में कनवर्ट करते हैं, तो आप किसी न किसी काले रंग को साफ़ कर सकते हैं। यह आपको धीमा किए बिना हमेशा के लिए ड्राइंग रखने देता है।

"किसी न किसी" रंग में "साफ" को चित्रित करके, शायद थोड़ा अलग रंग में, आप दोनों दुनिया के सर्वश्रेष्ठ होंगे।

यह पेंट प्रोग्राम के समान है - यदि आप वास्तव में तेज़ी से आकर्षित करते हैं, तो आप एक मोटा संस्करण देखते हैं, तो पेंट प्रोग्राम समय के साथ छवि को "साफ़ करता है"।


एल्गोरिथ्म पर कुछ टिप्पणियां:

मैं इस क्षेत्र में धोखा का एक बहुत देखा है। मैंने एक सेगा उत्पत्ति एमुलेटर पर ध्वनि खेला है जो upsamples। और इसमें कुछ सुंदर जंगली एल्गोरिदम हैं जो बहुत अच्छी तरह से काम करते हैं और बहुत तेज़ होते हैं।

आपके पास वास्तव में कुछ फायदे हैं जो आप प्राप्त कर सकते हैं क्योंकि आपको डॉट पर चमक और त्रिज्या पता हो सकता है।

आप बस प्रत्येक पिक्सेल और उसके 8 पड़ोसियों को देख सकते हैं और उन 9 पिक्सेल को "चमक" के लिए अपनी चमक के अनुसार "उपन्यास" कहने दें।


अन्य विचारों

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

कैटमूल-रोम स्पलीन का उपयोग करें, जो सभी नियंत्रण बिंदुओं के माध्यम से जाता है।

+0

मुझे यह विचार पसंद है, यह सही समझ में आता है। तो शायद "साफ" पिक्सेल का प्रतिनिधित्व करें जिसमें 5x5 पिक्सेल मान वाले structs हैं और एक अलग थ्रेड पर कतार में उनके माध्यम से जाएं। फिर भी, इस कतार के माध्यम से जलना एक बड़े पैमाने पर सीपीयू उपक्रम होगा। हो सकता है कि मैं इन structs में से प्रत्येक को एक कशेरुक में स्टोर कर सकता हूं और वीडियो कार्ड पर स्पलीन वक्र कर सकता हूं? मैं अभी भी 5x5 2 डी splines की गणना करने के लिए एक प्रकाश तेज रास्ता तलाश रहा हूँ। इस उच्च स्तर के सुझाव के लिए धन्यवाद! – bufferz

+0

यह वास्तव में कोई फर्क नहीं पड़ता कि यह कितना धीमा है। आप बाद में अनुकूलित कर सकते हैं। आप केवल टाइमर देखते हैं और देखते हैं कि आप प्रत्येक फ्रेम को कितनी स्क्रीन कर सकते हैं। – Nosredna

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