Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8728979
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T08:44:56+00:00 2026-06-13T08:44:56+00:00

I am trying to use opencv EM algorithm to do color extraction.I am using

  • 0

I am trying to use opencv EM algorithm to do color extraction.I am using the following code based on example in opencv documentation:

cv::Mat capturedFrame ( height, width, CV_8UC3 );
int i, j;
int nsamples = 1000;
cv::Mat samples ( nsamples, 2, CV_32FC1 );
cv::Mat labels;
cv::Mat img = cv::Mat::zeros ( height, height, CV_8UC3 );
img = capturedFrame;
cv::Mat sample ( 1, 2, CV_32FC1 );
CvEM em_model;
CvEMParams params;
samples = samples.reshape ( 2, 0 );

    for ( i = 0; i < N; i++ )
    {           
        //from the training samples
        cv::Mat samples_part = samples.rowRange ( i*nsamples/N, (i+1)*nsamples/N);

        cv::Scalar mean (((i%N)+1)*img.rows/(N1+1),((i/N1)+1)*img.rows/(N1+1));
        cv::Scalar sigma (30,30);
        cv::randn(samples_part,mean,sigma);                     

    }       

    samples = samples.reshape ( 1, 0 );

    //initialize model parameters
    params.covs         = NULL;
    params.means        = NULL;
    params.weights      = NULL;
    params.probs        = NULL;
    params.nclusters    = N;
    params.cov_mat_type = CvEM::COV_MAT_SPHERICAL;
    params.start_step   = CvEM::START_AUTO_STEP;
    params.term_crit.max_iter = 300;
    params.term_crit.epsilon  = 0.1;
    params.term_crit.type   = CV_TERMCRIT_ITER|CV_TERMCRIT_EPS;     
    //cluster the data
    em_model.train ( samples, Mat(), params, &labels );     

    cv::Mat probs;
    probs = em_model.getProbs();

    cv::Mat weights;
    weights = em_model.getWeights();

cv::Mat modelIndex = cv::Mat::zeros ( img.rows, img.cols, CV_8UC3 );

for ( i = 0; i < img.rows; i ++ )
{
    for ( j = 0; j < img.cols; j ++ )
    {
        sample.at<float>(0) = (float)j;
    sample.at<float>(1) = (float)i;     

    int response = cvRound ( em_model.predict ( sample ) ); 
    modelIndex.data [ modelIndex.cols*i + j] = response;

    }
}

My question here is:

Firstly, I want to extract each model, here totally five, then store those corresponding pixel values in five different matrix. In this case, I could have five different colors seperately. Here I only obtained their indexes, is there any way to achieve their corresponding colors here? To make it easy, I can start from finding the dominant color based on these five GMMs.

Secondly, here my sample datapoints are “100”, and it takes about nearly 3 seconds for them. But I want to do all these things in no more than 30 milliseconds. I know OpenCV background extraction, which is using GMM, performs really fast, below 20ms, that means, there must be a way for me to do all these within 30 ms for all 600×800=480000 pixels. I found predict function is the most time consuming one.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T08:44:57+00:00Added an answer on June 13, 2026 at 8:44 am

    First Question:

    In order to do color extraction you first need to train the EM with your input pixels. After that you simply loop over all the input pixels again and use predict() to classify each of them. I’ve attached a small example that utilizes EM for foreground/background separation based on colors. It shows you how to extract the dominant color (mean) of each gaussian and how to access the original pixel color.

    #include <opencv2/opencv.hpp>
    
    int main(int argc, char** argv) {
    
        cv::Mat source = cv::imread("test.jpg");
    
        //ouput images
        cv::Mat meanImg(source.rows, source.cols, CV_32FC3);
        cv::Mat fgImg(source.rows, source.cols, CV_8UC3);
        cv::Mat bgImg(source.rows, source.cols, CV_8UC3);
    
        //convert the input image to float
        cv::Mat floatSource;
        source.convertTo(floatSource, CV_32F);
    
        //now convert the float image to column vector
        cv::Mat samples(source.rows * source.cols, 3, CV_32FC1);
        int idx = 0;
        for (int y = 0; y < source.rows; y++) {
            cv::Vec3f* row = floatSource.ptr<cv::Vec3f > (y);
            for (int x = 0; x < source.cols; x++) {
                samples.at<cv::Vec3f > (idx++, 0) = row[x];
            }
        }
    
        //we need just 2 clusters
        cv::EMParams params(2);
        cv::ExpectationMaximization em(samples, cv::Mat(), params);
    
        //the two dominating colors
        cv::Mat means = em.getMeans();
        //the weights of the two dominant colors
        cv::Mat weights = em.getWeights();
    
        //we define the foreground as the dominant color with the largest weight
        const int fgId = weights.at<float>(0) > weights.at<float>(1) ? 0 : 1;
    
        //now classify each of the source pixels
        idx = 0;
        for (int y = 0; y < source.rows; y++) {
            for (int x = 0; x < source.cols; x++) {
    
                //classify
                const int result = cvRound(em.predict(samples.row(idx++), NULL));
                //get the according mean (dominant color)
                const double* ps = means.ptr<double>(result, 0);
    
                //set the according mean value to the mean image
                float* pd = meanImg.ptr<float>(y, x);
                //float images need to be in [0..1] range
                pd[0] = ps[0] / 255.0;
                pd[1] = ps[1] / 255.0;
                pd[2] = ps[2] / 255.0;
    
                //set either foreground or background
                if (result == fgId) {
                    fgImg.at<cv::Point3_<uchar> >(y, x, 0) = source.at<cv::Point3_<uchar> >(y, x, 0);
                } else {
                    bgImg.at<cv::Point3_<uchar> >(y, x, 0) = source.at<cv::Point3_<uchar> >(y, x, 0);
                }
            }
        }
    
        cv::imshow("Means", meanImg);
        cv::imshow("Foreground", fgImg);
        cv::imshow("Background", bgImg);
        cv::waitKey(0);
    
        return 0;
    }
    

    I’ve tested the code with the following image and it performs quite good.

    enter image description here

    Second Question:

    I’ve noticed that the maximum number of clusters has a huge impact on the performance. So it’s better to set this to a very conservative value instead of leaving it empty or setting it to the number of samples like in your example. Furthermore the documentation mentions an iterative procedure to repeatedly optimize the model with less-constrained parameters. Maybe this gives you some speed-up. To read more please have a look at the docs inside the sample code that is provided for train() here.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Anyone know how to create a cvCreateStructuringElementEx using a image? I'm trying use opencv.cv.cvCreateStructuringElementEx()
I am trying to use two Gaussian mixtures with EM algorithm to estimate color
I am trying to use templates along with vector in my code the following
I'm trying to use OpenCV with Python and converting some C++ code. Anyway, if
I am trying to use the Qt new functions described here: http://opencv.willowgarage.com/documentation/cpp/qt_new_functions.html#cv-createbutton And I
I'm trying to get started working with sift feature extraction using (C++) OpenCv. I
I am trying to track a face using OpenCV 's CamShift algorithm but the
I'm trying to use OpenCV GpuMat but I'm getting an assert error, my code
I'm trying to use OpenCV to extract SURF descriptors from an image. I'm using
I am trying to use OpenCV and Python to stitch together several hundred puzzle

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.