Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more functions used for stereo image processing. #1113

Merged
merged 4 commits into from
Oct 17, 2023
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
4 changes: 2 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ Your pull requests will be greatly appreciated!
- [ ] [checkChessboard](https://docs.opencv.org/master/d9/d0c/group__calib3d.html)
- [ ] [composeRT](https://docs.opencv.org/master/d9/d0c/group__calib3d.html)
- [ ] [computeCorrespondEpilines](https://docs.opencv.org/master/d9/d0c/group__calib3d.html)
- [ ] [convertPointsFromHomogeneous](https://docs.opencv.org/master/d9/d0c/group__calib3d.html)
- [X] [convertPointsFromHomogeneous](https://docs.opencv.org/master/d9/d0c/group__calib3d.html)
- [ ] [convertPointsHomogeneous](https://docs.opencv.org/master/d9/d0c/group__calib3d.html)
- [ ] [convertPointsToHomogeneous](https://docs.opencv.org/master/d9/d0c/group__calib3d.html)
- [ ] [correctMatches](https://docs.opencv.org/master/d9/d0c/group__calib3d.html)
Expand Down Expand Up @@ -175,7 +175,7 @@ Your pull requests will be greatly appreciated!
- [ ] [stereoCalibrate](https://docs.opencv.org/master/d9/d0c/group__calib3d.html)
- [ ] [stereoRectify](https://docs.opencv.org/master/d9/d0c/group__calib3d.html)
- [ ] [stereoRectifyUncalibrated](https://docs.opencv.org/master/d9/d0c/group__calib3d.html)
- [ ] [triangulatePoints](https://docs.opencv.org/master/d9/d0c/group__calib3d.html)
- [X] [triangulatePoints](https://docs.opencv.org/master/d9/d0c/group__calib3d.html)
- [ ] [validateDisparity](https://docs.opencv.org/master/d9/d0c/group__calib3d.html)

- [ ] **Fisheye - WORK STARTED** The following functions still need implementation:
Expand Down
8 changes: 8 additions & 0 deletions calib3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,11 @@ Mat EstimateAffine2D(Point2fVector from, Point2fVector to) {
Mat EstimateAffine2DWithParams(Point2fVector from, Point2fVector to, Mat inliers, int method, double ransacReprojThreshold, size_t maxIters, double confidence, size_t refineIters) {
return new cv::Mat(cv::estimateAffine2D(*from, *to, *inliers, method, ransacReprojThreshold, maxIters, confidence, refineIters));
}

void TriangulatePoints(Mat projMatr1, Mat projMatr2, Point2fVector projPoints1, Point2fVector projPoints2, Mat points4D) {
return cv::triangulatePoints(*projMatr1, *projMatr2, *projPoints1, *projPoints2, *points4D);
}

void ConvertPointsFromHomogeneous(Mat src, Mat dst) {
return cv::convertPointsFromHomogeneous(*src, *dst);
}
17 changes: 17 additions & 0 deletions calib3d.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,20 @@ func EstimateAffine2D(from, to Point2fVector) Mat {
func EstimateAffine2DWithParams(from Point2fVector, to Point2fVector, inliers Mat, method int, ransacReprojThreshold float64, maxIters uint, confidence float64, refineIters uint) Mat {
return newMat(C.EstimateAffine2DWithParams(from.p, to.p, inliers.p, C.int(method), C.double(ransacReprojThreshold), C.size_t(maxIters), C.double(confidence), C.size_t(refineIters)))
}

// TriangulatePoints reconstructs 3-dimensional points (in homogeneous coordinates)
// by using their observations with a stereo camera.
//
// For further details, please see:
// https://docs.opencv.org/4.x/d9/d0c/group__calib3d.html#gad3fc9a0c82b08df034234979960b778c
func TriangulatePoints(projMatr1, projMatr2 Mat, projPoints1, projPoints2 Point2fVector, points4D *Mat) {
C.TriangulatePoints(projMatr1.Ptr(), projMatr2.Ptr(), projPoints1.p, projPoints2.p, points4D.Ptr())
}

// ConvertPointsFromHomogeneous converts points from homogeneous to Euclidean space.
//
// For further details, please see:
// https://docs.opencv.org/4.x/d9/d0c/group__calib3d.html#gac42edda3a3a0f717979589fcd6ac0035
func ConvertPointsFromHomogeneous(src Mat, dst *Mat) {
C.ConvertPointsFromHomogeneous(src.Ptr(), dst.Ptr())
}
2 changes: 2 additions & 0 deletions calib3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ Mat EstimateAffinePartial2D(Point2fVector from, Point2fVector to);
Mat EstimateAffinePartial2DWithParams(Point2fVector from, Point2fVector to, Mat inliers, int method, double ransacReprojThreshold, size_t maxIters, double confidence, size_t refineIters);
Mat EstimateAffine2D(Point2fVector from, Point2fVector to);
Mat EstimateAffine2DWithParams(Point2fVector from, Point2fVector to, Mat inliers, int method, double ransacReprojThreshold, size_t maxIters, double confidence, size_t refineIters);
void TriangulatePoints(Mat projMatr1, Mat projMatr2, Point2fVector projPoints1, Point2fVector projPoints2, Mat points4D);
void ConvertPointsFromHomogeneous(Mat src, Mat dst);
#ifdef __cplusplus
}
#endif
Expand Down
45 changes: 45 additions & 0 deletions calib3d_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -668,3 +668,48 @@ func TestEstimateAffine2DWithParams(t *testing.T) {
t.Errorf("TestEstimateAffine2DWithParams(): unexpected rows = %v, want = %v", m.Rows(), 2)
}
}

func TestTriangulatePoints(t *testing.T) {
projMat1, projMat2 := NewMatWithSize(3, 4, MatTypeCV64F), NewMatWithSize(3, 4, MatTypeCV64F)
defer projMat1.Close()
defer projMat2.Close()
projPoints1, projPoints2 := NewPoint2fVectorFromPoints([]Point2f{{Y: 1.0, X: 2.0}}), NewPoint2fVectorFromPoints([]Point2f{{Y: 3.0, X: 4.0}})
defer projPoints1.Close()
defer projPoints2.Close()
homogeneous := NewMat()
defer homogeneous.Close()
TriangulatePoints(projMat1, projMat2, projPoints1, projPoints2, &homogeneous)
if homogeneous.Empty() {
t.Errorf("TriangulatePoints(): output homogeneous mat is empty")
}
}

func TestConvertPointsFromHomogeneous(t *testing.T) {
homogeneous := NewMatWithSize(1, 4, MatTypeCV32F)
defer homogeneous.Close()
homogeneous.SetFloatAt(0, 0, 1)
homogeneous.SetFloatAt(0, 1, 2)
homogeneous.SetFloatAt(0, 2, 4)
homogeneous.SetFloatAt(0, 3, 2)
euclidean := NewMat()
defer euclidean.Close()
ConvertPointsFromHomogeneous(homogeneous, &euclidean)
if euclidean.Empty() {
t.Fatalf("ConvertPointsFromHomogeneous(): output euclidean mat is empty")
}
ptsVector := NewPoint3fVectorFromMat(euclidean)
defer ptsVector.Close()
pts := ptsVector.ToPoints()
if len(pts) != 1 {
t.Fatalf("ConvertPointsFromHomogeneous(): euclidean mat converted to points is empty")
}
if pts[0].X != 0.5 {
t.Errorf("ConvertPointsFromHomogeneous(): euclidean X - got %v, want %v", pts[0].X, 0.5)
}
if pts[0].Y != 1 {
t.Errorf("ConvertPointsFromHomogeneous(): euclidean Y - got %v, want %v", pts[0].Y, 1)
}
if pts[0].Z != 2 {
t.Errorf("ConvertPointsFromHomogeneous(): euclidean Z - got %v, want %v", pts[0].Z, 2)
}
}
11 changes: 11 additions & 0 deletions core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,17 @@ void Mat_MinMaxLoc(Mat m, double* minVal, double* maxVal, Point* minLoc, Point*
maxLoc->y = cMaxLoc.y;
}

void Mat_MinMaxLocWithMask(Mat m, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc, Mat mask) {
cv::Point cMinLoc;
cv::Point cMaxLoc;
cv::minMaxLoc(*m, minVal, maxVal, &cMinLoc, &cMaxLoc, *mask);

minLoc->x = cMinLoc.x;
minLoc->y = cMinLoc.y;
maxLoc->x = cMaxLoc.x;
maxLoc->y = cMaxLoc.y;
}

void Mat_MixChannels(struct Mats src, struct Mats dst, struct IntVector fromTo) {
std::vector<cv::Mat> srcMats;

Expand Down
18 changes: 18 additions & 0 deletions core.go
Original file line number Diff line number Diff line change
Expand Up @@ -1534,6 +1534,24 @@ func MinMaxLoc(input Mat) (minVal, maxVal float32, minLoc, maxLoc image.Point) {
return float32(cMinVal), float32(cMaxVal), minLoc, maxLoc
}

// MinMaxLocWithMask finds the global minimum and maximum in an array with a mask used to select a sub-array.
//
// For further details, please see:
// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#gab473bf2eb6d14ff97e89b355dac20707
func MinMaxLocWithMask(input, mask Mat) (minVal, maxVal float32, minLoc, maxLoc image.Point) {
var cMinVal C.double
var cMaxVal C.double
var cMinLoc C.struct_Point
var cMaxLoc C.struct_Point

C.Mat_MinMaxLocWithMask(input.p, &cMinVal, &cMaxVal, &cMinLoc, &cMaxLoc, mask.p)

minLoc = image.Pt(int(cMinLoc.x), int(cMinLoc.y))
maxLoc = image.Pt(int(cMaxLoc.x), int(cMaxLoc.y))

return float32(cMinVal), float32(cMaxVal), minLoc, maxLoc
}

// Copies specified channels from input arrays to the specified channels of output arrays.
//
// For further details, please see:
Expand Down
1 change: 1 addition & 0 deletions core.h
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ void Mat_Merge(struct Mats mats, Mat dst);
void Mat_Min(Mat src1, Mat src2, Mat dst);
void Mat_MinMaxIdx(Mat m, double* minVal, double* maxVal, int* minIdx, int* maxIdx);
void Mat_MinMaxLoc(Mat m, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc);
void Mat_MinMaxLocWithMask(Mat m, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc, Mat mask);
void Mat_MixChannels(struct Mats src, struct Mats dst, struct IntVector fromTo);
void Mat_MulSpectrums(Mat a, Mat b, Mat c, int flags);
void Mat_Multiply(Mat src1, Mat src2, Mat dst);
Expand Down
54 changes: 54 additions & 0 deletions core_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3142,3 +3142,57 @@ func TestSetThreadNumber(t *testing.T) {

SetNumThreads(original)
}

func TestMinMaxLoc(t *testing.T) {
input := NewMatWithSize(2, 2, MatTypeCV32F)
defer input.Close()
input.SetFloatAt(0, 0, 1)
input.SetFloatAt(0, 1, 2)
input.SetFloatAt(1, 0, 3)
input.SetFloatAt(1, 1, 4)
minVal, maxVal, minLoc, maxLoc := MinMaxLoc(input)

wantMinVal, wantMaxValue := float32(1.0), float32(4.0)
if minVal != wantMinVal {
t.Errorf("minVal got: %v, want %v", minVal, wantMinVal)
}
if maxVal != wantMaxValue {
t.Errorf("maxVal got: %v, want %v", maxVal, wantMaxValue)
}
wantMinLoc, wantMaxLoc := image.Point{Y: 0, X: 0}, image.Point{Y: 1, X: 1}
if minLoc != wantMinLoc {
t.Errorf("minLoc got: %v, want %v", minLoc, wantMinLoc)
}
if maxLoc != wantMaxLoc {
t.Errorf("maxLoc got: %v, want %v", maxLoc, wantMaxLoc)
}
}

func TestMinMaxLocWithMask(t *testing.T) {
input := NewMatWithSize(2, 2, MatTypeCV32F)
defer input.Close()
input.SetFloatAt(0, 0, 1)
input.SetFloatAt(0, 1, 2)
input.SetFloatAt(1, 0, 3)
input.SetFloatAt(1, 1, 4)
mask := NewMatWithSize(2, 2, MatTypeCV8U)
defer mask.Close()
mask.SetUCharAt(1, 0, 1)
mask.SetUCharAt(1, 1, 1)
minVal, maxVal, minLoc, maxLoc := MinMaxLocWithMask(input, mask)

wantMinVal, wantMaxValue := float32(3.0), float32(4.0)
if minVal != wantMinVal {
t.Errorf("minVal got: %v, want %v", minVal, wantMinVal)
}
if maxVal != wantMaxValue {
t.Errorf("maxVal got: %v, want %v", maxVal, wantMaxValue)
}
wantMinLoc, wantMaxLoc := image.Point{Y: 1, X: 0}, image.Point{Y: 1, X: 1}
if minLoc != wantMinLoc {
t.Errorf("minLoc got: %v, want %v", minLoc, wantMinLoc)
}
if maxLoc != wantMaxLoc {
t.Errorf("maxLoc got: %v, want %v", maxLoc, wantMaxLoc)
}
}
Loading