Skip to content

Commit

Permalink
Add separate "Compute" bindings for detection algorithms (#1117)
Browse files Browse the repository at this point in the history
features2d, contrib/xfeatures2d: Implement Compute bindings for AKAZE, BRISK, KAZE, ORB, SIFT and SURF
  • Loading branch information
pericles-tpt authored Oct 24, 2023
1 parent a573f59 commit ca77b8f
Show file tree
Hide file tree
Showing 8 changed files with 397 additions and 29 deletions.
24 changes: 24 additions & 0 deletions contrib/xfeatures2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,30 @@ struct KeyPoints SURF_Detect(SURF d, Mat src) {
return ret;
}

struct KeyPoints SURF_Compute(SURF d, Mat src, struct KeyPoints kp, Mat desc) {
std::vector<cv::KeyPoint> computed;
for (size_t i = 0; i < kp.length; i++) {
cv::KeyPoint k = 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);
computed.push_back(k);
}

(*d)->compute(*src, computed, *desc);

KeyPoint* kps = new KeyPoint[computed.size()];

for (size_t i = 0; i < computed.size(); ++i) {
KeyPoint k = {computed[i].pt.x, computed[i].pt.y, computed[i].size, computed[i].angle,
computed[i].response, computed[i].octave, computed[i].class_id
};
kps[i] = k;
}

KeyPoints ret = {kps, (int)computed.size()};
return ret;
}

