2012-04-11 44 views
3

我正在使用EmguCV封裝OpenCV,我試圖通過基礎矩陣進行未校準校正。EmguCV FindFundamentalMat - 輸入參數

我發現像點與FindChessboardCorners功能,從兩個攝像頭,然後我想找個基本矩陣,但我必須傳遞參數的功能eCvInvoke.cvFindFundamentalMat() CvInvoke.cvFindFundamentalMat()

讓我困擾的是問題2D點的數組,只是無法將正確的格式傳遞給OpenCv函數cvFindFundamentalMat。因爲我已經理解了EmguCV/OpenCV,openCv期望CvMat類型的一維數組,通過IntPtr ... 但即使我這樣做,OpenCV也會拋出一條錯誤消息「OpenCV:通道數或列數或行必須= 1「

PointsF[] points1 = Camera1.Points; 
PointF[] points2 = Camera2.Points 

Matrix<float> points1 = new Matrix<float> (1, Camera1.ImagePoints[0].Length*2, 1); 
for (int i =0; i < Camera1.ImagePoints[0].Length-1; i+=2) 
{ 
     points1[0, i] = Camera1.ImagePoints[0][i].X; 
     points1[0, i+1] = Camera1.ImagePoints[0][i].Y; 
} 

Matrix<float> points2= new Matrix<float>(1, Camera2.ImagePoints[0].Length * 2, 1); 
for (int i = 0; i < Camera2.ImagePoints[0].Length-1; i+=2) 
{ 
     points1[0, i] = Camera2.ImagePoints[0][i].X; 
     points1[0, i+1] = Camera2.ImagePoints[0][i].Y; 
} 

IntPtr points1Matrix = Marshal.AllocHGlobal(StructSize.MCvMat); 
GCHandle handlePoints1Ptr = GCHandle.Alloc(points1.MCvMat, GCHandleType.Pinned); 
points1Matrix = handlePoints1Ptr.AddrOfPinnedObject(); 

IntPtr points2Matrix = Marshal.AllocHGlobal(StructSize.MCvMat); 
GCHandle handlePoints2Ptr = GCHandle.Alloc(points2.MCvMat, GCHandleType.Pinned); 
points2Matrix = handlePoints2Ptr.AddrOfPinnedObject(); 

_fundamentalMatrix = new Matrix<double>(3, 3, 1); 

CvInvoke.cvFindFundamentalMat(points1Matrix, points2Matrix, _fundamentalMatrix.Ptr, CV_FM.CV_FM_RANSAC, 1.0, 0.99, IntPtr.Zero); 

我在做什麼錯?

回答

3

這有點晚,但這是我的代碼。如果它不再幫助你,它可能會幫助其他人。我不能確切地說你的代碼有什麼問題,我自己對OpenCV非常陌生:

public void Calculate() 
{ 
    _pointCount = _leftPoints.Count; 
    IntPtr points1 = CreatePointListPointer(_leftPoints); 
    IntPtr points2 = CreatePointListPointer(_rightPoints); 
    IntPtr status = CvInvoke.cvCreateMat(1, _pointCount, MAT_DEPTH.CV_8U); 

    IntPtr fundamentalMatrix = CvInvoke.cvCreateMat(3, 3, MAT_DEPTH.CV_32F); 
    int fmCount = CvInvoke.cvFindFundamentalMat(points1, 
               points2, 
               fundamentalMatrix, 
               CV_FM.CV_FM_7POINT, 
               3.0, 
               0.99, 
               status); 
} 


public IntPtr CreatePointListPointer(IList<PointF> points) 
{ 
    IntPtr result = CvInvoke.cvCreateMat(_pointCount, 2, MAT_DEPTH.CV_32F); 

    for (int i = 0; i < _pointCount; i++) 
    { 
     double currentX = points[i].X; 
     double currentY = points[i].Y; 
     CvInvoke.cvSet2D(result, i, 0, new MCvScalar(currentX)); 
     CvInvoke.cvSet2D(result, i, 1, new MCvScalar(currentY)); 
    } 

    return result; 
}