मुझे ओपनसीवी में आपके जैसी समस्या के साथ सामना करना पड़ा था। मेरे पास एक स्टीरियो छवि जोड़ी थी और मैं कैमरों के बाहरी मानकों और सभी मनाए गए बिंदुओं के विश्व निर्देशांक की गणना करना चाहता था। इस समस्या का इलाज यहां किया गया है:
बेर्थोल्ड के पी। हॉर्न। सापेक्ष अभिविन्यास पुनरीक्षित। बेर्थोल्ड के पी हॉर्न। आर्टिफिशियल इंटेलिजेंस प्रयोगशाला, मैसाचुसेट्स इंस्टीट्यूट ऑफ टेक्नोलॉजी, 545 प्रौद्योगिकी ...
http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.64.4700
हालांकि, मैं इस समस्या (शायद आप एक मिल जाएगा) का एक उपयुक्त कार्यान्वयन को खोजने के लिए सक्षम नहीं था। समय सीमाओं के कारण मेरे पास इस पेपर में सभी गणित को समझने और इसे स्वयं लागू करने का समय नहीं था, इसलिए मैं एक त्वरित और गंदे समाधान के साथ आया जो मेरे लिए काम करता है। मैं समझाऊंगा कि मैंने इसे हल करने के लिए क्या किया:
मान लें कि हमारे पास दो कैमरे हैं, जहां पहले कैमरे के बाहरी पैरामीटर आरटी = मैटक्स :: आंख() हैं। अब दूसरे कैमरे के घूर्णन आर के बारे में अनुमान लगाएं। दोनों छवियों में देखी गई छवि बिंदुओं की प्रत्येक जोड़ी के लिए, हम विश्व समन्वय में उनकी संबंधित किरणों के निर्देशों की गणना करते हैं और उन्हें 2 डी-सरणी dirs में संग्रहीत करते हैं (संपादित करें: आंतरिक कैमरा पैरामीटर ज्ञात माना जाता है)। हम ऐसा इसलिए कर सकते हैं क्योंकि हम मानते हैं कि हम हर कैमरे के अभिविन्यास को जानते हैं। अब हम एक अतिरंजित रैखिक प्रणाली एसी = 0 बनाते हैं जहां सी दूसरे कैमरे का केंद्र है। मैं समारोह एक गणना करने के लिए प्रदान करते हैं:
Mat buildA(Matx<double, 3, 3> &R, Array<Vec3d, 2> dirs)
{
CV_Assert(dirs.size(0) == 2);
int pointCount = dirs.size(1);
Mat A(pointCount, 3, DataType<double>::type);
Vec3d *a = (Vec3d *)A.data;
for (int i = 0; i < pointCount; i++)
{
a[i] = dirs(0, i).cross(toVec(R*dirs(1, i)));
double length = norm(a[i]);
if (length == 0.0)
{
CV_Assert(false);
}
else
{
a[i] *= (1.0/length);
}
}
return A;
}
फिर बुला सीवी :: SVD :: solveZ (ए) आप इस प्रणाली के लिए आदर्श 1 के कम से कम वर्गों समाधान दे देंगे। इस तरह, आप दूसरे कैमरे के घूर्णन और अनुवाद प्राप्त करते हैं। हालांकि, चूंकि मैंने दूसरे कैमरे के घूर्णन के बारे में अनुमान लगाया है, इसलिए मैं इसके घूर्णन के बारे में कई अनुमान लगाता हूं (3x1 वेक्टर ओमेगा का उपयोग करके पैरामीटर किया गया है जिसमें से मैं सीवी :: रॉड्रिग्स का उपयोग करके रोटेशन मैट्रिक्स की गणना करता हूं) और फिर मैं इस अनुमान को परिष्कृत करता हूं संख्यात्मक जैकोबियन के साथ लेवेनबर्ग-मार्वार्ड ऑप्टिमाइज़र में दोबारा सिस्टम एसी = 0 को हल करना। यह मेरे लिए काम करता है लेकिन यह थोड़ा गंदा है, इसलिए यदि आपके पास समय है, तो मैं आपको कागज में जो समझाया गया है उसे लागू करने के लिए प्रोत्साहित करता हूं।
संपादित करें:
यहाँ अवशेषों की वेक्टर के मूल्यांकन के लिए Levenberg-Marquardt अनुकूलक में नियमित है:
void Stereo::eval(Mat &X, Mat &residues, Mat &weights)
{
Matx<double, 3, 3> R2Ref = getRot(X); // Map the 3x1 euler angle to a rotation matrix
Mat A = buildA(R2Ref, _dirs); // Compute the A matrix that measures the distance between ray pairs
Vec3d c;
Mat cMat(c, false);
SVD::solveZ(A, cMat); // Find the optimum camera centre of the second camera at distance 1 from the first camera
residues = A*cMat; // Compute the output vector whose length we are minimizing
weights.setTo(1.0);
}
वैसे, मैं इंटरनेट पर एक छोटे से अधिक खोज की है और पाया कुछ अन्य कोड जो कैमरा के बीच सापेक्ष अभिविन्यास की गणना के लिए उपयोगी हो सकते हैं। मैं अभी तक किसी भी कोड की कोशिश की है नहीं, लेकिन यह उपयोगी लगता है:
http://www9.in.tum.de/praktika/ppbv.WS02/doc/html/reference/cpp/toc_tools_stereo.html
http://lear.inrialpes.fr/people/triggs/src/
http://www.maths.lth.se/vision/downloads/
यह स्पष्ट नहीं है अगर आप जानते हैं 3 डी दुनिया अंक है कि आप का पालन के निर्देशांक ऊपर विभिन्न छवियों में। यदि ऐसा है, तो यह एक परिप्रेक्ष्य-एन-पॉइंट-समस्या है और आप यहां उपलब्ध ईपीएनपी एल्गोरिदम का उपयोग करके प्रत्येक कैमरे के पैरामीटर को कैलिब्रेट कर सकते हैं: http://cvlab.epfl.ch/software/EPnP/index.php। अन्यथा, नीचे मेरा जवाब देखें। – Rulle
फोटोग्राफ ऑब्जेक्ट के 3 डी निर्देशांक अज्ञात हैं। –
यदि ऑब्जेक्ट पर बिंदुओं के 3 डी वर्ल्ड निर्देशांक _unknown_ हैं, तो मुझे नहीं लगता कि cv :: calibrateCamera काम करेगा, क्योंकि ऐसा लगता है कि ऑब्जेक्ट पॉइंट _known_ हैं। – Rulle