# Image segmentation using OpenCV’s Expectation Maximization Standard

Sorry for the shilling, but here’s my upcoming project:

https://plusplusone.herokuapp.com

Here’s sample implementation of OpenCV’s Expectation Maximization (EM) that I pilfered out of StackOverflow: http://stackoverflow.com/questions/12490256/opencv-color-extraction-based-on-gaussian-mixture-model

I’m no EM expert (well, I’m expert in nothing), but it seems that EM is an algorithm that basically tries to estimate hidden / unobserved parameters that maximize the likelihood parameters in order to describe the statistical models of a given data. So, I assume (I might be wrong, I’m probably wrong), if the dataset is governed by a number of independent gaussian distributions, then EM tries to find unobserved parameters that describe those gaussian models. Since I’ve already thoroughly confused you, I’d recommend you to google for better EM explanations.

Anyway, here’s the implementation code.

```
/**
* Create a sample vector out of RGB image
*/
Mat asSamplesVectors( Mat& img ) {
Mat float_img;
img.convertTo( float_img, CV_32F );

Mat samples( img.rows * img.cols, 3, CV_32FC1 );

/* Flatten  */
int index = 0;
for( int y = 0; y < img.rows; y++ ) {
Vec3f * row = float_img.ptr(y);
for( int x = 0; x < img.cols; x++ )
samples.at<Vec3f>(index++, 0) = row[x];
}
return samples;
}

/**
Perform segmentation (clustering) using EM algorithm
**/
vector EMSegmentation( Mat& image, int no_of_clusters = 2 ){
Mat samples = asSamplesVectors( image );

cout << "Starting EM training" << endl;
EM em( no_of_clusters );
em.train( samples );
cout << "Finished training EM" << endl;

vector<Mat> segmented;
for( int i = 0; i < no_of_clusters; i++ )
segmented.push_back( Mat::zeros( image.rows, image.cols, CV_8UC3 ) );

int index = 0;
for( int y = 0; y < image.rows; y++ ) {
for( int x = 0; x < image.cols; x++ ) {
int result = em.predict( samples.row(index++) );
segmented[result].at<Point3i>(y, x, 0) = image.at<Point3i>(y, x, 0);
}
}

return segmented;
}
```

Here’s the sample test data and the result of applying EM algorithm:  And here’s a sample result of applying k-means to it. Which looks quite similar to EM’s result, but if you were to observed carefully part of the head is not segmented correctly, due to the similarity between its color and the color of the background. Images used in this example is obtained from 3D photography dataset which is available here: http://www-cvr.ai.uiuc.edu/ponce_grp/data/mview/

## 3 thoughts on “Image segmentation using OpenCV’s Expectation Maximization”

1. sid

dude,how and where to execute this

• sub

Just run the EMSegmentation function on an OpenCV Mat image. Btw, wordpress removed some of the code due to formatting, e.g. is removed, just FYI.

2. michael scheinfeild

i think in opencv3 to make the sample vector you need to use :
samples = float_img.reshape(3, 1);