Ask Your Question
0

In k means clustering, how do I reconstruct just a part of the image?

asked 2016-11-01 09:30:19 -0600

Prototype gravatar image

updated 2016-11-02 11:35:49 -0600

I performed k means clustering. How do I access the largest cluster?

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include<iostream>
using namespace cv;

int main( int argc, char** argv )
{
Mat newbgr;
Mat src;
Mat image = imread( "/home/manohar/Downloads/images/R-3.PNG", 1 );
imshow( "Original", image );

 cvtColor(image, src, CV_BGR2Lab);
 Mat samples(src.rows * src.cols, 3, CV_32F);
for( int y = 0; y < src.rows; y++ )
for( int x = 0; x < src.cols; x++ )
  for( int z = 0; z < 3; z++)
    samples.at<float>(y + x*src.rows, z) = src.at<Vec3b>(y,x)[z];


  int clusterCount = 3;
 Mat labels;
 int attempts = 10;
Mat centers;
kmeans(samples, clusterCount, labels, TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 10000, 0.0001), attempts, KMEANS_PP_CENTERS, centers );




Mat new_image( src.size(), src.type() );
for( int y = 0; y < src.rows; y++ )
for( int x = 0; x < src.cols; x++ )
{
   int cluster_idx = labels.at<int>(y + x*src.rows,0);
  new_image.at<Vec3b>(y,x)[0] = centers.at<float>(cluster_idx, 0);
  new_image.at<Vec3b>(y,x)[1] = centers.at<float>(cluster_idx, 1);
  new_image.at<Vec3b>(y,x)[2] = centers.at<float>(cluster_idx, 2);
}


imshow( "K means", new_image );

waitKey( 0 );
 return 0;
}
edit retag flag offensive close merge delete

Comments

first problem is, that you won't know, which cluster_idx red is assigned to.

berak gravatar imageberak ( 2016-11-01 09:42:18 -0600 )edit

@berak, how do I assign red to the cluster idx and the white to another? Labes? If so please let me know how. I am new to opencv. So in the end, I basically need two images. one with the red circle where the white R occurs black and another with just the white R where everything else occurs black.

Prototype gravatar imagePrototype ( 2016-11-01 10:02:44 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
2

answered 2016-11-01 16:11:10 -0600

LBerger gravatar image

updated 2016-11-02 12:12:37 -0600

I hope it helps

#include <opencv2/opencv.hpp> 

using namespace std;
using namespace cv;


void main(void)
{
    Mat img=imread("14780105241945453.png",IMREAD_COLOR);
    cout << "Pixels "<<img.rows*img.cols<<"\n";
    Mat src,srcF;
    cvtColor(img, src, CV_BGR2Lab);
    src.convertTo(srcF, CV_32FC3);
    cout << "Pixels " << srcF.rows*srcF.cols << "\n";
    vector<Vec3f> plan;
    plan.assign((Vec3f*)srcF.datastart, (Vec3f*)srcF.dataend);
    cout << "Pixels " << plan.size() << "\n";
    int clusterCount = 3;
    Mat labels;
    Mat centers;
    kmeans(plan, clusterCount,labels,TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 1.0), 3, KMEANS_PP_CENTERS, centers);
    Mat mask;
    namedWindow("Original", WINDOW_NORMAL);
    imshow("Original", img);
int maxCluster=0,ind=-1;
for (int i = 0; i < clusterCount; i++)
{
    cv::Mat cloud = (labels == i) ;
    namedWindow(format("Cluster %d",i), WINDOW_NORMAL);
    Mat result = Mat::zeros(img.rows, img.cols, CV_8UC3);

    if (cloud.isContinuous())
        mask = cloud.reshape(0, img.rows);
    else
        cout << "error";
    int m=countNonZero(mask);
    if (m > maxCluster)
    {
        maxCluster = m;
        ind=i;
    }
    img.copyTo(result, mask);
    imshow(format("Cluster %d", i), result);
    imwrite(format("Cluster%d.png", i), result);

}
cout<<"Cluster max is "<<ind<<" with "<<maxCluster<<" pixels";
waitKey();
}

with your image results are cluster 0 image description

cluster 1 (black on black) :image description ( with this original image descriptionyou have image description but it becomes cluster 2....)

and cluster 2 image description

edit flag offensive delete link more

Comments

Thanks a lot. Its great!

Prototype gravatar imagePrototype ( 2016-11-02 11:34:46 -0600 )edit

@LBerger How do I achieve the same in python? Please help me out.

Prototype gravatar imagePrototype ( 2017-07-12 09:35:13 -0600 )edit

@LBerger , I was able to achieve Kmeans in python. How do I do the rest?

Prototype gravatar imagePrototype ( 2017-07-12 09:53:53 -0600 )edit

sorry I don't know python

LBerger gravatar imageLBerger ( 2017-07-12 16:15:51 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-11-01 09:30:19 -0600

Seen: 1,035 times

Last updated: Nov 02 '16