2012-07-07 36 views
2

想了解如何在最新的OpenCV 2.4.2中使用EM算法。 我曾經使用C版本,它工作得很好,但自從系統升級以來,似乎已經在OpenCV 2.4.2中刪除了C API。如何在OpenCV 2.4.2中使用CV :: EM類?

這是EM的一個簡單情況:假設我有一個被認爲是來自兩種球的半徑列表,並且我想估計這兩種類型的均值/方差。換句話說,這是一個一維問題。

我試圖用新的API編寫EM的C++版本,但還沒有得到它的工作。

int nsamples = radius_list.size(); 
int ncluster = 2;     //we assume a bimodal model 
Mat samples = Mat::zeros(nsamples, 1, CV_32FC1); 

// init data 
for (int i = 0; i < radius_list.size(); ++i) { 
    int value = radius_list[i]; 
    samples.at<float>(i, 0) = value; 
} 
EM em_model = EM(ncluster, EM::COV_MAT_SPHERICAL); 

if (!em_model.train(samples)) { 
    cerr << "error training the EM model" << endl; 
    exit(-1); 
} 

const Mat& means = em_model.get<Mat>("means"); 
int mean1 = means.at<float>(0, 0); 
int mean2 = means.at<float>(1, 0); 
cout << "mean1 = " << mean1 << ", mean2 = " << mean2 << endl; 

const vector<Mat>& covs = em_model.get<vector<Mat> >("covs"); 
int scale1 = covs[0].at<float>(0, 0); 
int scale2 = covs[1].at<float>(0, 0); 
cout << "scale1 = " << scale1 << ", scale2 = " << scale2 << endl; 

的問題是:雖然如果()並沒有抱怨,檢索到的均值和刻度值在我的機器上 是垃圾值,-2147483648。

請告知如何修改代碼以使其正常工作。我仍然在學習OpenCV中的各種C++ API。

謝謝大家!

+0

C API並未真正刪除。它現在居住在opencv_legacy – 2012-07-07 07:59:34

+0

欣賞安德烈!經過一段時間的測試/運行後,我將C API返回到代碼中,它似乎工作得很好!雖然我可以繼續使用C API,但我也很想轉向C++ API。上述代碼的任何建議? – galactica 2012-07-07 18:29:57

+0

我建議你獲取OpenCV源代碼並研究舊API的實現。它被實現爲新的'EM'類的包裝。希望您能在代碼中找到缺少的細節。 – 2012-07-07 19:07:03

回答

5

您在做隱式類型轉換,分散了編譯器。意思是,權重和協方差矩陣不是整數,但雙打(您可以通過打印Mat.depth()導致屏幕檢查),以便改變從所有行:

int mean1 = means.at<float>(0, 0); 

喜歡代碼:

double mean1 = means.at<double>(0, 0); 

Regards, Rafal