7

मैं अपने वेबकैम का उपयोग करके ज्ञात वैश्विक स्थितियों के साथ चार फिडियसियल की एक छवि से वैश्विक अनुमान अनुमान प्राप्त करने की कोशिश कर रहा हूं।कैमरा पॉज़ अनुमान (ओपनसीवी पीएनपी)

मैंने कई स्टैकएक्सचेंज प्रश्न और कुछ कागजात देखे हैं और मुझे सही समाधान नहीं मिल रहा है। मैं जो पद संख्या प्राप्त करता हूं वह दोहराया जा सकता है लेकिन कैमरे के आंदोलन के लिए रैखिक रूप से आनुपातिक नहीं है। एफवाईआई मैं सी ++ ओपनसीवी 2.1 का उपयोग कर रहा हूं।

At this link is pictured मेरे समन्वय सिस्टम और नीचे उपयोग किए गए परीक्षण डेटा।

% Input to solvePnP(): 
imagePoints =  [ 481, 831; % [x, y] format 
        520, 504; 
        1114, 828; 
        1106, 507] 
objectPoints = [0.11, 1.15, 0; % [x, y, z] format 
       0.11, 1.37, 0; 
       0.40, 1.15, 0; 
       0.40, 1.37, 0] 

% camera intrinsics for Logitech C910 
cameraMat = [1913.71011, 0.00000, 1311.03556; 
      0.00000, 1909.60756, 953.81594; 
      0.00000, 0.00000, 1.00000] 
distCoeffs = [0, 0, 0, 0, 0] 

% output of solvePnP(): 
tVec = [-0.3515; 
     0.8928; 
     0.1997] 

rVec = [2.5279; 
     -0.09793; 
     0.2050] 
% using Rodrigues to convert back to rotation matrix: 

rMat = [0.9853, -0.1159, 0.1248; 
     -0.0242, -0.8206, -0.5708; 
     0.1686, 0.5594, -0.8114] 

अब तक, किसी को भी कुछ भी इन नंबरों के साथ कुछ गलत देख सकते हैं? मैं इसकी सराहना करता हूं अगर कोई उन्हें उदाहरण के लिए MatLAB (ऊपर कोड एम-फाइल अनुकूल है) में जांच करेगा।

इस बिंदु से, मुझे यकीन है कि आरएमएटी और टीवीईसी से वैश्विक मुद्रा कैसे प्राप्त करें। मैं क्या this question में पढ़ा है, rMat और tVec से मुद्रा प्राप्त करने के लिए से बस है:

position = transpose(rMat) * tVec % matrix multiplication 

हालांकि मैं अन्य स्रोतों मैं इसे इतना आसान नहीं है पढ़ा है कि से संदेह है।

असली दुनिया निर्देशांक में कैमरे की स्थिति प्राप्त करने के लिए, मुझे क्या करने की ज़रूरत है? जैसा कि मुझे अनिश्चितता है कि यह एक कार्यान्वयन समस्या है (हालांकि संभवतः एक सिद्धांत समस्या है) मैं किसी ऐसे व्यक्ति के लिए चाहूंगा जिसने इस प्रश्न का उत्तर देने के लिए ओपनसीवी में सफलतापूर्वक पीएनपी फ़ंक्शन का उपयोग किया हो, हालांकि किसी भी विचार का स्वागत है!

आपके समय के लिए बहुत बहुत धन्यवाद।

+0

आप tVec उलटा भूल गया। तो ऐसा करने का सही तरीका है -ट्रांस (आरएमएटी) * टीवीईसी – Vlad

उत्तर

4

मैंने इसे थोड़ी देर पहले हल किया, साल की देरी के लिए क्षमा मांगे।

_, rVec, tVec = cv2.solvePnP(objectPoints, imagePoints, cameraMatrix, distCoeffs) 
Rt = cv2.Rodrigues(rvec) 
R = Rt.transpose() 
pos = -R * tVec 

अब स्थिति:

अजगर OpenCV 2.1 मैं उपयोग कर रहा था, और नए संस्करण 3.0.0-देव में, मुझे लगता है कि वैश्विक फ्रेम चीज़ें आवश्यक हैं में कैमरे के मुद्रा प्राप्त करने के लिए सत्यापित किया है वैश्विक फ्रेम में व्यक्त कैमरे की स्थिति है (उसी फ्रेम को ऑब्जेक्ट पॉइंट्स में व्यक्त किया गया है)। आर एक रवैया मैट्रिक्स डीसीएम है जो रवैया को स्टोर करने के लिए एक अच्छा रूप है। आप यूलर कोण तो आप परिवर्तित कर सकते हैं डीसीएम यूलर के लिए एक XYZ रोटेशन अनुक्रम का उपयोग को देखते हुए कोण की आवश्यकता होती है:

