Ask Your Question
2

get Center of nearby contours ??

asked 2015-06-06 10:21:28 -0600

sakaz gravatar image

updated 2016-01-12 09:08:20 -0600

I am working on a project using OPENCV for some image processing. I been learning from examples, tutorials but I am new on opencv so I have a question. I have attached pictures (1) is original input (2) output for better understanding all of you. I have used dbscan algorithm for segmentation. My purpose is to detect multiple objects in an image and draw rectangle around them and give center point of each rectangle to track or know the position.

But after some image processing filters , effects, Background subtraction, Findcontours ... i have found center of all contours. and pass to merged_contour_points vector. But it draw rectangle around all contours. I Hope you understand.

Here are my codes;

#include "stdafx.h"
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
#include <map>
#include <sstream>


template <class T>
inline std::string to_string (const T& t)
{
    std::stringstream ss;
    ss << t;
    return ss.str();
}

class DbScan
{
public:
    std::map<int, int> labels;
    vector<Rect>& data;
    int C;
    double eps;
    int mnpts;
    double* dp;
    //memoization table in case of complex dist functions
#define DP(i,j) dp[(data.size()*i)+j]
    DbScan(vector<Rect>& _data,double _eps,int _mnpts):data(_data)
    {
        C=-1;
        for(int i=0;i<data.size();i++)
        {
            labels[i]=-99;
        }
        eps=_eps;
        mnpts=_mnpts;
    }
    void run()
    {
        dp = new double[data.size()*data.size()];
        for(int i=0;i<data.size();i++)
        {
            for(int j=0;j<data.size();j++)
            {
                if(i==j)
                    DP(i,j)=0;
                else
                    DP(i,j)=-1;
            }
        }
        for(int i=0;i<data.size();i++)
        {
            if(!isVisited(i))
            {
                vector<int> neighbours = regionQuery(i);
                if(neighbours.size()<mnpts)
                {
                    labels[i]=-1;//noise
                }else
                {
                    C++;
                    expandCluster(i,neighbours);
                }
            }
        }
        delete [] dp;
    }
    void expandCluster(int p,vector<int> neighbours)
    {
        labels[p]=C;
        for(int i=0;i<neighbours.size();i++)
        {
            if(!isVisited(neighbours[i]))
            {
                labels[neighbours[i]]=C;
                vector<int> neighbours_p = regionQuery(neighbours[i]);
                if (neighbours_p.size() >= mnpts)
                {
                    expandCluster(neighbours[i],neighbours_p);
                }
            }
        }
    }

    bool isVisited(int i)
    {
        return labels[i]!=-99;
    }

    vector<int> regionQuery(int p)
    {
        vector<int> res;
        for(int i=0;i<data.size();i++)
        {
            if(distanceFunc(p,i)<=eps)
            {
                res.push_back(i);
            }
        }
        return res;
    }

    double dist2d(Point2d a,Point2d b)
    {
        return sqrt(pow(a.x-b.x,2) + pow(a.y-b.y,2));
    }

    double distanceFunc(int ai,int bi)
    {
        if(DP(ai,bi)!=-1)
            return DP(ai,bi);
        Rect a = data[ai];
        Rect b = data[bi];
        /*
        Point2d cena= Point2d(a.x+a.width/2,
                              a.y+a.height/2);
        Point2d cenb = Point2d(b.x+b.width/2,
                              b.y+b.height/2);
        double dist = sqrt(pow(cena.x-cenb.x,2) + pow(cena.y-cenb.y,2));
        DP(ai,bi)=dist;
        DP(bi,ai)=dist;*/
        Point2d tla =Point2d(a.x,a.y);
        Point2d tra =Point2d(a.x+a.width,a.y);
        Point2d bla =Point2d(a.x,a.y+a.height);
        Point2d bra =Point2d(a.x+a.width,a.y+a.height);

        Point2d tlb =Point2d(b.x,b.y);
        Point2d trb =Point2d(b.x+b.width,b.y);
        Point2d ...
(more)
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
3

answered 2015-06-06 11:12:38 -0600

Eduardo gravatar image

updated 2015-06-06 13:21:47 -0600

The bounding rectangle is calculated from your merged_contour_points1 variable which contains all the clustered blobs (except label == -1), that's why you have a rectangle that surrounds all the contours.

Instead, if you store only blobs with the same label, you will have:

Img res

If you want to retrieve only the contours (without clustering), with this tutorial: Img res2

Note: There is a border contour in the original image and I remove it and I use the result of cv::boundingRect directly instead of displaying the bounding rectangle of the min area rectangle.

Finally, the link to the DBSCAN algorithm implementation if someone want to use it, and the link to the original author post.

edit flag offensive delete link more

Comments

Thanks for your reply. I do understand it but i have tried to store only the points with the same labels but should i need to erase the vector. would you please give me little code idea.

int buffer = 0;
        if (label != buffer) {
            buffer = label;

            cv::RotatedRect rotated_bounding_rect1 = minAreaRect(merged_contour_points1);
            Rect brect1 = rotated_bounding_rect1.boundingRect();
            rectangle(grouped, brect1, Scalar(255,255,0));

    merged_contour_points1.erase(merged_contour_points1.begin(), merged_contour_points1.end() max_points_length);           

            }

            for (int j = 0; j < contours[i].size(); j++) {

                merged_contour_points1.push_back(contours[i][j]);
}
sakaz gravatar imagesakaz ( 2015-06-06 11:39:04 -0600 )edit
2

Just create another variable to store the result, for example a vector of vector (std::vector<std::vector<cv::Point> >) or a map (std::map<int, std::vector<cv::Point> >) .

Eduardo gravatar imageEduardo ( 2015-06-06 13:25:48 -0600 )edit

Thanks alot for your kind help and suggestion. I have used std::vector<std::vector<cv::point> for sorting out labels. :)

sakaz gravatar imagesakaz ( 2015-06-06 16:57:43 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-06-06 10:21:28 -0600

Seen: 4,329 times

Last updated: Jun 06 '15