Add pointer to matching keypoint to kp_t struct.

* This way we don't need to allocate the array of matching keypoints
and risk running out of memory due to fragmentation. So all or nothing.
This commit is contained in:
iabdalkader 2016-02-26 01:44:23 +02:00
parent 1b27383c9d
commit 074cf9d5e4
3 changed files with 38 additions and 19 deletions

View File

@ -321,21 +321,35 @@ array_t *freak_find_keypoints(image_t *image, bool normalized, int threshold, re
return keypoints;
}
int16_t *freak_match_keypoints(array_t *kpts1, array_t *kpts2, int threshold)
int freak_match_keypoints(array_t *kpts1, array_t *kpts2, int threshold)
{
int matches=0;
int kpts1_size = array_length(kpts1);
int kpts2_size = array_length(kpts2);
int16_t *kpts_match = xalloc(array_length(kpts1)*sizeof(*kpts_match));
// Reset the second set of keypoints.
// Note: The first set will be cleared when matching.
for (int x=0; x<kpts2_size; x++) {
((kp_t*)array_at(kpts2, x))->match = NULL;
}
// Match keypoints
for (int x=0; x<kpts1_size; x++) {
int min_idx = 0;
kp_t *min_kp=NULL;
int min_dist = MAX_KP_DIST;
kp_t *kp1 = array_at(kpts1, x);
for (int y=0; y<kpts2_size; y++) {
int dist = 0;
kp_t *kp2 = array_at(kpts2, y);
// If keypoint was matched skip it
if (kp2->match != NULL) {
continue;
}
// Check the first 128 bits of the descriptor
for (int m=0; m<4; m++) { //128 bits
uint32_t v = ((uint32_t*)(kp1->desc))[m] ^ ((uint32_t*)(kp2->desc))[m];
while (v) {
@ -359,19 +373,21 @@ int16_t *freak_match_keypoints(array_t *kpts1, array_t *kpts2, int threshold)
}
if (dist < min_dist) {
min_idx = y;
min_kp = kp2;
min_dist = dist;
}
}
if ((((MAX_KP_DIST-min_dist)*100/MAX_KP_DIST)) < threshold) {
//no match
kpts_match[x] = -1;
kp1->match = NULL;
// No match
} else {
kpts_match[x] = min_idx;
matches++;
kp1->match = min_kp;
min_kp->match = kp1;
}
}
return kpts_match;
return matches;
}
int freak_save_descriptor(array_t *kpts, const char *path)

View File

@ -245,9 +245,10 @@ typedef struct cluster {
} cluster_t;
/* FAST/FREAK Keypoint */
typedef struct {
typedef struct kp {
uint16_t x;
uint16_t y;
struct kp *match;
uint8_t desc[64];
} kp_t;
@ -392,7 +393,7 @@ array_t *imlib_detect_objects(struct image *image, struct cascade *cascade, stru
/* FAST/FREAK Feature Extractor */
void fast_detect(image_t *image, array_t *keypoints, int threshold, rectangle_t *roi);
array_t *freak_find_keypoints(image_t *image, bool normalized, int threshold, rectangle_t *roi);
int16_t *freak_match_keypoints(array_t *kpts1, array_t *kpts2, int threshold);
int freak_match_keypoints(array_t *kpts1, array_t *kpts2, int threshold);
int freak_save_descriptor(array_t *kpts, const char *path);
int freak_load_descriptor(array_t *kpts, const char *path);

View File

@ -1095,7 +1095,6 @@ static mp_obj_t py_image_find_eyes(mp_obj_t image_obj, mp_obj_t roi_obj)
static mp_obj_t py_image_match_keypoints(uint n_args, const mp_obj_t *args)
{
int16_t *kpts_match;
int threshold = mp_obj_get_int(args[3]);
py_kp_obj_t *kpts1 = ((py_kp_obj_t*)args[1]);
py_kp_obj_t *kpts2 = ((py_kp_obj_t*)args[2]);
@ -1109,15 +1108,18 @@ static mp_obj_t py_image_match_keypoints(uint n_args, const mp_obj_t *args)
return mp_const_none;
}
// match the keypoint sets
kpts_match = freak_match_keypoints(kpts1->kpts, kpts2->kpts, threshold);
// Match the two keypoint sets
int match=0, cx=0, cy=0;
for (int i=0; i<array_length(kpts1->kpts); i++) {
if (kpts_match[i] != -1) {
kp_t *kp = array_at(kpts2->kpts, kpts_match[i]);
cx += kp->x; cy += kp->y;
match++;
// Returns the number of matches
match = freak_match_keypoints(kpts1->kpts, kpts2->kpts, threshold);
if (match) {
for (int i=0; i<array_length(kpts1->kpts); i++) {
kp_t *kp = array_at(kpts1->kpts, i);
if (kp->match != NULL) {
cx += kp->match->x;
cy += kp->match->y;
}
}
}