roll = atan2(-R[2][1], R[2][2]) 
pitch = asin(R[2][0]) 
yaw = atan2(-R[1][0], R[0][0]) 
+0

ओपनसीवी में एक्स-वाई-जेड समन्वय प्रणाली नहीं है। ओपनसीवी के साथ यूलर कोणों में कैसे परिवर्तित करें? –

+1

@tokam 'क्या आपके पास एक्स-वाई-जेड समन्वय प्रणाली नहीं है' का क्या मतलब है? ओपनसीवी 3.0 में 'RQdecomp3x3' फ़ंक्शन है। मैंने पाया कि यह मुझे इंटरनेट पर कभी-कभी मिलने वाले रूपांतरण के समान परिणाम देता है (उदाहरण के लिए यहां http://nghiaho.com/?page_id=846): 'theta_x = atan2 (Rat (2,1), आर (2,2)); theta_y = atan2 (-R.at (2,0), वर्ग (पाउट (आरएटी (2,1), 2) + पाउ (आरएट (2,2), 2)); theta_z = atan2 (आरएटी (1,0), आरएट (0,0)); ' – oarfish

+0

मुझे लगता है कि ओपनसीवी की समन्वय प्रणाली हवाई जहाज और अन्य क्षेत्रों के लिए मानक समन्वय प्रणाली से अलग है। –

2

कैमरा की स्थिति {- ट्रांसपोज़ (आर) * टी} होगी। बस।

और आपने सबकुछ ठीक से किया है, सीवी :: resolPnp अगर मुझे सही याद है तो अनुवाद के लिए (4 x 1) वेक्टर देता है, तो आपको w, y, z को w समन्वय के साथ विभाजित करना होगा।

+0

अवनिंद्रा, आपके उत्तर के लिए धन्यवाद। हल करें पीएनपी ने मेरे लिए कभी भी 4x1 वेक्टर नहीं लौटाया है, मुझे लगता है कि मैंने सोर्स कोड में जो देखा वह उससे नियमित (डी-सामान्यीकृत) रूप में वापस आ गया है। क्या यह हो सकता है कि मैं कैमरे के इंट्रिनिक्स के लिए उपयोग कर रहे मान गलत हैं (मैंने कुछ तत्वों को अस्वीकार करने का प्रयास करने की सलाह दी है), या मेरे फ्रेम गलत तरीके से परिभाषित किए गए हैं? धन्यवाद। – Gouda

+0

मैं सहमत हूं लेकिन कुछ अजीब कारणों के लिए- टी * आरटी() वह है जो इसे काम करता है। – Vlad

4

आप वैश्विक मुद्रा एक 4x4 कैमरा मुद्रा मैट्रिक्स, जो ओपन में इस्तेमाल किया जा सकता है के साथ मतलब है, मैं इसे इस तरह

CvMat* ToOpenGLCos(const CvMat* tVec, const CvMat* rVec) 
{ 
    //** flip COS 180 degree around x-axis **// 

    // Rodrigues to rotation matrix 
    CvMat* extRotAsMatrix = cvCreateMat(3,3,CV_32FC1); 
    cvRodrigues2(rVec,extRotAsMatrix); 

    // Simply merge rotation matrix and translation vector to 4x4 matrix 
    CvMat* world2CameraTransformation = CreateTransformationMatrixH(tVec, 
    extRotAsMatrix); 

    // Create correction rotation matrix (180 deg x-axis) 
    CvMat* correctionMatrix = cvCreateMat(4,4,CV_32FC1); 
    /* 1.00000 0.00000 0.00000 0.00000 
     0.00000 -1.00000 -0.00000 0.00000 
     0.00000 0.00000 -1.00000 0.00000 
     0.00000 0.00000 0.00000 1.00000 */ 
    cvmSet(correctionMatrix,0,0,1.0); cvmSet(correctionMatrix,0,1,0.0); 
    ... 

    // Flip it 
    CvMat* world2CameraTransformationOpenGL = cvCreateMat(4,4,CV_32FC1); 
    cvMatMul(correctionMatrix,world2CameraTransformation, world2CameraTransformationOpenGL); 

    CvMat* camera2WorldTransformationOpenGL = cvCreateMat(4,4,CV_32FC1); 
    cvInv(world2CameraTransformationOpenGL,camera2WorldTransformationOpenGL, 
    CV_LU); 

    cvReleaseMat(&world2CameraTransformationOpenGL); 
    ... 

    return camera2WorldTransformationOpenGL; 
} 

मैं समन्वय प्रणाली के लिए आवश्यक है flipping लगता है, क्योंकि OpenCV और ओपन/VTK/आदि। विभिन्न चित्रांक प्रणालियों का उपयोग करें, जैसा कि इस तस्वीर में चित्रित OpenGL and OpenCV Coordinate Systems

अच्छा, यह इस तरह से काम करता है लेकिन किसी के पास बेहतर स्पष्टीकरण हो सकता है।

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