//go:build !gocv_specific_modules || (gocv_specific_modules && gocv_features2d) package gocv import ( "image/color" "runtime" "testing" ) func TestAKAZE(t *testing.T) { img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in AKAZE test") } defer img.Close() dst := NewMat() defer dst.Close() ak := NewAKAZE() defer ak.Close() kp := ak.Detect(img) if len(kp) < 512 { t.Errorf("Invalid KeyPoint array in AKAZE test: %d", len(kp)) } mask := NewMat() defer mask.Close() kpc, desc := ak.Compute(img, mask, kp) defer desc.Close() if len(kpc) < 512 { t.Errorf("Invalid KeyPoint array in AKAZE Compute: %d", len(kpc)) } if desc.Empty() { t.Error("Invalid Mat desc in AKAZE Compute") } kpdc, desc2 := ak.DetectAndCompute(img, mask) defer desc2.Close() if len(kpdc) < 512 { t.Errorf("Invalid KeyPoint array in AKAZE DetectAndCompute: %d", len(kpdc)) } if desc2.Empty() { t.Error("Invalid Mat desc in AKAZE DetectAndCompute") } } func TestAKAZEWithParams(t *testing.T) { img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in AKAZE test") } defer img.Close() dst := NewMat() defer dst.Close() ak := NewAKAZEWithParams(3, 0, 3, 0.001, 4, 4, 1) defer ak.Close() // Test Detect method kp := ak.Detect(img) if len(kp) < 473 { t.Errorf("Invalid KeyPoint array in AKAZE test: %d", len(kp)) } mask := NewMat() defer mask.Close() kpc, desc := ak.Compute(img, mask, kp) defer desc.Close() if len(kpc) < 473 { t.Errorf("Invalid KeyPoint array in AKAZE Compute: %d", len(kpc)) } if desc.Empty() { t.Error("Invalid Mat desc in AKAZE Compute") } kpdc, desc2 := ak.DetectAndCompute(img, mask) defer desc2.Close() if len(kpdc) < 473 { t.Errorf("Invalid KeyPoint array in AKAZE DetectAndCompute: %d", len(kpdc)) } if desc2.Empty() { t.Error("Invalid Mat desc in AKAZE DetectAndCompute") } } func TestAgastFeatureDetector(t *testing.T) { img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in AgastFeatureDetector test") } defer img.Close() dst := NewMat() defer dst.Close() ad := NewAgastFeatureDetector() defer ad.Close() kp := ad.Detect(img) if len(kp) < 2800 { t.Errorf("Invalid KeyPoint array in AgastFeatureDetector test: %d", len(kp)) } } func TestAgastFeatureDetectorWithParams(t *testing.T) { img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in AgastFeatureDetector test") } defer img.Close() dst := NewMat() defer dst.Close() ad := NewAgastFeatureDetectorWithParams(10, true, 0) defer ad.Close() kp := ad.Detect(img) if len(kp) < 2137 { t.Errorf("Invalid KeyPoint array in AgastFeatureDetector test: %d", len(kp)) } } func TestBRISK(t *testing.T) { img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in BRISK test") } defer img.Close() dst := NewMat() defer dst.Close() br := NewBRISK() defer br.Close() kp := br.Detect(img) if len(kp) < 513 { t.Errorf("Invalid KeyPoint array in BRISK Detect: %d", len(kp)) } mask := NewMat() defer mask.Close() kpc, desc := br.Compute(img, mask, kp) defer desc.Close() if len(kpc) < 512 { t.Errorf("Invalid KeyPoint array in BRISK Compute: %d", len(kpc)) } if desc.Empty() { t.Error("Invalid Mat desc in BRISK Compute") } kpdc, desc2 := br.DetectAndCompute(img, mask) defer desc2.Close() if len(kpdc) < 512 { t.Errorf("Invalid KeyPoint array in BRISK DetectAndCompute: %d", len(kpdc)) } if desc2.Empty() { t.Error("Invalid Mat desc in BRISK DetectAndCompute") } } func TestBRISKWithParams(t *testing.T) { img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in BRISK test") } defer img.Close() dst := NewMat() defer dst.Close() // Create BRISK with custom parameters (e.g., threshold = 30, octaves = 3, patternScale = 1.0) br := NewBRISKWithParams(30, 3, 1.0) defer br.Close() kp := br.Detect(img) if len(kp) < 513 { t.Errorf("Invalid KeyPoint array in BRISK Detect: %d", len(kp)) } mask := NewMat() defer mask.Close() kpc, desc := br.Compute(img, mask, kp) defer desc.Close() if len(kpc) < 512 { t.Errorf("Invalid KeyPoint array in BRISK Compute: %d", len(kpc)) } if desc.Empty() { t.Error("Invalid Mat desc in BRISK Compute") } kpdc, desc2 := br.DetectAndCompute(img, mask) defer desc2.Close() if len(kpdc) < 512 { t.Errorf("Invalid KeyPoint array in BRISK DetectAndCompute: %d", len(kpdc)) } if desc2.Empty() { t.Error("Invalid Mat desc in BRISK DetectAndCompute") } } func TestFastFeatureDetector(t *testing.T) { img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in FastFeatureDetector test") } defer img.Close() dst := NewMat() defer dst.Close() fd := NewFastFeatureDetector() defer fd.Close() kp := fd.Detect(img) if len(kp) < 2690 { t.Errorf("Invalid KeyPoint array in FastFeatureDetector test: %d", len(kp)) } } func TestFastFeatureDetectorWithParams(t *testing.T) { img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in FastFeatureDetector test") } defer img.Close() dst := NewMat() defer dst.Close() fd := NewFastFeatureDetectorWithParams(10, true, FastFeatureDetectorType916) defer fd.Close() kp := fd.Detect(img) if len(kp) < 2690 { t.Errorf("Invalid KeyPoint array in FastFeatureDetector test: %d", len(kp)) } } func TestGFTTDetector(t *testing.T) { img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in GFTTDetector test") } defer img.Close() dst := NewMat() defer dst.Close() gft := NewGFTTDetector() defer gft.Close() kp := gft.Detect(img) if len(kp) < 512 { t.Errorf("Invalid KeyPoint array in GFTTDetector test: %d", len(kp)) } } func TestGFTTDetectorWithParams(t *testing.T) { img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in GFTTDetector test") } defer img.Close() dst := NewMat() defer dst.Close() params := GFTTDetectorParams{ MaxCorners: 500, QualityLevel: 0.01, MinDistance: 10, BlockSize: 3, UseHarrisDetector: false, K: 0.04, } gft := NewGFTTDetectorWithParams(params) defer gft.Close() kp := gft.Detect(img) if len(kp) < 323 { t.Errorf("Invalid KeyPoint array in GFTTDetector test: %d", len(kp)) } } func TestKAZE(t *testing.T) { img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in KAZE test") } defer img.Close() dst := NewMat() defer dst.Close() k := NewKAZE() defer k.Close() kp := k.Detect(img) if len(kp) < 512 { t.Errorf("Invalid KeyPoint array in KAZE test: %d", len(kp)) } mask := NewMat() defer mask.Close() kpc, desc := k.Compute(img, mask, kp) defer desc.Close() if len(kpc) < 512 { t.Errorf("Invalid KeyPoint array in KAZE Compute: %d", len(kpc)) } if desc.Empty() { t.Error("Invalid Mat desc in KAZE Compute") } kpdc, desc2 := k.DetectAndCompute(img, mask) defer desc2.Close() if len(kpdc) < 512 { t.Errorf("Invalid KeyPoint array in KAZE DetectAndCompute: %d", len(kpdc)) } if desc2.Empty() { t.Error("Invalid Mat desc in KAZE DetectAndCompute") } } func TestKAZEWithParams(t *testing.T) { // Load the image for testing img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in KAZE With Params test") } defer img.Close() // Create a destination matrix dst := NewMat() defer dst.Close() // Set up the parameters for KAZE with the function NewKazeWithParams extended := true upright := false threshold := float32(0.001) nOctaves := 4 nOctaveLayers := 4 diffusivity := 1 // Based on your input parameter options (e.g., 1 could be for `cv::KAZE::DIFF_PM_G2`) // Create a KAZE object with the specified parameters k := NewKazeWithParams(extended, upright, threshold, nOctaves, nOctaveLayers, diffusivity) defer k.Close() // Detect keypoints kp := k.Detect(img) if len(kp) < 512 { t.Errorf("Invalid KeyPoint array in KAZE With Params test: %d", len(kp)) } // Create a mask (optional) mask := NewMat() defer mask.Close() // Compute descriptors for the keypoints kpc, desc := k.Compute(img, mask, kp) defer desc.Close() if len(kpc) < 512 { t.Errorf("Invalid KeyPoint array in KAZE With Params Compute: %d", len(kpc)) } if desc.Empty() { t.Error("Invalid Mat desc in KAZE With Params Compute") } // Perform DetectAndCompute kpdc, desc2 := k.DetectAndCompute(img, mask) defer desc2.Close() if len(kpdc) < 512 { t.Errorf("Invalid KeyPoint array in KAZE With Params DetectAndCompute: %d", len(kpdc)) } if desc2.Empty() { t.Error("Invalid Mat desc in KAZE With Params DetectAndCompute") } } func TestMSER(t *testing.T) { img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in MSER test") } defer img.Close() dst := NewMat() defer dst.Close() mser := NewMSER() defer mser.Close() kp := mser.Detect(img) if len(kp) == 0 { t.Errorf("Invalid KeyPoint array in MSER test: %d", len(kp)) } } func TestMSERWithParams(t *testing.T) { img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in MSER With Params test") } defer img.Close() dst := NewMat() defer dst.Close() delta := 5 minArea := 60 maxArea := 14400 maxVariation := 0.25 minDiversity := 0.2 maxEvolution := 200 areaThreshold := 1.01 minMargin := 0.003 edgeBlurSize := 5 mser := NewMSERWithParams(delta, minArea, maxArea, maxVariation, minDiversity, maxEvolution, areaThreshold, minMargin, edgeBlurSize) defer mser.Close() regions := mser.Detect(img) if len(regions) == 0 { t.Errorf("Invalid region detection in MSER With Params test: %d", len(regions)) } } func TestORB(t *testing.T) { img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in AgastFeatureDetector test") } defer img.Close() dst := NewMat() defer dst.Close() od := NewORB() defer od.Close() kp := od.Detect(img) if len(kp) != 500 { t.Errorf("Invalid KeyPoint array in ORB test: %d", len(kp)) } mask := NewMat() defer mask.Close() kpc, desc := od.Compute(img, mask, kp) defer desc.Close() if len(kpc) < 500 { t.Errorf("Invalid KeyPoint array in ORB Compute: %d", len(kpc)) } if desc.Empty() { t.Error("Invalid Mat desc in ORB Compute") } kpdc, desc2 := od.DetectAndCompute(img, mask) defer desc2.Close() if len(kpdc) < 500 { t.Errorf("Invalid KeyPoint array in ORB DetectAndCompute: %d", len(kpdc)) } if desc2.Empty() { t.Error("Invalid Mat desc in ORB DetectAndCompute") } } func TestSimpleBlobDetector(t *testing.T) { img := IMRead("images/face.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in SimpleBlobDetector test") } defer img.Close() dst := NewMat() defer dst.Close() bd := NewSimpleBlobDetector() defer bd.Close() kp := bd.Detect(img) if len(kp) != 2 { t.Errorf("Invalid KeyPoint array in SimpleBlobDetector test: %d", len(kp)) } } func TestSimpleBlobDetectorWithParams(t *testing.T) { img := IMRead("images/circles.jpg", IMReadColor) if img.Empty() { t.Error("Invalid Mat in SimpleBlobDetector test") } defer img.Close() params := NewSimpleBlobDetectorParams() params.SetMaxArea(27500.0) bdp := NewSimpleBlobDetectorWithParams(params) defer bdp.Close() kp := bdp.Detect(img) if len(kp) != 4 { t.Errorf("Invalid KeyPoint array in SimpleBlobDetector test: %d", len(kp)) } } func TestSimpleBlobDetectorParams(t *testing.T) { float64EqualityThreshold := 1e-5 knownBlobColor := 235 knownFilterByArea := false knownFilterByCircularity := true knownFilterByColor := false knownFilterByConvexity := false knownFilterByInertia := false knownMaxArea := 20000.0 knownMaxCircularity := 0.99 knownMaxConvexity := 0.98 knownMaxInertiaRatio := 0.97 knownMaxThreshold := 233.0 knownMinArea := 230.0 knownMinCircularity := 0.9 knownMinConvexity := 0.89 knownMinDistBetweenBlobs := 15.5 knownMinInertiaRatio := 0.88 knownMinRepeatability := 5 knownMinThreshold := 200.0 knownThresholdStep := 2.0 params := NewSimpleBlobDetectorParams() params.SetBlobColor(knownBlobColor) params.SetFilterByArea(knownFilterByArea) params.SetFilterByCircularity(knownFilterByCircularity) params.SetFilterByColor(knownFilterByColor) params.SetFilterByConvexity(knownFilterByConvexity) params.SetFilterByInertia(knownFilterByInertia) params.SetMaxArea(knownMaxArea) params.SetMaxCircularity(knownMaxCircularity) params.SetMaxConvexity(knownMaxConvexity) params.SetMaxInertiaRatio(knownMaxInertiaRatio) params.SetMaxThreshold(knownMaxThreshold) params.SetMinArea(knownMinArea) params.SetMinCircularity(knownMinCircularity) params.SetMinConvexity(knownMinConvexity) params.SetMinDistBetweenBlobs(knownMinDistBetweenBlobs) params.SetMinInertiaRatio(knownMinInertiaRatio) params.SetMinRepeatability(knownMinRepeatability) params.SetMinThreshold(knownMinThreshold) params.SetThresholdStep(knownThresholdStep) if params.GetBlobColor() != knownBlobColor { t.Error("BlobColor incorrect in SimpleBlobDetectorParams test") } if params.GetFilterByArea() != knownFilterByArea { t.Error("FilterByArea incorrect in SimpleBlobDetectorParams test") } if params.GetFilterByCircularity() != knownFilterByCircularity { t.Error("FilterByCircularity incorrect in SimpleBlobDetectorParams test") } if params.GetFilterByColor() != knownFilterByColor { t.Error("FilterByColor incorrect in SimpleBlobDetectorParams test") } if params.GetFilterByConvexity() != knownFilterByConvexity { t.Error("FilterByConvexity incorrect in SimpleBlobDetectorParams test") } if params.GetFilterByInertia() != knownFilterByInertia { t.Error("FilterByInertia incorrect in SimpleBlobDetectorParams test") } if params.GetMaxArea() != knownMaxArea { t.Error("MaxArea incorrect in SimpleBlobDetectorParams test") } diffMaxCircularity := params.GetMaxCircularity() - knownMaxCircularity if diffMaxCircularity > float64EqualityThreshold { t.Errorf("DiffMaxCircularity greater than float64EqualityThreshold in SimpleBlobDetectorParams test. Diff: %f", diffMaxCircularity) } diffMaxConvexity := params.GetMaxConvexity() - knownMaxConvexity if diffMaxConvexity > float64EqualityThreshold { t.Errorf("DiffMaxConvexity greater than float64EqualityThreshold in SimpleBlobDetectorParams test. Diff: %f", diffMaxConvexity) } diffMaxInertiaRatio := params.GetMaxInertiaRatio() - knownMaxInertiaRatio if diffMaxInertiaRatio > float64EqualityThreshold { t.Errorf("DiffMaxInertiaRatio greater than float64EqualityThreshold in SimpleBlobDetectorParams test. Diff: %f", diffMaxInertiaRatio) } if params.GetMaxThreshold() != knownMaxThreshold { t.Error("MaxThreshold incorrect in SimpleBlobDetectorParams test") } if params.GetMinArea() != knownMinArea { t.Error("MinArea incorrect in SimpleBlobDetectorParams test") } diffMinCircularity := params.GetMinCircularity() - knownMinCircularity if diffMinCircularity > float64EqualityThreshold { t.Errorf("DiffMinCircularity greater than float64EqualityThreshold in SimpleBlobDetectorParams test. Diff %f", diffMinCircularity) } diffMinConvexity := params.GetMinConvexity() - knownMinConvexity if diffMinConvexity > float64EqualityThreshold { t.Errorf("DiffMinConvexity greater than float64EqualityThreshold in SimpleBlobDetectorParams test. Diff: %f", diffMinConvexity) } if params.GetMinDistBetweenBlobs() != knownMinDistBetweenBlobs { t.Error("MinDistBetweenBlobs incorrect in SimpleBlobDetectorParams test") } diffMinInertiaRatio := params.GetMinInertiaRatio() - knownMinInertiaRatio if diffMinInertiaRatio > float64EqualityThreshold { t.Errorf("DiffMinInertiaRatio greater than float64EqualityThreshold in SimpleBlobDetectorParams test. Diff: %f", diffMinInertiaRatio) } if params.GetMinRepeatability() != knownMinRepeatability { t.Error("MinRepeatability incorrect in SimpleBlobDetectorParams test") } if params.GetMinThreshold() != knownMinThreshold { t.Error("MinThreshold incorrect in SimpleBlobDetectorParams test") } if params.GetThresholdStep() != knownThresholdStep { t.Error("ThresholdStep incorrect in SimpleBlobDetectorParams test") } } func TestBFMatcher(t *testing.T) { descriptorFile := "images/sift_descriptor.png" desc1 := IMRead(descriptorFile, IMReadGrayScale) if desc1.Empty() { t.Error("descriptor one is empty in BFMatcher test") } defer desc1.Close() desc2 := IMRead(descriptorFile, IMReadGrayScale) if desc2.Empty() { t.Error("descriptor two is empty in BFMatcher test") } defer desc2.Close() bf := NewBFMatcher() defer bf.Close() k := 2 dMatches := bf.KnnMatch(desc1, desc2, k) if len(dMatches) < 1 { t.Errorf("DMatches was excepted to have at least one element") } for i := range dMatches { if len(dMatches[i]) != k { t.Errorf("Length does not match k cluster amount in BFMatcher") } } matches := bf.Match(desc1, desc2) if len(matches) != 890 { t.Errorf("Matches was excepted to have 890 elements, but it has %d", len(matches)) } bfParams := NewBFMatcherWithParams(NormHamming, false) defer bfParams.Close() dMatches = bfParams.KnnMatch(desc1, desc2, k) if len(dMatches) < 1 { t.Errorf("DMatches was excepted to have at least one element") } for i := range dMatches { if len(dMatches[i]) != k { t.Errorf("Length does not match k cluster amount in BFMatcher") } } } func TestFlannBasedMatcher(t *testing.T) { descriptorFile := "images/sift_descriptor.png" desc1 := IMRead(descriptorFile, IMReadGrayScale) if desc1.Empty() { t.Error("descriptor one is empty in FlannBasedMatcher test") } defer desc1.Close() desc1.ConvertTo(&desc1, MatTypeCV32F) desc2 := IMRead(descriptorFile, IMReadGrayScale) if desc2.Empty() { t.Error("descriptor two is empty in FlannBasedMatcher test") } defer desc2.Close() desc2.ConvertTo(&desc2, MatTypeCV32F) f := NewFlannBasedMatcher() defer f.Close() k := 2 dMatches := f.KnnMatch(desc1, desc2, k) if len(dMatches) < 1 { t.Errorf("DMatches was excepted to have at least one element") } for i := range dMatches { if len(dMatches[i]) != k { t.Errorf("Length does not match k cluster amount in FlannBasedMatcher") } } } func TestDrawKeyPoints(t *testing.T) { keypointsFile := "images/simple.jpg" img := IMRead(keypointsFile, IMReadColor) if img.Empty() { t.Error("keypoints file is empty in DrawKeyPoints test") } defer img.Close() ffd := NewFastFeatureDetector() kp := ffd.Detect(img) simpleKP := NewMat() defer simpleKP.Close() DrawKeyPoints(img, kp, &simpleKP, color.RGBA{255, 0, 0, 0}, DrawDefault) if simpleKP.Rows() != img.Rows() || simpleKP.Cols() != img.Cols() { t.Error("Invalid DrawKeyPoints test") } } func TestDrawMatches(t *testing.T) { if runtime.GOOS == "darwin" { t.Skip("skipping test on macos") } queryFile := "images/box.png" trainFile := "images/box_in_scene.png" query := IMRead(queryFile, IMReadGrayScale) train := IMRead(trainFile, IMReadGrayScale) if query.Empty() || train.Empty() { t.Error("at least one of files is empty in DrawMatches test") } defer query.Close() defer train.Close() sift := NewSIFT() defer sift.Close() m1 := NewMat() m2 := NewMat() defer m1.Close() defer m2.Close() kp1, des1 := sift.DetectAndCompute(query, m1) kp2, des2 := sift.DetectAndCompute(train, m2) defer des1.Close() defer des2.Close() bf := NewBFMatcher() defer bf.Close() matches := bf.KnnMatch(des1, des2, 2) if len(matches) == 0 { t.Error("no matches found in DrawMatches test") } var good []DMatch for _, m := range matches { if len(m) > 1 { if m[0].Distance < 0.75*m[1].Distance { good = append(good, m[0]) } } } c := color.RGBA{ R: 255, G: 0, B: 0, A: 0, } mask := make([]byte, 0) out := NewMat() defer out.Close() DrawMatches(query, kp1, train, kp2, good, &out, c, c, mask, DrawDefault) if out.Cols() != (query.Cols()+train.Cols()) || out.Rows() < train.Rows() || out.Rows() < query.Rows() { t.Error("Invalid DrawMatches test") } mask = make([]byte, len(good)) smoke := NewMat() defer smoke.Close() DrawMatches(query, kp1, train, kp2, good, &smoke, c, c, mask, DrawDefault) } func TestSIFT(t *testing.T) { if runtime.GOOS == "darwin" { t.Skip("skipping test on macos") } img := IMRead("./images/face.jpg", IMReadGrayScale) if img.Empty() { t.Error("Invalid Mat in SIFT test") } defer img.Close() dst := NewMat() defer dst.Close() si := NewSIFT() defer si.Close() kp := si.Detect(img) if len(kp) == 512 { t.Errorf("Invalid KeyPoint array in SIFT test: %d", len(kp)) } mask := NewMat() defer mask.Close() kpc, desc := si.Compute(img, mask, kp) defer desc.Close() if len(kpc) < 512 { t.Errorf("Invalid KeyPoint array in SIFT Compute: %d", len(kpc)) } if desc.Empty() { t.Error("Invalid Mat desc in SIFT Compute") } kpdc, desc2 := si.DetectAndCompute(img, mask) defer desc2.Close() if len(kpdc) < 512 { t.Errorf("Invalid KeyPoint array in SIFT DetectAndCompute: %d", len(kpdc)) } if desc2.Empty() { t.Error("Invalid Mat desc in SIFT DetectAndCompute") } } func TestSIFTWithParams(t *testing.T) { if runtime.GOOS == "darwin" { t.Skip("skipping test on macos") } img := IMRead("./images/face.jpg", IMReadGrayScale) if img.Empty() { t.Error("Invalid Mat in SIFT test") } defer img.Close() dst := NewMat() defer dst.Close() nFeatures := 256 nOctaveLayers := 3 contrastThreshold := 0.039 var edgeThreshold float64 = 11 sigma := 1.55 si := NewSIFTWithParams(&nFeatures, &nOctaveLayers, &contrastThreshold, &edgeThreshold, &sigma) defer si.Close() kp := si.Detect(img) if len(kp) != 256 { t.Errorf("Invalid KeyPoint array in SIFT test: %d", len(kp)) } mask := NewMat() defer mask.Close() kpc, desc := si.Compute(img, mask, kp) defer desc.Close() if len(kpc) != 256 { t.Errorf("Invalid KeyPoint array in SIFT Compute: %d", len(kpc)) } if desc.Empty() { t.Error("Invalid Mat desc in SIFT Compute") } kpdc, desc2 := si.DetectAndCompute(img, mask) defer desc2.Close() if len(kpdc) != 256 { t.Errorf("Invalid KeyPoint array in SIFT DetectAndCompute: %d", len(kpdc)) } if desc2.Empty() { t.Error("Invalid Mat desc in SIFT DetectAndCompute") } }