What is the difference between Matlab's and OpenCV's undistortPoints?

8 views (last 30 days)
I've been trying to solve this for the past few days now. I basically have calibration data for a couple of cameras done in MATLAB, and would now like to use the same undistortPoints functionality in OpenCV, using the same distortion coefficients and camera matrices.
In MATLAB, I have a cameraParameters object which I pass to undistortPoints, along with a point, and get the undistorted point back. This works as intended.
% Default distortion coefficients
>> undistortPoints([485, 502], cameraParameters)
ans =
485 502
% Updated distortion coefficient k1
>> changedDist = cameraParameters('RadialDistortion', [-2 0 0])
>> undistortPoints([485, 502], changedDist)
ans =
-4.9085 -5.0805
Now I try and use the same function (and camera parameters) in OpenCV (with Java bindings) and it displays completely different results. Does anyone know specifically the differences between OpenCV's and MATLAB's undistortPoints implementations? Am I supposed to use something else?
public void testUnDistortPointsChangedDistortion() {
Mat srcMat = new Mat(2, 1, CvType.CV_32FC2);
Mat dstMat = new Mat(2, 1, CvType.CV_32FC2);
srcMat.put(0, 0, new float[] { 485, 502 });
MatOfPoint2f src = new MatOfPoint2f(srcMat);
MatOfPoint2f dst = new MatOfPoint2f(dstMat);
Mat defaultCameraMatrix = Mat.eye(3, 3, CvType.CV_32F);
Mat distCoefficientMatrix = new Mat(1, 5, CvType.CV_32F);
distCoefficientMatrix.put(0, 0, -2f); // updated
Imgproc.undistortPoints(
src,
dst,
defaultCameraMatrix,
distCoefficientMatrix
);
System.out.println(dst.dump());
assertEquals(-4.9085f, dst.get(0, 0)[0]);
assertEquals(-5.0805f, dst.get(0, 0)[1]);
}
Output:
[-0.00049771206, -0.00051515765;
-2.7577372e-023, -7.3429287e-024]
junit.framework.AssertionFailedError:
Expected :-4.9085
Actual :-4.977120552212E-4
<Click to see difference>
at cs407.project.calibration.SystemTrackerTest.testUnDistortPointsChangedDistortion(SystemTrackerTest.java:99)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Note that using the unaltered distortion coefficient matrix (all 0s), the test passes and dst contains exactly the src elements.

Answers (1)

Dima Lisin
Dima Lisin on 20 Apr 2015
I would check what srcMat looks like after the call to put(). You have created srcMat to be a 2x1 column vector, yet the output, dstMat, ends up being a 2x2 matrix. This looks more like a programming error.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!