Ask Your Question
0

k mean clustering of hsv histogram of frames of a video

asked 2013-10-28 12:44:49 -0600

zulfiqar gravatar image

updated 2013-10-28 13:18:19 -0600

berak gravatar image

I have calculated the hsv histogram of frames of a video . now i want to cluster frames in using k mean clustering i have searched it and found the in build method

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

but I don't understand how to use it can anyone explain it. my code is shown below if anyone can tell what i have to pass as arguments

// Set up images
System::String ^ str = path->Text ;
char* str2 = (char*)Marshal::StringToHGlobalAnsi(str).ToPointer();
printf(str2);

String^ P = path->Text;
//const char* t = P.
IplImage* img = cvLoadImage(str2);
IplImage* back_img = cvCreateImage( cvGetSize( img ), IPL_DEPTH_8U, 1 );

// Compute HSV image and separate into colors
IplImage* hsv = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 3 );
cvCvtColor( img, hsv, CV_BGR2HSV );

IplImage* h_plane = cvCreateImage( cvGetSize( img ), 8, 1 );
IplImage* s_plane = cvCreateImage( cvGetSize( img ), 8, 1 );
IplImage* v_plane = cvCreateImage( cvGetSize( img ), 8, 1 );
IplImage* planes[] = { h_plane, s_plane };
cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 );

// Build and fill the histogram int h_bins = 30, s_bins = 32; CvHistogram* hist; { int hist_size[] = { h_bins, s_bins }; float h_ranges[] = { 0, 180 }; float s_ranges[] = { 0, 255 }; float* ranges[] = { h_ranges, s_ranges }; hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 ); } cvCalcHist( planes, hist, 0, 0 ); // Compute histogram //cvNormalizeHist( hist, 20*255 ); // Normalize it

//cvCalcBackProject( planes, back_img, hist );// Calculate back projection
//cvNormalizeHist( hist, 1.0 ); // Normalize it

// Create an image to visualize the histogram
int scale = 10;
IplImage* hist_img = cvCreateImage( cvSize( h_bins * scale, s_bins * scale ), 8, 3 );
cvZero ( hist_img );

// populate the visualization
float max_value = 0;
cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 );

for( int h = 0; h < h_bins; h++ ){
    for( int s = 0; s < s_bins; s++ ){
        float bin_val = cvQueryHistValue_2D( hist, h, s );
        int intensity = cvRound( bin_val * 255 / max_value );
        cvRectangle( hist_img, cvPoint( h*scale, s*scale ),
                    cvPoint( (h+1)*scale - 1, (s+1)*scale - 1 ),
                    CV_RGB( intensity, intensity, intensity ),
                    CV_FILLED );
    }
}

// Show original
cvNamedWindow( "Source", 1) ;
cvShowImage( "Source", img );

// Show back projection
//cvNamedWindow( "Back Projection", 1) ;
//cvShowImage( "Back Projection", back_img );

// Show histogram equalized
cvNamedWindow( "H-S Histogram", 1) ;
cvShowImage( "H-S Histogram", hist_img );

cvWaitKey(0);

cvReleaseImage( &img );
cvReleaseImage( &back_img );
cvReleaseImage( &hist_img );

     }
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
1

answered 2013-10-28 13:10:46 -0600

stereomatching gravatar image

updated 2013-10-28 13:49:37 -0600

The first question I would like to ask you is why do you still using outdated, deprecated, old-style c api?If there is no specific reason, then please use the c++ interface, which has a better support for the moment. The codes written by c++ api are much more easier to read and maintain, prefer c++ api should save you and your colleagues a lot of headaches.

About your problem, you need to map the original data to a group of data(samples), remap the labels and centers generated by kmeans algorithm back to the image.

cv::Mat src = cv::imread(Folder + "perspective05.jpg");
if(src.empty()){
    std::cerr<"can't read the image"<std::endl;
    return -1;
}

//step 1 : map the src to the samples
cv::Mat samples(src.total(), 3, CV_32F);
float *samples_ptr = samples.ptr<float>(0);
for( int row = 0; row != src.rows; ++row){
    uchar *src_begin = src.ptr<uchar>(row);
    uchar *src_end = src_begin + src.cols * src.channels();        
    while(src_begin != src_end){
        samples_ptr[0] = src_begin[0];
        samples_ptr[1] = src_begin[1];
        samples_ptr[2] = src_begin[2];
        samples_ptr += 3; src_begin +=3;
    }        
}

//step 2 : apply kmeans to find labels and centers
int clusterCount = 3;
cv::Mat labels;
int attempts = 5;
cv::Mat centers;
cv::kmeans(samples, clusterCount, labels,
           cv::TermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 
                            10, 0.01),
           attempts, cv::KMEANS_PP_CENTERS, centers);

//step 3 : map the centers to the output
cv::Mat new_image(src.size(), src.type());
for( int row = 0; row != src.rows; ++row){
    uchar *new_image_begin = new_image.ptr<uchar>(row);
    uchar *new_image_end = new_image_begin + new_image.cols * 3;
    int *labels_ptr = labels.ptr<int>(row * src.cols);

    while(new_image_begin != new_image_end){
        int const cluster_idx = *labels_ptr;
        float *centers_ptr = centers.ptr<float>(cluster_idx);
        new_image_begin[0] = centers_ptr[0];
        new_image_begin[1] = centers_ptr[1];
        new_image_begin[2] = centers_ptr[2];
        new_image_begin += 3; ++labels_ptr;
    }
}

This blog show you the whole process, explain the reasons and encapsulate those annoying details under the hood.

edit flag offensive delete link more

Comments

auto probably won't work with managed c++ (winforms, again)

nice blog ;)

berak gravatar imageberak ( 2013-10-28 13:15:31 -0600 )edit

@berak thanks. My bad, I haven't tried managed c++ before(never find a need for garbage collection since c++ support RAII + Qt do a good job on gui development).I change the auto back to explicit type.

stereomatching gravatar imagestereomatching ( 2013-10-28 13:45:15 -0600 )edit

how can i make sample of multiple images?

zulfiqar gravatar imagezulfiqar ( 2013-10-29 10:50:03 -0600 )edit

Hi the code im currently writing is doing something similar to this, should be done in 2 weeks in case you find it useful. Also i know it's messy ect.. will optimise it when i have everything working.. https://github.com/albertJ32/MR8-Filt...

albertJ gravatar imagealbertJ ( 2015-07-24 08:30:16 -0600 )edit

Question Tools

Stats

Asked: 2013-10-28 12:44:49 -0600

Seen: 4,739 times

Last updated: Oct 28 '13