Sel*_*mar 5 c++ opencv gaussian image-segmentation expectation-maximization
背景: 我有一组来自图像的2组彩色像素,一组对应于背景,另一组对应于前景.接下来,我使用来自OpenCV的EM为每组训练2个高斯混合模型.我的目标是找到随机像素属于前景和背景的概率.因此,我对像素上的每个EM使用"预测"功能.
题:
该方法返回一个双元素双向量.零元素是样本的似然对数值.第一个元素是给定样品的最可能混合物组分的指数.
我不明白什么意思是"象征性对数".在我的结果中,我有时负值和值> 1.使用相同函数的人是否有这种结果或0到1之间的结果?我可以从结果中得出什么结论?
这是我的代码:
Mat mask = imread("mask.tif", 0);
Mat formerImage = imread("ImageFormer.tif");
Mat currentImage = imread("ImageCurrent.tif");
// number of cluster in the GMM
int nClusters = 5;
int countB=0, countF=0;
Vec3b color;
Vec2d probFg, probBg; // probabilities to belong to the foreground or background from GMMs
//count the number of pixels for each training data
for(int c=0; c<=40;c++) {
for(int l=0; l<=40;l++) {
if(mask.at<BYTE>(l, c)==255) {
countF++;
} else if(mask.at<BYTE>(l, c)==0) {
countB++;
}
}
}
printf("countB %d countF %d \n", countB, countF);
Mat samplesForeground = Mat(countF,3, CV_64F);
Mat samplesBackground = Mat(countB,3, CV_64F);
// Expectation-Maximisation able to resolve the GMM and to predict the probability for a pixel to belong to the GMM.
EM em_foreground= EM(nClusters);
EM em_background= EM(nClusters);
countB=0;
countF=0;
// fill the training data from the former image depending of the mask
for(int c=0; c<=40;c++) {
for(int l=0; l<=40;l++) {
if(mask.at<BYTE>(l, c)==255) {
color = formerImage.at<Vec3b>(l, c);
samplesForeground.at<double>(countF,0)=color[0];
samplesForeground.at<double>(countF,1)=color[1];
samplesForeground.at<double>(countF,2)=color[2];
countF++;
} else if(mask.at<BYTE>(l, c)==0) {
color = formerImage.at<Vec3b>(l, c);
samplesBackground.at<double>(countB, 0)=color[0];
samplesBackground.at<double>(countB, 1)=color[1];
samplesBackground.at<double>(countB, 2)=color[2];
countB++;
}
}
}
printf("countB %d countF %d \n", countB, countF);
em_foreground.train(samplesForeground);
em_background.train(samplesBackground);
Mat sample(1, 3, CV_64F);
// try every pixel of the current image and get the log likelihood
for(int c=0; c<=40;c++) {
for(int l=0; l<=40;l++) {
color = currentImage.at<Vec3b>(l,c);
sample.at<double>(0)=color[0];
sample.at<double>(1)=color[1];
sample.at<double>(2)=color[2];
probFg=em_foreground.predict(sample);
probBg=em_background.predict(sample);
if(probFg[0]>0 || probBg[0]>0)
printf("probFg[0] %f probBg[0] %f \n", probFg[0], probBg[0]);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
在@BrianL解释之后,我现在理解了对数可能性.
我的问题是预测函数的对数概率有时> 0.但它应该<= 0.以前有人遇到过这个问题吗?
我编辑了上面的代码来显示问题.我尝试过以下图片的程序:
第一个图像是ImageCurrent.tif,第二个是ImageFormer.tif,最后一个是mask.tif.

这可以被视为OpenCV中的一个错误吗?我应该在OpenCV bug跟踪器上打开票吗?
据我了解,图像的前景和背景部分有两个单独的 GMM。在前景 GMM 中评估时,测试图像中样本像素“x”的总概率为
P_fg(x) = sum_over_j_1_to_k ( Wj_fg * Pj_fg( x ))
where
k = number of clusters in foreground GMM
x = test sample
Pj_fg(x) = probability that sample x is in j-th cluster according to the foreground GMM
Wj_fg = weight of the j-th cluster in foreground GMM
also, sum of all weights should be 1 for each GMM.
Run Code Online (Sandbox Code Playgroud)
我们可以对背景 GMM 进行类似的计算。
从 opencv 中的 EM 代码来看,EM 返回的 2 个值的第一部分似乎是对数似然。对于前台 GMM 来说是
log(P_fg(x_i))
Run Code Online (Sandbox Code Playgroud)
我实现了您的算法,并且对于测试图像中的每个像素,我比较了两个 GMM 返回的对数似然,并将像素分类为具有较高值的 GMM。我得到了不错的结果。
在这方面,是的,这个值表明像素属于整个 GMM。
2)在我解决你的问题时,我总是得到所有测试样本像素的所有 GMMS 的对数似然值都低于 0。
| 归档时间: |
|
| 查看次数: |
5387 次 |
| 最近记录: |