HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Density-based clustering of image keypoints

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
imagedensitykeypointsbasedclustering

Problem

I have implemented the DBSCAN algorithm for clustering image keypoints. I have been following the pseudocode on the wiki page pretty strictly, and it's working, but I get the feeling its a very naive implementation and could be improved in terms of performance. I was hoping you could offer me some feedback on how to improve it.

/* DBSCAN - density-based spatial clustering of applications with noise */

vector> DBSCAN_keypoints(vector *keypoints, float eps, int minPts)
{
vector> clusters;
vector clustered;
vector noise;
vector visited;
vector neighborPts;
vector neighborPts_;
int c;

int noKeys = keypoints->size();

//init clustered and visited
for(int k = 0; k ()); //will stay empty?

//for each unvisted point P in dataset keypoints
for(int i = 0; i at(i),eps);
        if(neighborPts.size() ());
            c++;
            //expand cluster
            // add P to cluster c
            clusters[c].push_back(keypoints->at(i));
            //for each point P' in neighborPts
            for(int j = 0; j at(neighborPts[j]),eps);
                    if(neighborPts_.size() >= minPts)
                    {
                        neighborPts.insert(neighborPts.end(),neighborPts_.begin(),neighborPts_.end());
                    }
                }
                // if P' is not yet a member of any cluster
                // add P' to cluster c
                if(!clustered[neighborPts[j]])
                    clusters[c].push_back(keypoints->at(neighborPts[j]));
            }
        }

    }
}
return clusters;
}

vector regionQuery(vector *keypoints, KeyPoint *keypoint, float eps)
{
float dist;
vector retKeys;
for(int i = 0; isize(); i++)
{
    dist = sqrt(pow((keypoint->pt.x - keypoints->at(i).pt.x),2)+pow((keypoint->pt.y - keypoints->at(i).pt.y),2));
    if(dist <= eps && dist != 0.0f)
    {
        retKeys.push_back(i);
    }
}
return retKeys;
}

Solution

Just for correctness and not for performance reasons:

You nowhere mark any key as being clustered. As a result, keys may be clustered multiple times. In case all keys shall be clustered maximum one time, one may do the following modifications to the code above:

Add a following first line

clustered[i] = true;


behind

// add P to cluster c
clusters[c].push_back(keypoints->at(i));


and a following second line

clustered[neighborPts[j]] = true;


after

clusters[current_cluster].push_back(keypoints->at(neighborPts[j]));


Concerning the second line, make sure that it is inserted within the if-statement.

Code Snippets

clustered[i] = true;
// add P to cluster c
clusters[c].push_back(keypoints->at(i));
clustered[neighborPts[j]] = true;
clusters[current_cluster].push_back(keypoints->at(neighborPts[j]));

Context

StackExchange Code Review Q#23966, answer score: 9

Revisions (0)

No revisions yet.