簡體   English   中英

使用OpenCV cv :: kmeans()和一維輸入

[英]Using OpenCV cv::kmeans() with one-dimensional input

雖然python教程使用一維數據,但我不能對C ++接口做同樣的事情:

int size=100;
std::vector<float> data(size);
for (size_t i = 0; i < size ; i++)
{
    data[i] = (float)i; //placeholder
}
std::vector<int> labels;
std::vector<float> centers;
cv::kmeans(data, 3, labels,
    cv::TermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 10, 0.1),
    3, cv::KMEANS_PP_CENTERS, centers);

由於cv :: kmeans期望輸入是二維的,因此內部斷言失敗。 CV_Assert(N>=K)失敗,因為K是3而N是1.我的錯誤是什么?

麻煩的是當你將一個向量傳遞給一個接受InputArray的東西時,當在該InputArray上調用getMat()時,會創建一個帶有1行的Mat。 但是由於Xocoatzin在消息來源中指出的原因,在這種情況下這不會起作用。 你顯然無法重塑一個向量,盡管已經提出過。 如果您的輸入是矢量,並且您無法更改它,則需要將矢量顯式轉換為1列Mat,如下所示。

int size=100;
std::vector<float> data(size);
for (size_t i = 0; i < size ; i++)
{
    data[i] = (float)i; //placeholder
}

cv::Mat data_mat(data.size(), 1, CV32FC1, &data[0]);  // ** Make 1 column Mat from vector

std::vector<int> labels;
std::vector<float> centers;
cv::kmeans(data_mat, 3, labels,     // ** Pass 1 column Mat from Mat to kmeans
   cv::TermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 10, 0.1),
    3, cv::KMEANS_PP_CENTERS, centers);

編輯

我剛檢查了一下,它的內容如下:

//...
bool isrow = data.rows == 1 && data.channels() > 1; // MORE THAN ONE CHANNEL
int N = !isrow ? data.rows : data.cols; 
//...

//...
CV_Assert( N >= K );

因此,如果您將數據放在一行中,則需要在輸入矩陣中包含多個通道,並且列數多於K


快速解決方法:在調用kmeans之前重新整形矩陣

它不會復制任何數據,只是更改矩陣的尺寸。 所以如果你有:

[12345678] // mat 1 x 8

重塑2行后:

[1234| // a mat 2 x 4
|5678]

你應該能夠打電話給kmeans (不要忘記重塑)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM