[英]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.