cvKMeans2() clustering function

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

cvKMeans2() clustering function

Ioana Diana
This post has NOT been accepted by the mailing list yet.
This post was updated on .
Hello.

I've been trying to cluster some images based on opencv's cvKMeans2() function.
My problem is when I use as features, in "points", the mean value for the pixel in red channel, the mean value for the pixel in green channel and the mean value for the pixel in blue channel (3x3 neighbourhood).

I computed these means in separate functions for each channel.
Below is the one for the the blue channel.

void doMeanBlue(Mat srcImg){
                        int i, j, p=0;
               
                        Vec3b colour;

                        for(i=0;i<N;i++){
                                for(j=0;j<M;j++){
                                        colour= srcImg.at<Vec3b>(cv::Point(i,j));
                                        blue[i][j] = colour.val[0];
                                }
                        }

                        for(i=1;i<N-1;i++){
                                for(j=1;j<M-1;j++){
                                        meanb[i][j]=(blue[i-1][j-1]+blue[i-1][j]+blue[i-1][j+1]+
                                                                 blue[i][j-1]+blue[i][j]+blue[i][j+1]+
                                                                 blue[i+1][j-1]+blue[i+1][j]+blue[i+1][j+1])/9;

                                        meanb1D[p]= meanb[i][j];
                                        p++;
                                }
                        }
}

And the function used for clustering is:

//K-means Clustering Algorithm
        int kmean(char* img, int NO_CLUSTERS)
        {
                        int i, j, k, size;
                        IplImage *src_img=0, *dst_img=0;

                        CvMat tmp_header;
                        CvMat *clusters, *points, *tmp;
                        CvMat *centers = cvCreateMat( NO_CLUSTERS, 3, CV_32FC1);

                        const char* imagename=img;

                        //set background color
                        int background_color[BACKGROND_COLOR_CHANNELS] = {0,0,0};
   
                        //set place u save image file.
                        char file_name[] = "C:/Users/User/Desktop/Images/Results/";
                        char file_extension[] = ".bmp";
   
                        // (1)load a specified file as a 3-channel color image
                        src_img = cvLoadImage(imagename, CV_LOAD_IMAGE_COLOR);
                        if(src_img == 0)
                                return -1;

                        M=src_img->height;
                        N=src_img->width;

                        red= new float*[N];
                        green= new float*[N];
                        blue= new float*[N];
                       
                        meanr1D = new float[M*N];
                        meang1D = new float[M*N];
                        meanb1D = new float[M*N];

                        meanr= new float*[N];
                        meang= new float*[N];
                        meanb= new float*[N];

                        for(i=0;i<M*N;i++){
                                meanr1D[i]=0;
                                meang1D[i]=0;
                                meanb1D[i]=0;
                        }

                        for(int i = 0;i<N;i++)
                        {
                                meanr[i] = new float[M];
                                meang[i] = new float[M];
                                meanb[i] = new float[M];
                        }

                        for(int i = 0;i<N;i++)
                                for(j=0;j<M;j++){
                                        meanr[i][j]=0;
                                        meang[i][j]=0;
                                        meanb[i][j]=0;
                                }

                        for(int i = 0;i<N;i++)
                        {
                                red[i] = new float[M];
                                green[i] = new float[M];
                                blue[i] = new float[M];
                        }
                       
                        size = src_img->width * src_img->height;

                        dst_img  = cvCloneImage(src_img);

                        clusters = cvCreateMat(size, 1, CV_32SC1 );
                        points   = cvCreateMat(size, 1, CV_32FC3 );

                        IplImage* srcImg = src_img;
                        Mat mat(src_img, true);

                        // (2)reshape the image to be a 1 column matrix
                        #if 0
                                tmp = cvCreateMat(size, 1, CV_8UC3); //2 or 3 column matrix
                                tmp = cvReshape(src_img, &tmp_header, 0, size);
                                cvConvert(tmp, points);
                                cvReleaseMat(&tmp);
                        #else
                                doMeanRed(mat);
                                doMeanGreen(mat);
                                doMeanBlue(mat);
                               
                                for(i=1; i<size-1; i++) {
                                        points->data.fl[i*3+0] = meanb1D[i];
                                        points->data.fl[i*3+1] = meang1D[i];
                                        points->data.fl[i*3+2] = meanr1D[i];
                               
                                }
                               
                        #endif
   
                        // (3)run k-means clustering algorithm to segment pixels in RGB color space
                        cvKMeans2( points, NO_CLUSTERS, clusters,
                                        cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 100, 5.0 ), 5, 0, 0, centers, 0);
   
                        // (4)make a each centroid represent all pixels in the cluster
                        //cluster which u selected outputs.
                        //cluster which u didn't select is painted black color.
                        for(j=0;j<NO_CLUSTERS;j++)
                        {
                                //generate saved file name.
                                sprintf(file,"%s%d%s",file_name,j,file_extension);
                                for(i=0; i<size; i++)
                                {
                                        int idx = clusters->data.i[i];
                                        if(j == idx)
                                        {
                                                dst_img->imageData[i*3+0] = srcImg->imageData[i*3+0];
                                                dst_img->imageData[i*3+1] = srcImg->imageData[i*3+1];
                                                dst_img->imageData[i*3+2] = srcImg->imageData[i*3+2];
                                        }

                                        else
                                        {
                                                dst_img->imageData[i*3+0] = BACKGROND_COLOR_BLUE;
                                                dst_img->imageData[i*3+1] = BACKGROND_COLOR_GREEN;
                                                dst_img->imageData[i*3+2] = BACKGROND_COLOR_RED;
                                        }
                                }
                                cvSaveImage(file,dst_img,0);
                        }
   
                        cvReleaseImage(&src_img);
                        cvReleaseImage(&dst_img);
                        cvReleaseMat(&clusters);
                        cvReleaseMat(&points);
                        //cvReleaseMat(&count);

                        return 0;
}

And the result if I want to have 3 clusters is:




Can someone help me, please? I can't figure out what is wrong.
And also, how many features cand I have in points? If i also want to compute the standard deviation for each channel and set it as feature in points, what should I do?
Loading...