2014-06-27 7 views
10

ओपनसीवी प्रति आरएनएएनएसी-फ़ंक्शन प्रति से कम या कम से कम इस रूप में प्रदान नहीं करता है कि आप इसे केवल कॉल कर सकते हैं और इसके साथ किया जा सकता है (उदाहरण के लिए cv::ransac(...))। RANSAC का उपयोग करने में सक्षम सभी फ़ंक्शंस/विधियों में एक ध्वज है जो इसे सक्षम बनाता है। हालांकि, यदि आप वास्तव में होमोग्राफी/मौलिक मैट्रिक्स का अनुमान लगाने के बाद इनलाइनर्स RANSAC गणनाओं के साथ कुछ और करना चाहते हैं तो उदाहरण के लिए यह हमेशा उपयोगी नहीं होता है उदाहरण के लिए ऑक्टेव या इसी तरह के सॉफ़्टवेयर/पॉइंट्स की लाइब्रेरी में एक अच्छी साजिश बनाएं, अतिरिक्त एल्गोरिदम लागू करें फ़िल्टर किए गए मैचों आदि के शेष सेटओपनसीवी: FindHomography()/findFundamental() और RANSAC

दो छवियों से मेल खाने के बाद किसी को मैचों का वेक्टर मिलता है। इसके साथ-साथ हमारे पास मुख्य बिंदुओं के प्रत्येक सेट (प्रत्येक छवि के लिए एक) है जो मिलान प्रक्रिया में उपयोग किया गया था। मैचों और कीपॉइंट्स का उपयोग करके हम अंक के दो वैक्टर बनाते हैं (उदा। cv::Point2f points) और इन्हें findHomography() पर पास करें। this और this पदों से मैंने पाया कि मास्क का उपयोग करके इनलाइनों को वास्तव में कैसे चिह्नित किया जाता है, कि हम उस कार्य को पास करते हैं। मास्क के अंदर प्रत्येक पंक्ति एक आंतरिक/बाहरी से संबंधित है। हालांकि मैं अपने दो सेट अंकों से पंक्ति-अनुक्रमणिका जानकारी का उपयोग करने का तरीका समझने में असमर्थ हूं। ओपनसीवी के स्रोत कोड को देखते हुए मुझे बहुत दूर नहीं मिला। findFundamental() (findHomography() के समान जब यह उसके हस्ताक्षर और मास्क-पार्ट की बात आती है) तो वे compressPoints() का उपयोग करते हैं, जो किसी भी तरह से इनपुट (स्रोत और गंतव्य बिंदु) के रूप में हमारे दो सेट को जोड़ती है। मास्क की प्रकृति को निर्धारित करने के लिए परीक्षण करते समय मैंने मिलान किए गए बिंदुओं के 2 सेट (cv::Keypoints से cv::Point2f - एक मानक प्रक्रिया) की कोशिश की। प्रत्येक सेट में 300 अंक होते हैं, कुल मिलाकर हमारे पास 600 अंक होते हैं। लौटा मुखौटा में 300 पंक्तियां होती हैं (इस विषय के लिए मान महत्वपूर्ण नहीं हैं)।

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

उत्तर

10

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

for(int i = 0; i < matchesObjectScene.size(); ++i) 
{ 
    // extract points from keypoints based on matches 
    pointsObject.push_back(keypointsObject.at(matchesObjectScene.at(i).queryIdx).pt); 
    pointsScene.push_back(keypointsScene.at(matchesObjectScene.at(i).trainIdx).pt); 
} 
// compute homography using RANSAC 
cv::Mat mask; 
cv::Mat H = cv::findHomography(pointsObject, pointsScene, CV_RANSAC, ransacThreshold, mask); 

उदाहरण अगर ऊपर हम

int maskRow = 10; 
std::cout << "POINTS: object(" << pointsObject.at(maskRow).x << "," << pointsObject.at(maskRow).y << ") - scene(" << pointsScene.at(maskRow).x << "," << pointsScene.at(maskRow).y << ")" << std::endl; 

और उसके बाद फिर कुछ inlier प्रिंट लेकिन इस बार हमारे keypoints (भी निकाला 2 डी अंक साथ किया जा सकता)

std::cout << "POINTS (via match-set): object(" << keypointsObject.at(matchesCurrentObject.at(maskRow).queryIdx).pt.x << "," << keypointsObject.at(matchesCurrentObject.at(maskRow).queryIdx).pt.y << ") - scene(" << keypointsScene.at(matchesCurrentObject.at(maskRow).trainIdx).pt.x << "," << keypointsScene.at(matchesCurrentObject.at(maskRow).trainIdx).pt.y << ")" << std::endl; 

का उपयोग कर हम वास्तव में एक ही आउटपुट प्राप्त करते हैं:

POINTS: object(462,199) - sscene(485,49) 
POINTS (via match-set): object(462,199) - scene(485,49) 

वास्तविक inlier हम बस अगर नकाब में वर्तमान पंक्ति वास्तव में एक 0 या गैर शून्य मान होता है की जाँच करने के लिए है पाने के लिए:

if((unsigned int)mask.at<uchar>(maskRow)) 
    // store match or keypoints or points somewhere where you can access them later 
+1

पहला वाक्य के लिए, वास्तव में नकाब में पंक्ति एक प्रतिनिधित्व नहीं करता है inlier। पंक्ति आंतरिक या बाहरी की स्थिति का प्रतिनिधित्व करती है। आगे की व्याख्या के लिए इस पोस्ट का संदर्भ लें [लिंक] (http://stackoverflow.com/questions/15815304/opencv-c-findhomography-mask-values-meaning)। –

+0

हां, यह सही है और यही मेरा मतलब था लेकिन अब जब मैं इस वाक्य को दोबारा पढ़ता हूं तो मुझे लगता है कि इसका गलत अर्थ कैसे किया जा सकता है। मै इसे बदलूंगा। – rbaleksandar

+0

लेकिन पंक्ति आंतरिक या बाहरी लोगों की स्थिति का प्रतिनिधित्व करती है लेकिन प्रत्येक आंतरिक या आउटलायर स्थिति पर कोई महत्वपूर्ण बिंदु नहीं है। वेक्टर में कीपॉइंट्स संग्रहीत हैं। तो हम मास्क में अंतर्निहित के मुख्य कुंजी बिंदु कैसे प्राप्त कर सकते हैं? – Abc

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