Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
499 changes: 499 additions & 0 deletions src/OpenCvSharp/Cv2/Cv2_calib3d.FishEye.cs

Large diffs are not rendered by default.

576 changes: 84 additions & 492 deletions src/OpenCvSharp/Cv2/Cv2_calib3d.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,21 @@ public static extern ExceptionStatus calib3d_stereoCalibrate_InputArray(
int flags, TermCriteria criteria,
out double returnValue);

[DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus calib3d_stereoCalibrate_Mat(
IntPtr[] objectPoints, int opSize,
IntPtr[] imagePoints1, int ip1Size,
IntPtr[] imagePoints2, int ip2Size,
IntPtr cameraMatrix1,
IntPtr distCoeffs1,
IntPtr cameraMatrix2,
IntPtr distCoeffs2,
Size imageSize,
IntPtr R, IntPtr T,
IntPtr E, IntPtr F,
int flags, TermCriteria criteria,
out double returnValue);

[DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe ExceptionStatus calib3d_stereoCalibrate_array(
IntPtr[] objectPoints, int opSize1, int[] opSizes2,
Expand Down
78 changes: 78 additions & 0 deletions src/OpenCvSharp/Modules/core/Mat/Mat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,84 @@ public static MatExpr Eye(int rows, int cols, MatType type)
return retVal;
}

/// <summary>
/// Returns a zero array of the specified size and type as <see cref="Mat"/>.
/// Unlike <see cref="Zeros(int,int,MatType)"/>, this method returns a <see cref="Mat"/> directly,
/// so a single <c>using</c> statement is sufficient to manage its lifetime.
/// </summary>
/// <param name="rows">Number of rows.</param>
/// <param name="cols">Number of columns.</param>
/// <param name="type">Created matrix type.</param>
/// <returns></returns>
public static Mat ZerosMat(int rows, int cols, MatType type)
{
using var expr = Zeros(rows, cols, type);
return (Mat)expr;
}

/// <summary>
/// Returns a zero array of the specified size and type as <see cref="Mat"/>.
/// Unlike <see cref="Zeros(Size,MatType)"/>, this method returns a <see cref="Mat"/> directly,
/// so a single <c>using</c> statement is sufficient to manage its lifetime.
/// </summary>
/// <param name="size">Alternative to the matrix size specification Size(cols, rows).</param>
/// <param name="type">Created matrix type.</param>
/// <returns></returns>
public static Mat ZerosMat(Size size, MatType type)
=> ZerosMat(size.Height, size.Width, type);

/// <summary>
/// Returns an array of all 1's of the specified size and type as <see cref="Mat"/>.
/// Unlike <see cref="Ones(int,int,MatType)"/>, this method returns a <see cref="Mat"/> directly,
/// so a single <c>using</c> statement is sufficient to manage its lifetime.
/// </summary>
/// <param name="rows">Number of rows.</param>
/// <param name="cols">Number of columns.</param>
/// <param name="type">Created matrix type.</param>
/// <returns></returns>
public static Mat OnesMat(int rows, int cols, MatType type)
{
using var expr = Ones(rows, cols, type);
return (Mat)expr;
}

/// <summary>
/// Returns an array of all 1's of the specified size and type as <see cref="Mat"/>.
/// Unlike <see cref="Ones(Size,MatType)"/>, this method returns a <see cref="Mat"/> directly,
/// so a single <c>using</c> statement is sufficient to manage its lifetime.
/// </summary>
/// <param name="size">Alternative to the matrix size specification Size(cols, rows).</param>
/// <param name="type">Created matrix type.</param>
/// <returns></returns>
public static Mat OnesMat(Size size, MatType type)
=> OnesMat(size.Height, size.Width, type);

/// <summary>
/// Returns an identity matrix of the specified size and type as <see cref="Mat"/>.
/// Unlike <see cref="Eye(int,int,MatType)"/>, this method returns a <see cref="Mat"/> directly,
/// so a single <c>using</c> statement is sufficient to manage its lifetime.
/// </summary>
/// <param name="rows">Number of rows.</param>
/// <param name="cols">Number of columns.</param>
/// <param name="type">Created matrix type.</param>
/// <returns></returns>
public static Mat EyeMat(int rows, int cols, MatType type)
{
using var expr = Eye(rows, cols, type);
return (Mat)expr;
}

/// <summary>
/// Returns an identity matrix of the specified size and type as <see cref="Mat"/>.
/// Unlike <see cref="Eye(Size,MatType)"/>, this method returns a <see cref="Mat"/> directly,
/// so a single <c>using</c> statement is sufficient to manage its lifetime.
/// </summary>
/// <param name="size">Alternative to the matrix size specification Size(cols, rows).</param>
/// <param name="type">Created matrix type.</param>
/// <returns></returns>
public static Mat EyeMat(Size size, MatType type)
=> EyeMat(size.Height, size.Width, type);

#region FromArray

/// <summary>
Expand Down
54 changes: 43 additions & 11 deletions src/OpenCvSharpExtern/calib3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,9 @@ CVAPI(ExceptionStatus) calib3d_initCameraMatrix2D_array(
std::vector<std::vector<cv::Point3f> > objectPointsVec(opSize1);
for (auto i = 0; i < opSize1; i++)
objectPointsVec[i] = std::vector<cv::Point3f>(objectPoints[i], objectPoints[i] + opSize2[i]);
std::vector<std::vector<cv::Point3f> > imagePointsVec(ipSize1);
std::vector<std::vector<cv::Point2f> > imagePointsVec(ipSize1);
for (auto i = 0; i < ipSize1; i++)
imagePointsVec[i] = std::vector<cv::Point3f>(imagePoints[i], imagePoints[i] + ipSize2[i]);
imagePointsVec[i] = std::vector<cv::Point2f>(imagePoints[i], imagePoints[i] + ipSize2[i]);

const auto ret = cv::initCameraMatrix2D(objectPointsVec, imagePointsVec, cpp(imageSize), aspectRatio);
*returnValue = new cv::Mat(ret);
Expand Down Expand Up @@ -509,9 +509,41 @@ CVAPI(ExceptionStatus) calib3d_stereoCalibrate_InputArray(
double *returnValue)
{
BEGIN_WRAP
std::vector<cv::_InputArray> objectPointsVec(opSize);
std::vector<cv::_InputArray> imagePoints1Vec(ip1Size);
std::vector<cv::_InputArray> imagePoints2Vec(ip2Size);
std::vector<cv::Mat> objectPointsVec(opSize);
std::vector<cv::Mat> imagePoints1Vec(ip1Size);
std::vector<cv::Mat> imagePoints2Vec(ip2Size);
for (auto i = 0; i < opSize; i++)
objectPointsVec[i] = objectPoints[i]->getMat();
for (auto i = 0; i < ip1Size; i++)
imagePoints1Vec[i] = imagePoints1[i]->getMat();
for (auto i = 0; i < ip2Size; i++)
imagePoints2Vec[i] = imagePoints2[i]->getMat();

*returnValue = cv::stereoCalibrate(objectPointsVec, imagePoints1Vec, imagePoints2Vec,
*cameraMatrix1, *distCoeffs1,
*cameraMatrix2, *distCoeffs2,
cpp(imageSize), entity(R), entity(T), entity(E), entity(F), flags, cpp(criteria));
END_WRAP
}
CVAPI(ExceptionStatus) calib3d_stereoCalibrate_Mat(
cv::Mat **objectPoints, int opSize,
cv::Mat **imagePoints1, int ip1Size,
cv::Mat **imagePoints2, int ip2Size,
cv::Mat *cameraMatrix1,
cv::Mat *distCoeffs1,
cv::Mat *cameraMatrix2,
cv::Mat *distCoeffs2,
MyCvSize imageSize,
cv::Mat *R, cv::Mat *T,
cv::Mat *E, cv::Mat *F,
int flags,
MyCvTermCriteria criteria,
double *returnValue)
{
BEGIN_WRAP
std::vector<cv::Mat> objectPointsVec(opSize);
std::vector<cv::Mat> imagePoints1Vec(ip1Size);
std::vector<cv::Mat> imagePoints2Vec(ip2Size);
for (auto i = 0; i < opSize; i++)
objectPointsVec[i] = *objectPoints[i];
for (auto i = 0; i < ip1Size; i++)
Expand All @@ -522,7 +554,7 @@ CVAPI(ExceptionStatus) calib3d_stereoCalibrate_InputArray(
*returnValue = cv::stereoCalibrate(objectPointsVec, imagePoints1Vec, imagePoints2Vec,
*cameraMatrix1, *distCoeffs1,
*cameraMatrix2, *distCoeffs2,
cpp(imageSize), entity(R), entity(T), entity(E), entity(F), flags, cpp(criteria));
cpp(imageSize), *R, *T, *E, *F, flags, cpp(criteria));
END_WRAP
}
CVAPI(ExceptionStatus) calib3d_stereoCalibrate_array(
Expand Down Expand Up @@ -659,12 +691,12 @@ CVAPI(ExceptionStatus) calib3d_rectify3Collinear_InputArray(
float *returnValue)
{
BEGIN_WRAP
std::vector<cv::_InputArray> imgpt1Vec(imgpt1Size);
std::vector<cv::_InputArray> imgpt3Vec(imgpt3Size);
for (auto i = 0; i < imgpt1Size; i++)
imgpt1Vec[i] = *(imgpt1[i]);
std::vector<cv::Mat> imgpt1Vec(imgpt1Size);
std::vector<cv::Mat> imgpt3Vec(imgpt3Size);
for (auto i = 0; i < imgpt1Size; i++)
imgpt3Vec[i] = *(imgpt3[i]);
imgpt1Vec[i] = imgpt1[i]->getMat();
for (auto i = 0; i < imgpt3Size; i++)
imgpt3Vec[i] = imgpt3[i]->getMat();
cv::Rect _roi1, _roi2;

const auto ret = cv::rectify3Collinear(*cameraMatrix1, *distCoeffs1,
Expand Down
76 changes: 71 additions & 5 deletions test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public void CalibrateCameraByMat()

using var objectPoints = Mat<Point3f>.FromArray(objectPointsArray);
using var imagePoints = Mat<Point2f>.FromArray(imagePointsArray);
using var cameraMatrix = new Mat<double>(Mat.Eye(3, 3, MatType.CV_64FC1));
using var cameraMatrix = Mat.EyeMat(3, 3, MatType.CV_64FC1);
using var distCoeffs = new Mat<double>();
var rms = Cv2.CalibrateCamera([objectPoints], [imagePoints], image.Size(), cameraMatrix,
distCoeffs, out var rotationVectors, out var translationVectors,
Expand All @@ -165,7 +165,7 @@ public void FishEyeCalibrate()

using var objectPoints = Mat<Point3f>.FromArray(objectPointsArray);
using var imagePoints = Mat<Point2f>.FromArray(imagePointsArray);
using var cameraMatrix = new Mat<double>(Mat.Eye(3, 3, MatType.CV_64FC1));
using var cameraMatrix = Mat.EyeMat(3, 3, MatType.CV_64FC1);
using var distCoeffs = new Mat<double>();
var rms = Cv2.FishEye.Calibrate([objectPoints], [imagePoints], image.Size(), cameraMatrix,
distCoeffs, out var rotationVectors, out var translationVectors);
Expand Down Expand Up @@ -327,8 +327,8 @@ public void SolvePnPTestByMat()

using var objPtsMat = Mat.FromPixelData(objPts.Length, 1, MatType.CV_32FC3, objPts);
using var imgPtsMat = Mat.FromPixelData(imgPts.Length, 1, MatType.CV_32FC2, imgPts);
using var cameraMatrixMat = Mat.Eye(3, 3, MatType.CV_64FC1);
using var distMat = Mat.Zeros(5, 0, MatType.CV_64FC1);
using var cameraMatrixMat = Mat.EyeMat(3, 3, MatType.CV_64FC1);
using var distMat = Mat.ZerosMat(5, 0, MatType.CV_64FC1);
using var rvecMat = new Mat();
using var tvecMat = new Mat();
Cv2.SolvePnP(objPtsMat, imgPtsMat, cameraMatrixMat, distMat, rvecMat, tvecMat);
Expand Down Expand Up @@ -496,7 +496,7 @@ public void RecoverPoseWithTriangulatedPoints()

using var points1m = Mat<double>.FromArray(points1);
using var points2m = Mat<double>.FromArray(points2);
using var K = Mat.Eye(3, 3, MatType.CV_64F);
using var K = Mat.EyeMat(3, 3, MatType.CV_64F);
using var inliers = new Mat();
using var E = Cv2.FindEssentialMat(points1m, points2m, K, EssentialMatMethod.LMedS, 0.99, 1.0, inliers);

Expand Down Expand Up @@ -575,6 +575,72 @@ public void FindHomographyUsac()
});*/
}

[Fact]
public void StereoCalibrateByInputArray()
{
var patternSize = new Size(10, 7);

using var image = LoadImage("calibration/00.jpg");
Cv2.FindChessboardCorners(image, patternSize, out var cornerPoints);

var objectPointsArray = Create3DChessboardCorners(patternSize, 1.0f).ToArray();

using var opIA = InputArray.Create(objectPointsArray);
using var ip1IA = InputArray.Create(cornerPoints);
using var ip2IA = InputArray.Create(cornerPoints);

using var cameraMatrix1 = Mat.EyeMat(3, 3, MatType.CV_64FC1);
using var distCoeffs1 = new Mat<double>();
using var cameraMatrix2 = Mat.EyeMat(3, 3, MatType.CV_64FC1);
using var distCoeffs2 = new Mat<double>();
using var R = new Mat();
using var T = new Mat();
using var E = new Mat();
using var F = new Mat();

var rms = Cv2.StereoCalibrate(
new[] { opIA }, new[] { ip1IA }, new[] { ip2IA },
cameraMatrix1, distCoeffs1,
cameraMatrix2, distCoeffs2,
image.Size(), R, T, E, F,
CalibrationFlags.UseIntrinsicGuess);

Assert.False(double.IsNaN(rms));
Assert.False(double.IsInfinity(rms));
}

[Fact]
public void StereoCalibrateByMat()
{
var patternSize = new Size(10, 7);

using var image = LoadImage("calibration/00.jpg");
Cv2.FindChessboardCorners(image, patternSize, out var cornerPoints);

var objectPointsArray = Create3DChessboardCorners(patternSize, 1.0f).ToArray();

using var objectPoints = Mat<Point3f>.FromArray(objectPointsArray);
using var imagePoints = Mat<Point2f>.FromArray(cornerPoints);
using var cameraMatrix1 = Mat.EyeMat(3, 3, MatType.CV_64FC1);
using var distCoeffs1 = new Mat();
using var cameraMatrix2 = Mat.EyeMat(3, 3, MatType.CV_64FC1);
using var distCoeffs2 = new Mat();
using var R = new Mat();
using var T = new Mat();
using var E = new Mat();
using var F = new Mat();

var rms = Cv2.StereoCalibrate(
new[] { objectPoints }, new[] { imagePoints }, new[] { imagePoints },
cameraMatrix1, distCoeffs1,
cameraMatrix2, distCoeffs2,
image.Size(), R, T, E, F,
CalibrationFlags.UseIntrinsicGuess);

Assert.False(double.IsNaN(rms));
Assert.False(double.IsInfinity(rms));
}

private static IEnumerable<Point3f> Create3DChessboardCorners(Size boardSize, float squareSize)
{
for (var y = 0; y < boardSize.Height; y++)
Expand Down
6 changes: 3 additions & 3 deletions test/OpenCvSharp.Tests/shape/HistogramCostExtractorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ public void Norm_DefaultCostRoundTrip()
public void Norm_BuildCostMatrix()
{
using var ext = NormHistogramCostExtractor.Create();
using var hist1 = Mat.FromArray(new float[] { 0.5f, 0.3f, 0.2f });
using var hist2 = Mat.FromArray(new float[] { 0.4f, 0.4f, 0.2f });
using var hist1 = Mat.FromArray([0.5f, 0.3f, 0.2f]);
using var hist2 = Mat.FromArray([0.4f, 0.4f, 0.2f]);
using var costMat = new Mat();

ext.BuildCostMatrix(hist1, hist2, costMat);
Expand Down Expand Up @@ -237,4 +237,4 @@ public void SCDE_SetTransformAlgorithm_Affine()

extractor.SetTransformAlgorithm(affine);
}
}
}
Loading