sayvortana
sayvortana

Reputation: 825

How to use clustering with opencv c++ to classify the connected component based on the area and height

Hi, with opencv c++, I want to do clustering to classify the connected components based on the area and height. I do understand the concept of the clustering but i have hard time to implement it in opencv c++.

In the opencv

http://docs.opencv.org/modules/core/doc/clustering.html

There is a clustering methods kmeans

Most of the website I searched, they just explain the concept and parameters of the kmeans function in opencv c++ and most of them were copied from the opencv document website.

double kmeans(InputArray data, int K, InputOutputArray bestLabels, TermCriteria criteria, int attempts, int flags, OutputArray centers=noArray() )

There is also good example here but it was implemented in Python

http://docs.opencv.org/trunk/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html?highlight=kmeans

As i mentioned above, I have all the connected components and i can calculate areas and height of each connect components.

I want to use clustering to distinguish between connected components.

For instance, with k-means methods i would use k=2.

Thank..

Upvotes: 1

Views: 3912

Answers (2)

AnkitSahu
AnkitSahu

Reputation: 431

I am posting the snippet, Hope this will help you.... The Height and Area of component can be used as a feature for kmean. Now here for each feature kmean will give you centre. i.e. 1 center for Area and 1 center for height of component.

Mat labels;
int attempts = 11;
Mat centers;
int no_of_features = 2;//(i.e. height, area)
Mat samples(no_of_connected_components, no_of_features, CV_32F);
int no_of_sub_classes = 1; // vary for more sub classes

for (int j = 0; j < no_of_connected_components; j++)
{
    for (int x = 0; x < no_of_features; x++)
    {
        samples.at<float>(j, x) = connected_component_values[j,x];
        //fill the values(height, area) of connected component labelling
    }
}

cv::kmeans(samples, no_of_sub_classes, labels, TermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 10000, 0.001), attempts, KMEANS_PP_CENTERS, centers);

for (size_t si_i = 0; si_i < no_of_sub_classes ; si_i++)
{
    for (size_t si_j = 0; si_j < no_of_features; si_j++)
    {
        KmeanTable[si_i*no_of_sub_classes + si_i][si_j] = centers.at<float>(si_i, si_j);
    }

}

Here I am storing the center in kmeanTable 2D array you can use yours. Now for each connected component you can calculate the euclidean distance from centers. The lower difference features qualify for classification.

Upvotes: 2

wbest
wbest

Reputation: 611

Check this out.

Except instead of iterating over x,y, and z you'll iterate over component, and property (area, and height).

Upvotes: 0

Related Questions