0

I want to undistort some points in EmguCV, but I get a CVException during execution, because the following assertion fails:

OpenCV: src.isContinuous() && (src.depth() == CV_32F || src.depth() == CV_64F) && ((src.rows == 1 && src.channels() == 2) || src.cols*src.channels() == 2)

Here's how I call the function:

                                                      //fx fy,  cx,  cy, k1, k2, p1, p2
IntrinsicParameters intrinsic = new IntrinsicParameters( 1, 1, 100, 100,  0,  0,  0,  0);

VectorOfPoint points = new VectorOfPoint(new Point[] { new Point(0, 0), new Point(255, 255) });
VectorOfPoint pointsUndistorted = new VectorOfPoint(points.Size);

CvInvoke.UndistortPoints(points, pointsUndistorted, intrinsic.CameraMatrix, intrinsic.DistorionCoefficients); 

explanation:

  1. IntrinsicParameters is a custom class that wraps all intrinsic parameters, which I used default values for). I added a comment above to denote what parameter is which
  2. I create a VectorOfPoint called points that I want to distort.
  3. I create another VectorOfPoint to hold the result
  4. The program hangs on the last line in the snippet provided. When I click pause in VisualStudio the debugger says the mentioned assertion failed.

I tried to find some explanation of what this all means but there's no comment whatsoever in the openCV source code.

What am I doing wrong here? Am I not supposed to use undistortPoints() with this type of points? But then why can I pass them to the function?

Update using Mat

I tried to use Mat instead, which is a bit of a pain to use. I found this question explaining how to set the elements of a Mat and came up with this code:

int n = 2;
Mat mat = new Mat(new Size(1, n), Emgu.CV.CvEnum.DepthType.Cv32F, 2);
Mat matDistorted = new Mat(new Size(1, n), Emgu.CV.CvEnum.DepthType.Cv32F, 2);

Matrix<float> yetAnotherMatrixOr_YAM_forShort = new Matrix<float>(new float[,]{{0, 0}, {255, 255}});

mat.SetTo(yetAnotherMatrixOr_YAM_forShort);

CvInvoke.UndistortPoints(mat, matDistorted, intrinsic.CameraMatrix, intrinsic.DistorionCoefficients);

The exception I get now comes from a different assertion (hurray?):

OpenCV: checkScalar(value, type(), _value.kind(), _InputArray::MAT )

It looks like this happens when calling mat.SetTo(). I'm not sure why this is so complicated.

Community
  • 1
  • 1
null
  • 5,207
  • 1
  • 19
  • 35
  • can you try `Point2f` instead of `Point`? – Micka Jan 06 '16 at 14:10
  • @Micka how would I do that? EmguCV has `MCvPoint2D64f`, which I can create an array of: `MCvPoint2D64f[]`, but I can neither wrap that into a `VectorOfPoints` nor can I pass it to `CvInvoke.UndistortPoints()`. There's no `VectorOfPoints2f` either. How would I pass many `Point2f ` objects to `CvInvoke.UndistortPoints()`? Whatever it is, I think it has to implement `InputArray`, but am not sure. The type system of this library still confuses me. – null Jan 06 '16 at 14:21
  • sorry, don't know enough about emguCV... is it possible to create Mat objects with CV_32FC2 equivalent? Like new Mat(size, Cv32F, 2)? Feed your point positions (n points) to it and choose size to be 1 column and n rows. – Micka Jan 06 '16 at 14:26
  • @Micka I think I tried something like that, please take a look at my edit. Did I mess up the `Mat`? – null Jan 06 '16 at 14:57
  • no idea, sorry... .setTo typically means to set each pixel (or matrix element) to a fixed value. Can you try to modify the data of `mat` directly (I don't know how to access matrix elements in emguCV, sorry)? – Micka Jan 06 '16 at 15:03
  • 1
    @Micka you got me on the right track, while there's no `Point2f` in EmguCV, I managed to solve the problem by using `PointF` instead. Thanks! – null Jan 06 '16 at 16:02

1 Answers1

1

It looks like the problem was indeed the Point class.

Changing the code to use PointF and VectorOfPointF instead respectively solved the problem:

VectorOfPointF points = new VectorOfPointF(new PointF[] { new PointF(0, 0), new PointF(255, 255) });

VectorOfPointF pointsUndistorted = new VectorOfPointF(points.Size);
null
  • 5,207
  • 1
  • 19
  • 35