struct KeyPoints SURF_DetectAndCompute(SURF d, Mat src, Mat mask, Mat desc) {
std::vector<cv::KeyPoint> detected;
(*d)->detectAndCompute(*src, *mask, detected, *desc);
Expand Down
25 changes: 25 additions & 0 deletions contrib/xfeatures2d.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,31 @@ func (d *SURF) Detect(src gocv.Mat) []gocv.KeyPoint {
return getKeyPoints(ret)
}

// Compute keypoints in an image using SURF.
//
// For further details, please see:
// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#ab3cce8d56f4fc5e1d530b5931e1e8dc0
func (d *SURF) Compute(src gocv.Mat, mask gocv.Mat, kps []gocv.KeyPoint) ([]gocv.KeyPoint, gocv.Mat) {
desc := gocv.NewMat()
kp2arr := make([]C.struct_KeyPoint, len(kps))
for i, kp := range kps {
kp2arr[i].x = C.double(kp.X)
kp2arr[i].y = C.double(kp.Y)
kp2arr[i].size = C.double(kp.Size)
kp2arr[i].angle = C.double(kp.Angle)
kp2arr[i].response = C.double(kp.Response)
kp2arr[i].octave = C.int(kp.Octave)
kp2arr[i].classID = C.int(kp.ClassID)
}
cKeyPoints := C.struct_KeyPoints{
keypoints: (*C.struct_KeyPoint)(&kp2arr[0]),
length: (C.int)(len(kps)),
}
ret := C.SURF_Compute((C.SURF)(d.p), C.Mat(src.Ptr()), cKeyPoints, C.Mat(desc.Ptr()))

return getKeyPoints(ret), desc
}

// DetectAndCompute detects and computes keypoints in an image using SURF.
//
// For further details, please see:
Expand Down
1 change: 1 addition & 0 deletions contrib/xfeatures2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ SURF SURF_Create();
SURF SURF_CreateWithParams(double hessianThreshold, int nOctaves, int nOctaveLayers, bool extended, bool upright);
void SURF_Close(SURF f);
struct KeyPoints SURF_Detect(SURF f, Mat src);
struct KeyPoints SURF_Compute(SURF f, Mat src, struct KeyPoints kp, Mat desc);
struct KeyPoints SURF_DetectAndCompute(SURF f, Mat src, Mat mask, Mat desc);
BriefDescriptorExtractor BriefDescriptorExtractor_Create();
BriefDescriptorExtractor BriefDescriptorExtractor_CreateWithParams(int bytes, bool useOrientation);
Expand Down
34 changes: 26 additions & 8 deletions contrib/xfeatures2d_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,21 @@ func TestSURF(t *testing.T) {
mask := gocv.NewMat()
defer mask.Close()

kp2, desc := si.DetectAndCompute(img, mask)
if len(kp2) == 512 {
t.Errorf("Invalid KeyPoint array in SURF DetectAndCompute: %d", len(kp2))
kpc, desc := si.Compute(img, mask, kp)
defer desc.Close()
if len(kpc) < 512 {
t.Errorf("Invalid KeyPoint array in SURF Compute: %d", len(kpc))
}

if desc.Empty() {
t.Error("Invalid Mat desc in SURF Compute")
}

kpdc, desc2 := si.DetectAndCompute(img, mask)
defer desc2.Close()
if len(kpdc) < 512 {
t.Errorf("Invalid KeyPoint array in SURF DetectAndCompute: %d", len(kpdc))
}
if desc2.Empty() {
t.Error("Invalid Mat desc in SURF DetectAndCompute")
}
}
Expand Down Expand Up @@ -69,12 +78,21 @@ func TestSURFWithParams(t *testing.T) {
mask := gocv.NewMat()
defer mask.Close()

kp2, desc := si.DetectAndCompute(img, mask)
if len(kp2) == 512 {
t.Errorf("Invalid KeyPoint array in SURF DetectAndCompute: %d", len(kp2))
kpc, desc := si.Compute(img, mask, kp)
defer desc.Close()
if len(kpc) < 512 {
t.Errorf("Invalid KeyPoint array in SURF Compute: %d", len(kpc))
}

if desc.Empty() {
t.Error("Invalid Mat desc in SURF Compute")
}

kpdc, desc2 := si.DetectAndCompute(img, mask)
defer desc2.Close()
if len(kpdc) < 512 {
t.Errorf("Invalid KeyPoint array in SURF DetectAndCompute: %d", len(kpdc))
}
if desc2.Empty() {
t.Error("Invalid Mat desc in SURF DetectAndCompute")
}
}
Expand Down
120 changes: 120 additions & 0 deletions features2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,30 @@ struct KeyPoints AKAZE_Detect(AKAZE a, Mat src) {
return ret;
}

struct KeyPoints AKAZE_Compute(AKAZE a, Mat src, struct KeyPoints kp, Mat desc) {
std::vector<cv::KeyPoint> computed;
for (size_t i = 0; i < kp.length; i++) {
cv::KeyPoint k = 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);
computed.push_back(k);
}

(*a)->compute(*src, computed, *desc);

KeyPoint* kps = new KeyPoint[computed.size()];

for (size_t i = 0; i < computed.size(); ++i) {
KeyPoint k = {computed[i].pt.x, computed[i].pt.y, computed[i].size, computed[i].angle,
computed[i].response, computed[i].octave, computed[i].class_id
};
kps[i] = k;
}

KeyPoints ret = {kps, (int)computed.size()};
return ret;
}

struct KeyPoints AKAZE_DetectAndCompute(AKAZE a, Mat src, Mat mask, Mat desc) {
std::vector<cv::KeyPoint> detected;
(*a)->detectAndCompute(*src, *mask, detected, *desc);
Expand Down Expand Up @@ -95,6 +119,30 @@ struct KeyPoints BRISK_Detect(BRISK b, Mat src) {
return ret;
}

struct KeyPoints BRISK_Compute(BRISK b, Mat src, struct KeyPoints kp, Mat desc) {
std::vector<cv::KeyPoint> computed;
for (size_t i = 0; i < kp.length; i++) {
cv::KeyPoint k = 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);
computed.push_back(k);
}

(*b)->compute(*src, computed, *desc);

KeyPoint* kps = new KeyPoint[computed.size()];

for (size_t i = 0; i < computed.size(); ++i) {
KeyPoint k = {computed[i].pt.x, computed[i].pt.y, computed[i].size, computed[i].angle,
computed[i].response, computed[i].octave, computed[i].class_id
};
kps[i] = k;
}

KeyPoints ret = {kps, (int)computed.size()};
return ret;
}

struct KeyPoints BRISK_DetectAndCompute(BRISK b, Mat src, Mat mask, Mat desc) {
std::vector<cv::KeyPoint> detected;
(*b)->detectAndCompute(*src, *mask, detected, *desc);
Expand Down Expand Up @@ -164,6 +212,30 @@ struct KeyPoints KAZE_Detect(KAZE a, Mat src) {
return ret;
}

struct KeyPoints KAZE_Compute(KAZE a, Mat src, struct KeyPoints kp, Mat desc) {
std::vector<cv::KeyPoint> computed;
for (size_t i = 0; i < kp.length; i++) {
cv::KeyPoint k = 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);
computed.push_back(k);
}

(*a)->compute(*src, computed, *desc);

KeyPoint* kps = new KeyPoint[computed.size()];

for (size_t i = 0; i < computed.size(); ++i) {
KeyPoint k = {computed[i].pt.x, computed[i].pt.y, computed[i].size, computed[i].angle,
computed[i].response, computed[i].octave, computed[i].class_id
};
kps[i] = k;
}

KeyPoints ret = {kps, (int)computed.size()};
return ret;
}

struct KeyPoints KAZE_DetectAndCompute(KAZE a, Mat src, Mat mask, Mat desc) {
std::vector<cv::KeyPoint> detected;
(*a)->detectAndCompute(*src, *mask, detected, *desc);
Expand Down Expand Up @@ -265,6 +337,30 @@ struct KeyPoints ORB_Detect(ORB o, Mat src) {
return ret;
}

struct KeyPoints ORB_Compute(ORB o, Mat src, struct KeyPoints kp, Mat desc) {
std::vector<cv::KeyPoint> computed;
for (size_t i = 0; i < kp.length; i++) {
cv::KeyPoint k = 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);
computed.push_back(k);
}

(*o)->compute(*src, computed, *desc);

KeyPoint* kps = new KeyPoint[computed.size()];

for (size_t i = 0; i < computed.size(); ++i) {
KeyPoint k = {computed[i].pt.x, computed[i].pt.y, computed[i].size, computed[i].angle,
computed[i].response, computed[i].octave, computed[i].class_id
};
kps[i] = k;
}

KeyPoints ret = {kps, (int)computed.size()};
return ret;
}

struct KeyPoints ORB_DetectAndCompute(ORB o, Mat src, Mat mask, Mat desc) {
std::vector<cv::KeyPoint> detected;
(*o)->detectAndCompute(*src, *mask, detected, *desc);
Expand Down Expand Up @@ -515,6 +611,30 @@ struct KeyPoints SIFT_Detect(SIFT d, Mat src) {
return ret;
}

struct KeyPoints SIFT_Compute(SIFT d, Mat src, struct KeyPoints kp, Mat desc) {
std::vector<cv::KeyPoint> computed;
for (size_t i = 0; i < kp.length; i++) {
cv::KeyPoint k = 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);
computed.push_back(k);
}

(*d)->compute(*src, computed, *desc);

KeyPoint* kps = new KeyPoint[computed.size()];

for (size_t i = 0; i < computed.size(); ++i) {
KeyPoint k = {computed[i].pt.x, computed[i].pt.y, computed[i].size, computed[i].angle,
computed[i].response, computed[i].octave, computed[i].class_id
};
kps[i] = k;
}

KeyPoints ret = {kps, (int)computed.size()};
return ret;
}

struct KeyPoints SIFT_DetectAndCompute(SIFT d, Mat src, Mat mask, Mat desc) {
std::vector<cv::KeyPoint> detected;
(*d)->detectAndCompute(*src, *mask, detected, *desc);
Expand Down
Loading

0 comments on commit ca77b8f

Please sign in to comment.