2011-09-14 6 views
15

को देखते हुए लगातार दो 3 डी बिंदु बादल 1 और 2 (न कि पूरी बादल, OpenCV के GoodFeaturesToMatch साथ बादल से चयनित 100 अंक कहते हैं), एक Kinect depthmap से प्राप्त है, मैं कैमरे के homography की गणना करना चाहते हैं 1 से 2 तक। मैं समझता हूं कि यह एक प्रोजेक्टिव ट्रांसफॉर्म है, और यह पहले से ही कई लोगों द्वारा किया जा चुका है: here (slide 12), here (slide 30) और here in what seems to be the classic paper। मेरी समस्या यह है कि जब भी मैं एक सक्षम प्रोग्रामर हूं, मुझे गणित या ट्रिगर कौशल नहीं मिला है ताकि उन तरीकों में से एक को कोड में बदल दिया जा सके। चूंकि यह एक आसान समस्या नहीं है, मैं कोड के लिए एक बड़ी इनाम प्रदान करता हूं जो निम्न समस्या हल करता है:निकालें प्रक्षेपीय homography नक्शे

कैमरे मूल पर है, जेड दिशा में अनियमित पेंटाहेड्रॉन [ए, बी, सी, डी , ई, एफ]: camera position 1

कैमरा चाल छोड़ दिया (एक्स) के लिए -90mm, + 60 मिमी अप (वाई), + 50 मिमी फारवर्ड (जेड) और घूमता है 5 डिग्री नीचे, 10 डिग्री सही और -3 ° घड़ी की विपरीत दिशा: camera position 2

पूरे दृश्य घूर्णन ताकि कैमरा अपनी मूल स्थिति में वापस आ गया है मुझे 2 में कोने के स्थानों को निर्धारित करने के लिए अनुमति देते हैं: enter image description here

3DS मैक्स तैयार करने के लिए इस max 1, max 2 और max 3

यहाँ उपयोग की गई फ़ाइलों से पहले और बाद कोने की स्थिति, intrinsics, आदि .: vertices and intrinsics

ध्यान दें कि camera2 के कोने हैं 100% सटीक नहीं, जानबूझकर शोर का थोड़ा सा है।

here are the numbers in an Excel file

कोड की आवश्यकता है, जो में VB.Net या सी # आसानी से अनुवाद होना चाहिए, EmguCV और OpenCV जहां आवश्यक हो, कोने के 2 सेट और intrinsics लेता है और इस उत्पादन का उत्पादन का उपयोग कर:

Camera 2 is at -90 X, +60 Y, +50 Z rotated -5 Y, 10 X, -3 Z. 
The homography matrix to translate points in A to B is: 
a1, a2, a3 
b1, b2, b3 
c1, c2, c3 

मैं अगर homography समरूप निर्देशांक के लिए 3X3 या 3X4 है पता नहीं है, लेकिन यह मुझे 2.

1 से कोने अनुवाद करने के लिए मैं भी मान a1 पता नहीं है, a2 की अनुमति देनी चाहिए, आदि; आपको यही मिलना है> ;-)

500 बाउंटी ऑफर this very similar question पर दिए गए बक्षीस को 'प्रतिस्थापित करता है', मैंने इस प्रश्न को इंगित करते हुए एक टिप्पणी जोड़ा है।

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

+0

हाय, मेरे फिर से मैं एक नज़र होने दिया गया है और हाँ मुझे लगता है कि इस opencv में douable है और उम्मीद है कि मैं काम कर रहा EMGU कोड प्राप्त करने के कोशिश कर रहा हूँ, लेकिन इसके लिए कुछ समय लग रहा स्टैंड के तहत। ओपनसीवी में कैलिब्रेट कैमरे 2 को दस्तावेज की आवश्यकता होनी चाहिए: http://opencv.willowgarage.com/documentation/python/calib3d_camera_calibration_and_3d_reconstruction.html#calibratecamera2 मुझे ओपनसीवी में एक उदाहरण मिला है http://www.neuroforge.co .uk/index.php/77-tutorials/78-camera-calibration-python-opencv जो अब आवश्यक है, उसे उस चीज़ में ट्रांसफ़ॉर्म कर रहा है जिसका आप उपयोग कर सकते हैं, एक आशा लें कि यह – Chris

उत्तर

1

2 डी या 3 डी बिंदु बादलों के दो स्नैपशॉट्स के बीच कंप्यूटिंग अंतर के लिए उपयोग करने के लिए "सही" एल्गोरिदम को आईसीपी (Iterative Closest Point) कहा जाता है। एल्गोरिदम हल ICP

मानव-पठनीय प्रारूप में: दिए गए बिंदु सेट के लिए पी 1 और पी 2 रोटेशन मैट्रिक्स आर और अनुवाद टी ढूंढते हैं जो पी 1 से पी 2 को बदलता है। बस सुनिश्चित करें कि वे अपने मूल के आसपास सामान्यीकृत हैं।

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

