diff --git a/contrib/xfeatures2d.cpp b/contrib/xfeatures2d.cpp index fdf46759..784195e5 100644 --- a/contrib/xfeatures2d.cpp +++ b/contrib/xfeatures2d.cpp @@ -64,5 +64,28 @@ void BeblidDescriptorExtractor_Compute(BeblidDescriptorExtractor b, Mat src, str keypts.push_back(keypt); } + (*b)->compute(*src, keypts, *desc); +} + +TeblidDescriptorExtractor TeblidDescriptorExtractor_Create(float scaleFactor, int size) { + return new cv::Ptr(cv::xfeatures2d::TEBLID::create(scaleFactor, size)); +} + +void TeblidDescriptorExtractor_Close(TeblidDescriptorExtractor b) { + delete b; +} + +void TeblidDescriptorExtractor_Compute(TeblidDescriptorExtractor b, Mat src, struct KeyPoints kp, Mat desc) { + std::vector keypts; + keypts.reserve(kp.length); + cv::KeyPoint keypt; + + for (int i = 0; i < kp.length; ++i) { + keypt = cv::KeyPoint(kp.keypoints[i].x, kp.keypoints[i].y, + kp.keypoints[i].size, kp.keypoints[i].angle, kp.keypoints[i].response, + kp.keypoints[i].octave, kp.keypoints[i].classID); + keypts.push_back(keypt); + } + (*b)->compute(*src, keypts, *desc); } \ No newline at end of file diff --git a/contrib/xfeatures2d.go b/contrib/xfeatures2d.go index e0ea134b..4a6eba89 100644 --- a/contrib/xfeatures2d.go +++ b/contrib/xfeatures2d.go @@ -77,7 +77,7 @@ func getKeyPoints(ret C.KeyPoints) []gocv.KeyPoint { return keys } -// BeblidDescriptorExtractor is a wrapper around the cv::BeblidDescriptorExtractor descriptor algorithm. +// BeblidDescriptorExtractor is a wrapper around the cv::xfeatures2d::BEBLID descriptor algorithm. type BeblidDescriptorExtractor struct { // C.BeblidDescriptorExtractor p unsafe.Pointer @@ -93,7 +93,7 @@ const ( // NewBeblidDescriptorExtractor returns a new BEBLID descriptor algorithm. // // For further details, please see: -// https://docs.opencv.org/master/d5/df7/classcv_1_1xfeatures2d_1_1SURF.html +// https://docs.opencv.org/4.9.0/d7/d99/classcv_1_1xfeatures2d_1_1BEBLID.html func NewBeblidDescriptorExtractor(scaleFactor float32, size BeblidDescriptorExtractorSize) BeblidDescriptorExtractor { return BeblidDescriptorExtractor{p: unsafe.Pointer(C.BeblidDescriptorExtractor_Create(C.float(scaleFactor), C.int(size)))} } @@ -131,3 +131,58 @@ func (b *BeblidDescriptorExtractor) Compute(keyPoints []gocv.KeyPoint, src gocv. C.BeblidDescriptorExtractor_Compute((C.BeblidDescriptorExtractor)(b.p), C.Mat(src.Ptr()), cKeyPoints, C.Mat(desc.Ptr())) return desc } + +// TeblidDescriptorExtractor is a wrapper around the cv::xfeatures2d::TEBLID descriptor algorithm. +type TeblidDescriptorExtractor struct { + // C.TeblidDescriptorExtractor + p unsafe.Pointer +} + +type TeblidDescriptorExtractorSize = int + +const ( + TEBLID_SIZE_256_BITS TeblidDescriptorExtractorSize = 102 + TEBLID_SIZE_512_BITS TeblidDescriptorExtractorSize = 103 +) + +// NewTeblidDescriptorExtractor returns a new TEBLID descriptor algorithm. +// +// For further details, please see: +// https://docs.opencv.org/4.x/dd/dc1/classcv_1_1xfeatures2d_1_1TEBLID.html +func NewTeblidDescriptorExtractor(scaleFactor float32, size TeblidDescriptorExtractorSize) TeblidDescriptorExtractor { + return TeblidDescriptorExtractor{p: unsafe.Pointer(C.TeblidDescriptorExtractor_Create(C.float(scaleFactor), C.int(size)))} +} + +// Close TEBLID. +func (d *TeblidDescriptorExtractor) Close() error { + C.TeblidDescriptorExtractor_Close((C.TeblidDescriptorExtractor)(d.p)) + d.p = nil + return nil +} + +// Detect describes keypoints in an image using TEBLID +// +// For further details, please see: +// https://docs.opencv.org/4.x/dd/dc1/classcv_1_1xfeatures2d_1_1TEBLID.html +func (b *TeblidDescriptorExtractor) Compute(keyPoints []gocv.KeyPoint, src gocv.Mat) gocv.Mat { + desc := gocv.NewMat() + cKeyPointArray := make([]C.struct_KeyPoint, len(keyPoints)) + + for i, kp := range keyPoints { + cKeyPointArray[i].x = C.double(kp.X) + cKeyPointArray[i].y = C.double(kp.Y) + cKeyPointArray[i].size = C.double(kp.Size) + cKeyPointArray[i].angle = C.double(kp.Angle) + cKeyPointArray[i].response = C.double(kp.Response) + cKeyPointArray[i].octave = C.int(kp.Octave) + cKeyPointArray[i].classID = C.int(kp.ClassID) + } + + cKeyPoints := C.struct_KeyPoints{ + keypoints: (*C.struct_KeyPoint)(&cKeyPointArray[0]), + length: (C.int)(len(keyPoints)), + } + + C.TeblidDescriptorExtractor_Compute((C.TeblidDescriptorExtractor)(b.p), C.Mat(src.Ptr()), cKeyPoints, C.Mat(desc.Ptr())) + return desc +} diff --git a/contrib/xfeatures2d.h b/contrib/xfeatures2d.h index 78ba5194..be46d242 100644 --- a/contrib/xfeatures2d.h +++ b/contrib/xfeatures2d.h @@ -12,9 +12,11 @@ extern "C" { #ifdef __cplusplus typedef cv::Ptr* SURF; typedef cv::Ptr* BeblidDescriptorExtractor; +typedef cv::Ptr* TeblidDescriptorExtractor; #else typedef void* SURF; typedef void* BeblidDescriptorExtractor; +typedef void* TeblidDescriptorExtractor; #endif SURF SURF_Create(); @@ -26,6 +28,10 @@ BeblidDescriptorExtractor BeblidDescriptorExtractor_Create(float scaleFactor, in void BeblidDescriptorExtractor_Close(BeblidDescriptorExtractor b); void BeblidDescriptorExtractor_Compute(BeblidDescriptorExtractor b, Mat src, struct KeyPoints kp, Mat desc); +TeblidDescriptorExtractor TeblidDescriptorExtractor_Create(float scaleFactor, int size); +void TeblidDescriptorExtractor_Close(TeblidDescriptorExtractor b); +void TeblidDescriptorExtractor_Compute(TeblidDescriptorExtractor b, Mat src, struct KeyPoints kp, Mat desc); + #ifdef __cplusplus } #endif diff --git a/contrib/xfeatures2d_test.go b/contrib/xfeatures2d_test.go index 5411ea75..ad50cff2 100644 --- a/contrib/xfeatures2d_test.go +++ b/contrib/xfeatures2d_test.go @@ -72,3 +72,33 @@ func TestBeblidDescriptorExtractor(t *testing.T) { t.Error("Invalid Mat desc in BeblidDescriptorExtractor Compute") } } + +func TestTeblidDescriptorExtractor(t *testing.T) { + testNonFree := os.Getenv("OPENCV_ENABLE_NONFREE") + if testNonFree == "" { + t.Skip("Skipping TeblidDescriptorExtractor test since OPENCV_ENABLE_NONFREE was not set") + } + + img := gocv.IMRead("../images/face.jpg", gocv.IMReadGrayScale) + if img.Empty() { + t.Error("Invalid Mat in TeblidDescriptorExtractor test") + } + defer img.Close() + + fast := gocv.NewFastFeatureDetector() + defer fast.Close() + + b := NewTeblidDescriptorExtractor(1.00, TEBLID_SIZE_512_BITS) + defer b.Close() + + kp := fast.Detect(img) + + mask := gocv.NewMat() + defer mask.Close() + + desc := b.Compute(kp, img) + + if desc.Empty() { + t.Error("Invalid Mat desc in TeblidDescriptorExtractor Compute") + } +}