3

私は OpenCV 用の EmguCV ラッパーを使用しており、基本行列を介して校正されていない整流を実行しようとしています。

両方のカメラから FindChessboardCorners 関数を使用して画像ポイントを見つけました。次に基本行列を見つけたいのですが、関数 eCvInvoke.cvFindFundamentalMat() CvInvoke.cvFindFundamentalMat()にパラメーターを渡す際に問題があります。

私を悩ませているのは、2D ポイントの配列です。それを OpenCv 関数 cvFindFundamentalMat に渡すための適切な形式を取得できません。

私が理解しているように、EmguCV/OpenCV openCv は、IntPtr を介して渡された CvMat 型の 1 次元配列を想定しています...しかし、そうしても、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);

私は何を間違っていますか?

4

1 に答える 1

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;
}
于 2012-04-29T15:17:12.710 に答える