इस रुचि रखने वालों के लिए कम्प्यूटेशनल ज्यामिति प्रसंस्करण

+1

स्वीकृत है, क्योंकि यह औपचारिक रूप से सही उत्तर है, समाधान खोजने में कोई मदद नहीं है। (मैंने पहले ही संकेत दिया था कि जब मैंने कब्स का उल्लेख किया था तो मैं आईसीपी के बारे में जानता था)। – smirkingman

1

समान जरूरतों के साथ उन लोगों के लिए कुछ के साथ प्राप्त किया जा सकता है, तो यहां एक आंशिक Kabsch के कलन विधि का उपयोग अनुवाद और 3 डी ज्यामिति का एक टुकड़ा के इष्टतम रोटेशन निर्धारित करने के लिए समाधान है:

Imports Emgu 
Imports Emgu.CV 
Imports Emgu.CV.Structure 
Imports Emgu.CV.CvInvoke 
Imports Emgu.CV.CvEnum 
Imports System.Math 

Module Module1 
    ' A 2*2 cube, centred on the origin 
    Dim matrixA(,) As Double = {{-1, -1, -1}, 
           {1, -1, -1}, 
           {-1, 1, -1}, 
           {1, 1, -1}, 
           {-1, -1, 1}, 
           {1, -1, 1}, 
           {-1, 1, 1}, 
           {1, 1, 1} 
           } 
    Dim matrixB(,) As Double 
    Function Translate(ByVal mat As Matrix(Of Double), ByVal translation As Matrix(Of Double)) As Matrix(Of Double) 

     Dim tx As New Matrix(Of Double)({{1, 0, 0, 0}, 
             {0, 1, 0, 0}, 
             {0, 0, 1, 0}, 
             {translation(0, 0), translation(1, 0), translation(2, 0), 1}}) 
     Dim mtx As New Matrix(Of Double)(mat.Rows, mat.Cols + 1) 

     ' Convert from Nx3 to Nx4 
     For i As Integer = 0 To mat.Rows - 1 
      For j As Integer = 0 To mat.Cols - 1 
       mtx(i, j) = mat(i, j) 
      Next 
      mtx(i, mat.Cols) = 1 
     Next 

     mtx = mtx * tx 
     Dim result As New Matrix(Of Double)(mat.Rows, mat.Cols) 
     For i As Integer = 0 To mat.Rows - 1 
      For j As Integer = 0 To mat.Cols - 1 
       result(i, j) = mtx(i, j) 
      Next 
     Next 
     Return result 
    End Function 
    Function Rotate(ByVal mat As Matrix(Of Double), ByVal rotation As Matrix(Of Double)) As Matrix(Of Double) 
     Dim sinx As Double = Sin(rotation(0, 0)) 
     Dim siny As Double = Sin(rotation(1, 0)) 
     Dim sinz As Double = Sin(rotation(2, 0)) 
     Dim cosx As Double = Cos(rotation(0, 0)) 
     Dim cosy As Double = Cos(rotation(1, 0)) 
     Dim cosz As Double = Cos(rotation(2, 0)) 
     Dim rm As New Matrix(Of Double)(3, 3) 
     rm(0, 0) = cosy * cosz 
     rm(0, 1) = -cosx * sinz + sinx * siny * cosz 
     rm(0, 2) = sinx * sinz + cosx * siny * cosz 
     rm(1, 0) = cosy * sinz 
     rm(1, 1) = cosx * cosz + sinx * siny * sinz 
     rm(1, 2) = -sinx * cosz + cosx * siny * sinz 
     rm(2, 0) = -siny 
     rm(2, 1) = sinx * cosy 
     rm(2, 2) = cosx * cosy 
     Return mat * rm 
    End Function 
    Public Sub Main() 

     Dim ma As Matrix(Of Double) 
     Dim mb As Matrix(Of Double) 

     ma = New Matrix(Of Double)(matrixA) 

     ' Make second matrix by rotating X=5°, Y=6°, Z=7° and translating X+2, Y+3, Z+4 
     mb = ma.Clone 
     mb = Rotate(mb, New Matrix(Of Double)({radians(5), radians(6), radians(7)})) 
     mb = Translate(mb, New Matrix(Of Double)({2, 3, 4})) 

     Dim tx As Matrix(Of Double) = Nothing 
     Dim rx As Matrix(Of Double) = Nothing 
     Dim ac As Matrix(Of Double) = Nothing 
     Dim bc As Matrix(Of Double) = Nothing 
     Dim rotation As Matrix(Of Double) = Nothing 
     Dim translation As Matrix(Of Double) = Nothing 
     Dim xr As Double, yr As Double, zr As Double 

     Kabsch(ma, mb, ac, bc, translation, rotation, xr, yr, zr) 
     ShowMatrix("A centroid", ac) 
     ShowMatrix("B centroid", bc) 
     ShowMatrix("Translation", translation) 
     ShowMatrix("Rotation", rotation) 
     console.WriteLine(degrees(xr) & "° " & degrees(yr) & "° " & degrees(zr) & "°") 

     System.Console.ReadLine() 
    End Sub 
    Function radians(ByVal a As Double) 
     Return a * Math.PI/180 
    End Function 
    Function degrees(ByVal a As Double) 
     Return a * 180/Math.PI 
    End Function 
    ''' <summary> 
    ''' Compute translation and optimal rotation between 2 matrices using Kabsch's algorithm 
    ''' </summary> 
    ''' <param name="p">Starting matrix</param> 
    ''' <param name="q">Rotated and translated matrix</param> 
    ''' <param name="pcentroid">returned (3,1), centroid(p)</param> 
    ''' <param name="qcentroid">returned (3,1), centroid(q)</param> 
    ''' <param name="translation">returned (3,1), translation to get q from p</param> 
    ''' <param name="rotation">returned (3,3), rotation to get q from p</param> 
    ''' <param name="xr">returned, X rotation in radians</param> 
    ''' <param name="yr">returned, Y rotation in radians</param> 
    ''' <param name="zr">returned, Z rotation in radians</param> 
    ''' <remarks>nomeclature as per http://en.wikipedia.org/wiki/Kabsch_algorithm</remarks> 
    Sub Kabsch(ByVal p As Matrix(Of Double), ByVal q As Matrix(Of Double), 
       ByRef pcentroid As Matrix(Of Double), ByRef qcentroid As Matrix(Of Double), 
       ByRef translation As Matrix(Of Double), ByRef rotation As Matrix(Of Double), 
       ByRef xr As Double, ByRef yr As Double, ByRef zr As Double) 

     Dim zero As New Matrix(Of Double)({0, 0, 0}) 
     Dim a As Matrix(Of Double) 
     Dim v As New Matrix(Of Double)(3, 3) 
     Dim s As New Matrix(Of Double)(3, 3) 
     Dim w As New Matrix(Of Double)(3, 3) 
     Dim handed As Matrix(Of Double) 
     Dim d As Double 

     pcentroid = Centroid(p) 
     qcentroid = Centroid(q) 
     translation = qcentroid - pcentroid 
     p = Translate(p, zero - pcentroid) ' move p to the origin 
     q = Translate(q, zero - qcentroid) ' and q too 
     a = p.Transpose * q ' 3x3 covariance 
     cvSVD(a, s, v, w, SVD_TYPE.CV_SVD_DEFAULT) 
     d = System.Math.Sign(a.Det) 
     handed = New Matrix(Of Double)({{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}) 
     handed.Data(2, 2) = d 
     rotation = v * handed * w.Transpose ' optimal rotation matrix, U 
     ' Extract X,Y,Z angles from rotation matrix 
     yr = Asin(-rotation(2, 0)) 
     xr = Asin(rotation(2, 1)/Cos(yr)) 
     zr = Asin(rotation(1, 0)/Cos(yr)) 
    End Sub 

    Function Centroid(ByVal m As Matrix(Of Double)) As Matrix(Of Double) 

     Dim result As New Matrix(Of Double)(3, 1) 
     Dim ui() As Double = {0, 0, 0} 

     For i As Integer = 0 To m.Rows - 1 
      For j As Integer = 0 To 2 
       ui(j) = ui(j) + m(i, j) 
      Next 
     Next 

     For i As Integer = 0 To 2 
      result(i, 0) = ui(i)/m.Rows 
     Next 

     Return result 

    End Function 
    Sub ShowMatrix(ByVal name As String, ByVal m As Matrix(Of Double)) 
     console.WriteLine(name) 
     For i As Integer = 0 To m.Rows - 1 
      For j As Integer = 0 To m.Cols - 1 
       console.Write(m(i, j) & " ") 
      Next 
      console.WriteLine("") 
     Next 
    End Sub 

End Module 

आउटपुट:

A centroid 
0 
0 
0 
B centroid 
2 
3 
4 
Translation 
2 
3 
4 
Rotation 
0.987108879970813 -0.112363244371414 0.113976139595516 
0.121201730390574 0.989879474775675 -0.0738157569097856 
-0.104528463267653 0.0866782944696306 0.990737439302028 
5° 6° 7° 

लेकिन मैं अभी भी समझ नहीं कैमरा का स्थान निर्धारित करने के लिए कैसे।

0

Iterative निकटतम प्वाइंट एल्गोरिथ्म (आईसीपी) अब सी # के लिए सरकारी Kinect एसडीके 1.7 का एक हिस्सा है/वीबी

कैमरा की वसूली के भीतर एक विषय है वीबी में मुद्रा तब बहुत आसान है।

http://www.microsoft.com/en-us/kinectforwindows/develop/new.aspx

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

  • कोई संबंधित समस्या नहीं^_^