Ask Your Question

Finding clusters of detected min area rectangles

asked 2018-04-15 10:07:50 -0500

Tars gravatar image

I have 60ish objects in an image that I detected minarerect's for and I'd like to find clusters of similarly angled rectangles within a certain distance threshold of each other. I looked into kmeans a little, and I'm still kind of confused about the approach, but I'm pretty sure that kmeans isn't what I want to use since it needs me to tell it how many clusters I want to find, which is something I don't know.

As you can tell I'm new to opencv. I would appreciate any advice I can get from you all.

edit retag flag offensive close merge delete


I once used std::partitionfor it. Check the first answer here: You also have to let your boolean operator test, if the rectangles are similarly angled. Edit: An image would be nice for testing.

Grillteller gravatar imageGrillteller ( 2018-04-16 04:06:43 -0500 )edit

What you could do is something like put the areas in a vector. Then add the first value to a class, if the next one is less than 10% deviating add it to the same class, if not, start a new vector. For now each element has to be checked with the previous classes, before considering making a new one. The percentage can be your threshold on the seperation of classes.

StevenPuttemans gravatar imageStevenPuttemans ( 2018-04-17 07:49:35 -0500 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2018-07-03 18:57:13 -0500

Tars gravatar image

Thank you very much!sorry I didn't get back you both but I'd forgotten I'd posted on here. Here is the answer I came up with. I for the life of me can't figure out why my formatting isn't working properly. So if anyone can help me out I'd appreciate it. The code works well, but I ended up making some case specific adjustments to make it more effective.

vector<vector<int>> RAPC(vector<rotatedrect> minRect, float radius) {

vector<vector<int>> clusters; // vector that will contain identify who belongs to which cluster vector<bool> touched(minRect.size(), false); // initializing vector that will identify whether or not a rectangle has been assigned to a cluster

// for every rect for (int i = 0; i < minRect.size()-1; i++) { // compare to every other rect for (int n = (i + 1); n < minRect.size(); n++) { // distance from rect i to rect n float distance = sqrt(pow((minRect[i].center.x - minRect[n].center.x), 2) + pow((minRect[i].center.y - minRect[n].center.y), 2));

    //criteria to determine whether the two rectangles belong in the same cluster
    if ( distance < radius)
        // if neither rectangle has been assigned to a cluster yet
        if (touched[i] == false && touched[n] == false) {

            // create new cluster in clusters with i and n as members
            clusters.emplace_back(initializer_list<int>{i, n});

            touched[i] = true; // make note of i being placed

            touched[n] = true; // make note of n being placed

        // if i has already been assigned to a cluster
        else if (touched[i] == true && touched[n] == false) {

            int loc = findLoc(i, clusters); // find i in clusters

            clusters[loc].emplace_back(n); // place n in that cluster

            touched[n] = true; // make note of n being placed

        // if n has already been assigned to a cluster
        else if (touched[n] == true && touched[i] == false) {

            int loc = findLoc(n, clusters); // find n in clusters

            clusters[loc].emplace_back(i); // place n in that cluster

            touched[i] = true; // make note of i being placed
        // if both rectangles have already been assigned
        else (touched[i] == true && touched[n] == true); {

            int locI = findLoc(i, clusters); // search for location of i
            int locN = findLoc(n, clusters); // search for location of n

            // if both rectangles are already part of the same cluster, ignore
            if (locI == locN) {

            // concatenate vector n with vector i
            clusters[locI].insert(clusters[locI].end(), clusters[locN].begin(), clusters[locN].end());

            // erase original location of vector n
            clusters[locN].erase(clusters[locN].begin(), clusters[locN].end()); 


} return clusters;

// function used by RAPC mainly just to make code more concise

int findLoc(int numSearchedFor, vector<vector<int>> clusters) { bool searchComplete = false; int ans; // initializing function output ie the cluster ID where the value is found for (int i = 0; i < clusters.size(); i++) { for (int n = 0; n < clusters[i].size(); n++) { if (clusters[i][n] == numSearchedFor) { ans = i; searchComplete = true; break; } } if (searchComplete == true) { break; } } return ans; }

edit flag offensive delete link more
Login/Signup to Answer

Question Tools

1 follower


Asked: 2018-04-15 10:07:50 -0500

Seen: 285 times

Last updated: Apr 15 '18