Skip to content

Commit

Permalink
Merge pull request #393 from shimat/fix_issues
Browse files Browse the repository at this point in the history
Fix #335, #387
  • Loading branch information
shimat authored Nov 10, 2017
2 parents b82fbd9 + 659a06c commit d273b1c
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 38 deletions.
2 changes: 2 additions & 0 deletions OpenCvSharp.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Local_0020variables/@EntryIndexedValue">&lt;NamingElement Priority="6"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="local variable" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Parameters/@EntryIndexedValue">&lt;NamingElement Priority="5"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="parameter" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SURF/@EntryIndexedValue">SURF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String></wpf:ResourceDictionary>
36 changes: 5 additions & 31 deletions src/OpenCvSharp/Cv2/Cv2_calib3d.cs
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,6 @@ public static void MatMulDeriv(InputArray a, InputArray b,
NativeMethods.calib3d_matMulDeriv(a.CvPtr, b.CvPtr, dABdA.CvPtr, dABdB.CvPtr);
GC.KeepAlive(a);
GC.KeepAlive(b);
GC.KeepAlive(dABdA);
GC.KeepAlive(dABdB);
dABdA.Fix();
dABdB.Fix();
}
Expand Down Expand Up @@ -615,6 +613,7 @@ public static void ProjectPoints(InputArray objectPoints,
NativeMethods.calib3d_projectPoints_InputArray(objectPoints.CvPtr,
rvec.CvPtr, tvec.CvPtr, cameraMatrix.CvPtr, ToPtr(distCoeffs),
imagePoints.CvPtr, ToPtr(jacobian), aspectRatio);

GC.KeepAlive(objectPoints);
GC.KeepAlive(rvec);
GC.KeepAlive(tvec);
Expand Down Expand Up @@ -673,17 +672,13 @@ public static void ProjectPoints(IEnumerable<Point3f> objectPoints,
using (var rvecM = new Mat(3, 1, MatType.CV_64FC1, rvec))
using (var tvecM = new Mat(3, 1, MatType.CV_64FC1, tvec))
using (var cameraMatrixM = new Mat(3, 3, MatType.CV_64FC1, cameraMatrix))
using (var distCoeffsM = (distCoeffs == null) ? new Mat() : new Mat(distCoeffs.Length, 1, MatType.CV_64FC1, distCoeffs))
using (var imagePointsM = new MatOfPoint2f())
using (var jacobianM = new MatOfDouble())
{
var distCoeffsM = new Mat();
if (distCoeffs != null)
distCoeffsM = new Mat(distCoeffs.Length, 1, MatType.CV_64FC1, distCoeffs);
var jacobianM = new MatOfDouble();

NativeMethods.calib3d_projectPoints_Mat(objectPointsM.CvPtr,
rvecM.CvPtr, tvecM.CvPtr, cameraMatrixM.CvPtr, distCoeffsM.CvPtr,
imagePointsM.CvPtr, jacobianM.CvPtr, aspectRatio);
GC.KeepAlive(distCoeffsM);

imagePoints = imagePointsM.ToArray();
jacobian = jacobianM.ToRectangularArray();
Expand Down Expand Up @@ -737,14 +732,12 @@ public static void SolvePnP(
NativeMethods.calib3d_solvePnP_InputArray(
objectPoints.CvPtr, imagePoints.CvPtr, cameraMatrix.CvPtr, distCoeffsPtr,
rvec.CvPtr, tvec.CvPtr, useExtrinsicGuess ? 1 : 0, (int)flags);
rvec.Fix();
tvec.Fix();
GC.KeepAlive(objectPoints);
GC.KeepAlive(imagePoints);
GC.KeepAlive(cameraMatrix);
GC.KeepAlive(distCoeffs);
GC.KeepAlive(rvec);
GC.KeepAlive(tvec);
rvec.Fix();
tvec.Fix();
}

/// <summary>
Expand Down Expand Up @@ -858,9 +851,6 @@ public static void SolvePnPRansac(
GC.KeepAlive(imagePoints);
GC.KeepAlive(cameraMatrix);
GC.KeepAlive(distCoeffs);
GC.KeepAlive(rvec);
GC.KeepAlive(tvec);
GC.KeepAlive(inliers);
rvec.Fix();
tvec.Fix();
inliers?.Fix();
Expand Down Expand Up @@ -978,8 +968,6 @@ public static Mat InitCameraMatrix2D(

IntPtr matPtr = NativeMethods.calib3d_initCameraMatrix2D_Mat(objectPointsPtrs, objectPointsPtrs.Length,
imagePointsPtrs, imagePointsPtrs.Length, imageSize, aspectRatio);
GC.KeepAlive(objectPoints);
GC.KeepAlive(imagePoints);
return new Mat(matPtr);
}
/// <summary>
Expand Down Expand Up @@ -1039,7 +1027,6 @@ public static bool FindChessboardCorners(
int ret = NativeMethods.calib3d_findChessboardCorners_InputArray(
image.CvPtr, patternSize, corners.CvPtr, (int)flags);
GC.KeepAlive(image);
GC.KeepAlive(corners);
corners.Fix();
return ret != 0;
}
Expand Down Expand Up @@ -1093,7 +1080,6 @@ public static bool Find4QuadCornerSubpix(InputArray img, InputOutputArray corner
int ret = NativeMethods.calib3d_find4QuadCornerSubpix_InputArray(
img.CvPtr, corners.CvPtr, regionSize);
GC.KeepAlive(img);
GC.KeepAlive(corners);
corners.Fix();
return ret != 0;
}
Expand Down Expand Up @@ -1148,7 +1134,6 @@ public static void DrawChessboardCorners(InputOutputArray image, Size patternSiz

NativeMethods.calib3d_drawChessboardCorners_InputArray(
image.CvPtr, patternSize, corners.CvPtr, patternWasFound ? 1 : 0);
GC.KeepAlive(image);
GC.KeepAlive(corners);
image.Fix();
}
Expand All @@ -1172,7 +1157,6 @@ public static void DrawChessboardCorners(InputOutputArray image, Size patternSiz
NativeMethods.calib3d_drawChessboardCorners_array(
image.CvPtr, patternSize, cornersArray, cornersArray.Length,
patternWasFound ? 1 : 0);
GC.KeepAlive(image);
image.Fix();
}
#endregion
Expand Down Expand Up @@ -2210,7 +2194,6 @@ public static void ConvertPointsFromHomogeneous(InputArray src, OutputArray dst)
dst.ThrowIfNotReady();
NativeMethods.calib3d_convertPointsFromHomogeneous_InputArray(src.CvPtr, dst.CvPtr);
GC.KeepAlive(src);
GC.KeepAlive(dst);
dst.Fix();
}
/// <summary>
Expand Down Expand Up @@ -2259,7 +2242,6 @@ public static void ConvertPointsHomogeneous(InputArray src, OutputArray dst)
dst.ThrowIfNotReady();
NativeMethods.calib3d_convertPointsHomogeneous(src.CvPtr, dst.CvPtr);
GC.KeepAlive(src);
GC.KeepAlive(dst);
dst.Fix();
}
#endregion
Expand Down Expand Up @@ -2299,7 +2281,6 @@ public static Mat FindFundamentalMat(
mask?.Fix();
GC.KeepAlive(points1);
GC.KeepAlive(points2);
GC.KeepAlive(mask);
return new Mat(mat);
}

Expand Down Expand Up @@ -2338,7 +2319,6 @@ public static Mat FindFundamentalMat(
points2Array, points2Array.Length, (int)method,
param1, param2, ToPtr(mask));
mask?.Fix();
GC.KeepAlive(mask);
return new Mat(mat);
}
#endregion
Expand Down Expand Up @@ -2371,7 +2351,6 @@ public static void ComputeCorrespondEpilines(InputArray points,

GC.KeepAlive(F);
GC.KeepAlive(points);
GC.KeepAlive(lines);
lines.Fix();
}

Expand Down Expand Up @@ -2470,7 +2449,6 @@ public static void TriangulatePoints(
GC.KeepAlive(projMatr2);
GC.KeepAlive(projPoints1);
GC.KeepAlive(projPoints2);
GC.KeepAlive(points4D);
points4D.Fix();
}
/// <summary>
Expand Down Expand Up @@ -2549,8 +2527,6 @@ public static void CorrectMatches(
GC.KeepAlive(F);
GC.KeepAlive(points1);
GC.KeepAlive(points2);
GC.KeepAlive(newPoints1);
GC.KeepAlive(newPoints2);
newPoints1.Fix();
newPoints2.Fix();
}
Expand Down Expand Up @@ -2721,8 +2697,6 @@ public static int EstimateAffine3D(InputArray src, InputArray dst,
inliers.Fix();
GC.KeepAlive(src);
GC.KeepAlive(dst);
GC.KeepAlive(outVal);
GC.KeepAlive(inliers);
return ret;
}
}
Expand Down
15 changes: 8 additions & 7 deletions src/OpenCvSharpExtern/calib3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ CVAPI(void) calib3d_projectPoints_InputArray(cv::_InputArray *objectPoints,
double aspectRatio)
{
cv::projectPoints(*objectPoints, *rvec, *tvec, *cameraMatrix, *distCoeffs,
*imagePoints, *jacobian, aspectRatio);
*imagePoints, entity(jacobian), aspectRatio);
}
CVAPI(void) calib3d_projectPoints_Mat(cv::Mat *objectPoints,
cv::Mat *rvec, cv::Mat *tvec,
Expand All @@ -130,16 +130,17 @@ CVAPI(void) calib3d_solvePnP_vector(cv::Point3f *objectPoints, int objectPointsL
double *rvec, double *tvec, int useExtrinsicGuess,
int flags)
{
cv::Mat objectPointsMat(objectPointsLength, 1, CV_64FC3, objectPoints);
cv::Mat imagePointsMat(imagePointsLength, 1, CV_64FC2, imagePoints);
const cv::Mat objectPointsMat(objectPointsLength, 1, CV_32FC3, objectPoints);
const cv::Mat imagePointsMat(imagePointsLength, 1, CV_32FC2, imagePoints);
cv::Mat distCoeffsMat;
if (distCoeffs != NULL)
distCoeffsMat = cv::Mat(distCoeffsLength, 1, CV_64FC1, distCoeffs);

cv::Matx<double, 3, 1> rvecM, tvecM;
cv::solvePnP(objectPointsMat, imagePointsMat, *cameraMatrix, distCoeffsMat, rvecM, tvecM, useExtrinsicGuess != 0, flags);
memcpy(rvec, rvecM.val, sizeof(double) * 3);
memcpy(tvec, tvecM.val, sizeof(double) * 3);
const cv::Matx<double, 3, 3> cameraMatrixMat(cameraMatrix);
cv::Matx<double, 3, 1> rvecMat, tvecMat;
cv::solvePnP(objectPointsMat, imagePointsMat, cameraMatrixMat, distCoeffsMat, rvecMat, tvecMat, useExtrinsicGuess != 0, flags);
memcpy(rvec, rvecMat.val, sizeof(double) * 3);
memcpy(tvec, tvecMat.val, sizeof(double) * 3);
}

CVAPI(void) calib3d_solvePnPRansac_InputArray(cv::_InputArray *objectPoints, cv::_InputArray *imagePoints,
Expand Down
160 changes: 160 additions & 0 deletions test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Xunit;

namespace OpenCvSharp.Tests.Calib3D
{
public class Calib3DTest : TestBase
{
/// <summary>
/// https://stackoverflow.com/questions/25244603/opencvs-projectpoints-function
/// </summary>
[Fact]
public void ProjectPointsTest()
{
var objectPointsArray = Generate3DPoints().ToArray();
var objectPoints = new Mat(objectPointsArray.Length, 1, MatType.CV_64FC3, objectPointsArray);

Mat intrisicMat = new Mat(3, 3, MatType.CV_64FC1);
intrisicMat.Set<double>(0, 0, 1.6415318549788924e+003);
intrisicMat.Set<double>(1, 0,0);
intrisicMat.Set<double>(2, 0,0);
intrisicMat.Set<double>(0, 1,0);
intrisicMat.Set<double>(1, 1,1.7067753507885654e+003);
intrisicMat.Set<double>(2, 1,0);
intrisicMat.Set<double>(0, 2,5.3262822453148601e+002);
intrisicMat.Set<double>(1, 2,3.8095355839052968e+002);
intrisicMat.Set<double>(2, 2,1);

Mat rVec = new Mat(3, 1, MatType.CV_64FC1);
rVec.Set<double>(0, -3.9277902400761393e-002);
rVec.Set<double>(1, 3.7803824407602084e-002);
rVec.Set<double>(2, 2.6445674487856268e-002);

Mat tVec = new Mat(3, 1, MatType.CV_64FC1);
tVec.Set<double>(0, 2.1158489381208221e+000);
tVec.Set<double>(1, -7.6847683212704716e+000);
tVec.Set<double>(2, 2.6169795190294256e+001);

Mat distCoeffs = new Mat(4, 1, MatType.CV_64FC1);
distCoeffs.Set<double>(0, 0);
distCoeffs.Set<double>(1, 0);
distCoeffs.Set<double>(2, 0);
distCoeffs.Set<double>(3, 0);

// without jacobian
Mat projectedPoints = new Mat();
Cv2.ProjectPoints(objectPoints, rVec, tVec, intrisicMat, distCoeffs, projectedPoints);

// with jacobian
Mat jacobian = new Mat();
Cv2.ProjectPoints(objectPoints, rVec, tVec, intrisicMat, distCoeffs, projectedPoints, jacobian);

objectPoints.Dispose();
intrisicMat.Dispose();
rVec.Dispose();
tVec.Dispose();
distCoeffs.Dispose();
projectedPoints.Dispose();
jacobian.Dispose();

IEnumerable<Point3d> Generate3DPoints()
{
double x, y, z;

x = .5; y = .5; z = -.5;
yield return new Point3d(x, y, z);

x = .5; y = .5; z = .5;
yield return new Point3d(x, y, z);

x = -.5; y = .5; z = .5;
yield return new Point3d(x, y, z);

x = -.5; y = .5; z = -.5;
yield return new Point3d(x, y, z);

x = .5; y = -.5; z = -.5;
yield return new Point3d(x, y, z);

x = -.5; y = -.5; z = -.5;
yield return new Point3d(x, y, z);

x = -.5; y = -.5; z = .5;
yield return new Point3d(x, y, z);
}
}

[Fact]
public void SolvePnPTestByArray()
{
var rvec = new double[] { 0, 0, 0 };
var tvec = new double[] { 0, 0, 0 };
var cameraMatrix = new double[3, 3]
{
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 }
};
var dist = new double[] { 0, 0, 0, 0, 0 };

var objPts = new Point3f[]
{
new Point3f(0,0,1),
new Point3f(1,0,1),
new Point3f(0,1,1),
new Point3f(1,1,1),
new Point3f(1,0,2),
new Point3f(0,1,2)
};

double[,] jacobian;
Point2f[] imgPts;
Cv2.ProjectPoints(objPts, rvec, tvec, cameraMatrix, dist, out imgPts, out jacobian);

Cv2.SolvePnP(objPts, imgPts, cameraMatrix, dist, out rvec, out tvec);
}

[Fact]
public void SolvePnPTestByMat()
{
var rvec = new double[] { 0, 0, 0 };
var tvec = new double[] { 0, 0, 0 };
var cameraMatrix = new double[3, 3]
{
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 }
};
var dist = new double[] { 0, 0, 0, 0, 0 };

var objPts = new Point3f[]
{
new Point3f(0,0,1),
new Point3f(1,0,1),
new Point3f(0,1,1),
new Point3f(1,1,1),
new Point3f(1,0,2),
new Point3f(0,1,2)
};

double[,] jacobian;
Point2f[] imgPts;
Cv2.ProjectPoints(objPts, rvec, tvec, cameraMatrix, dist, out imgPts, out jacobian);

using (var objPtsMat = new Mat(objPts.Length, 1, MatType.CV_32FC3))
using (var imgPtsMat = new Mat(imgPts.Length, 1, MatType.CV_32FC2))
using (var cameraMatrixMat = Mat.Eye(3, 3, MatType.CV_64FC1))
using (var distMat = Mat.Zeros(5, 0, MatType.CV_64FC1))
using (var rvecMat = new Mat())
using (var tvecMat = new Mat())
{
Cv2.SolvePnP(objPtsMat, imgPtsMat, cameraMatrixMat, distMat, rvecMat, tvecMat);
}
}
}
}

0 comments on commit d273b1c

Please sign in to comment.