Introduction
In the previous page, I described the brief explanation on the theory of the EM Algorithm. In this page, I will use the implementation of the EM Algorithm the OpenCV provides to us to achieve a simple image segmentation. I will also relate the quantities the OpenCV computes to the expressions shown in the explanation.Expressions in Previous Page
To refer to some expressions used for the interpretation on the EM Algorithm, I describe them again.The likelihood function to maximize is defined as
where, is the normalized Gaussian, is the observed point, is the mean vector, and is the covariance matrix. indicates the weight of each Gaussian. Moreover, the following expressions also appeared during the process of the explanation.
Code
function main:As I consider the RGB color space, an observed point corresponds to a pixel on an image, i.e., . is the total number of the pixels.
- the 3th-6th lines : Read an input image (
image
). Confirm the type of the image, and define variblesimage_rows
andimage_cols
. - the 10th-13th lines : Reshape
image
to makereshaped_image
. Confirm its type and its number of rows and columns. - the 16th-20th lines : Convert the type of
reshaped_image
to makesamples
. Confirm its type and its number of rows and columns. Thesamples
is one of some inputs passed to the EM Algorithm. - the 22th-23th lines : Create an instance of the EM Algorithm (
cv::EM
). Arguments passed to the constructor of thecv::EM
are as follows:- the first argument : the number of the Gaussians
- the second argument : the type of the covariance matrix
- the third argument : the condition to quit the algorithm
EM::COV_MAT_DIAGONAL
and it means a diagonal matrix with positive diagonal elements. The number of free parameters is D for each matrix, where D is the space dimension. In this sample code, D equals to 3. - the 26th-28th lines : Prepare a matrix for an output.
- 31th line: Execute the EM Algorithm. The function
train
internally uses the K-means clustering to create initial parameters. - the 33th-35th lines : Confirm the type, the rows, and the columns of the output
log_likelihoods
. In each row the following quantity is stored
. - the 37th-39th lines : Confirm the type, the rows, and the columns of the output
labels
. Thelabels
has the following quantities:
(I modified the following statements. 2013/3/21)
where,
.
is the probability of the observed point.
.
- the 41th-44th lines : Confirm the type, the rows, and the columns of the output
probs
. Theprobs
has the quantities . I will discuss the functionobserve_probs
later. - the 46th-50th lines : Confirm the type, the rows, and the columns of the output
means
which has . As we consider the RGB space, the quantity is the 3D vector. I will discuss the functionobserve_labels_and_means
later. - the 52th-56th lines : Confirm the type, the rows, and the columns of the output
weights
. In the output, is stored. I will discuss the functionobserve_weights
later.
observe_probs
:
- the 13th line : Confirm the following equation:
- the 16th line : Confirm the following equation:
observe_weights
:
- the 10th line : Confirm the following equation:
observe_labels_and_means
:This function replaces a label k assigned to a certain pixel by a corresponding mean vector .
- the 4th line : Create a matrix in which a final result (
rgb_image
) is stored. - the 9th-11th lines :
means
is acluster_number
x 3 matrix, where 3 means the space dimension. In each row, the center coordinate (mean vector) of the Gaussian is stored. Apply the type conversion from double to unsigned char to the elements ofmeans
. Also, the number of the channels is converted to 3. - the 13th-18th lines : Replace the label by the corresponding (R,G,B) to make the final image
rgb_image
.
Results
cluster_num=2
cluster_num=3
cluster_num=5
cluster_num=10
original image
Development Environment
- Mac OS X 10.8.2
- Processor:3.06 GHz Intel Core 2 Duo
- Memory:4GB
- Xcode4.6 with Apple LLVM 4.2(C++ Language Dialect → GNU++11, C++ Standard Library → libc++)
- boost-1.51.0 built by the Apple LLVM 4.1. See here
- opencv-2.4.3 built by the Apple LLVM 4.2. See here.
Reference
- Pattern Recognition and Machine Learning, Christopher M. Bishop, Springer
- OpenCV Document
Hi Seiya Kumada, thank you for your post. However, I have a strange problem with Expectation-Maximization. When I run your first code on Linux, it executes fine in 3 seconds. However, when I try the same code on Windows, it takes near 20 minutes to converge. Do you know what might be the problem?
返信削除Hi Victor Hugo.
削除Thank you for your comment.
After receiving it, I timed the calculations with cluster_numer = 10 on both Windows7 and Mac OSX. The results are as follows:
Mac OSX : about 280[sec]
Windows7: about 290[sec]
My Windows machine has 4.0 GB RAM and Intel Core1.7GHz (core number 2).
So, I don't know what happened in your machine...
Hi Seiya,
削除I think I found my problem. I'm using a framework linked with several libraries. One of them is QT, which brought me problems before to manage screens. I think it might be causing problems to me again.
Thanks for your goodwill!
Hi Victor.
削除It's reassuring to know that.
I used Visual Studio 2010 to carry out the code on Windows7.
Since the compiler does not fully support C++11,
I modified the code a little.
Have a good time!
hi Seiya thank you very much for your post
返信削除You are welcome.
削除please don't lie to people. how can you say it's fully working with Mat rgb_image which doesn't exist of any further process?
返信削除Thank you very much for your clair explanation and your well written code. It was very helpful to me. The code works very good, i tried it in my computer for color/grayscale images
返信削除It's my pleasure.
削除Hi, thank you very much for the code and the explanation. It was exactly what I was looking for. Cheers!
返信削除I am happy to be of help.
削除Hi Seiya, thank you for your post.
返信削除Can I ask you a question?
I tried to copy and paste your code to my mac, (Macbook pro 13', 2015, El capitan)
and tried to run it with XCode, there is an error message with
cv::EM model {cluster_num};
(23rd line in your code)
Also, I found that this error makes some more errors.
How can I fix this problem?
Thanks. -From G.
OpenCV modified the structure of the class EM after I wrote this post. Please see the current API reference for more detail.
返信削除Thank you very much!
返信削除