2

我正在尝试从 csv 文件中读取时间序列。

每行包含 256 个(将来可能会有所不同)元素,我想将其作为 256 维空间中的一个点来处理。

然后我想对其执行 k-means-clustering 以找到描述数据的最重要的 k 个时间序列。

我目前正在阅读 csv 文件,将每一行存储在

std::vector<double> temprow

然后最终有一个

std::vector<std::vector<double>> data_vect

然后我正在转换为

cv::Mat data_mat = cv::Mat::zeros((int)all_data.size(), (int)all_data[0].size(), CV_32F)

通过使用循环遍历向量

for (int rows = 0; rows < (int)all_data.size(); rows++) {
    for (int cols = 0; cols < (int)all_data[0].size(); cols++) {
        data_mat.at<double>(rows, cols) = all_data[rows][cols];
    }
}
return data_mat;

这给我留下了具有以下属性的 cv::Mat:

std::cout << "Rows: " << data.rows << std::endl;    //Rows: 52178
std::cout << "Cols: " << data.cols << std::endl;    //Cols: 256
std::cout << "Dims: " << data.dims << std::endl;    //Dims: 2

然后我按如下方式执行 k-means 聚类:

cv::Mat labels,centers;
int k = 256;
int attempts = 10;
cv::TermCriteria criteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 10, 1.0);
cv::kmeans(data_mat, k, labels, criteria, attempts, cv::KMEANS_PP_CENTERS, centers);

在我的理解中,应该用每个集群的中心值填充中心,给我留下 ak*n 矩阵(在本例中为 256*256)。

但是,当我打电话时

std::cout << "Rows: " << centers.rows << std::endl; //Hopefully 256
std::cout << "Cols: " << centers.cols << std::endl; //Hopefully 256

我收到此通用错误消息:

在 Project1.exe 中的 0x00007FF806C86020 (opencv_world341.dll) 处引发异常:0xC0000005:访问冲突读取位置 0x0000024B9ECAFC80。

程序此时的中心属性是:

    flags   1124007936  int
    dims    0   int
    rows    0   int
    cols    0   int
+       data    0x0000000000000000 <NULL>   unsigned char *
+       datastart   0x0000000000000000 <NULL>   const unsigned char *
+       dataend 0x0000000000000000 <NULL>   const unsigned char *
+       datalimit   0x0000000000000000 <NULL>   const unsigned char *
+       allocator   0x0000000000000000 <NULL>   cv::MatAllocator *
+       u   0x0000000000000000 <NULL>   cv::UMatData *
+       size    {p=0x000000bdfc93f9e8 {0} } cv::MatSize
+       step    {p=0x000000bdfc93fa30 {0} buf=0x000000bdfc93fa30 {0, 0} }   cv::MatStep

所以看起来中心是NULL。因此,可能输入data_mat的形状错误,因此kmeans()没有将任何内容输出到中心,但是我再次没有收到kmeans()的任何错误消息

非常感谢您的努力和帮助,

蒂莫

编辑1:错误发生在kmeans()内部,因为

cv::kmeans(data_mat, k, labels, criteria, attempts, cv::KMEANS_PP_CENTERS, centers);
std::cout << "Finished k-means" << std::endl;

cout 没有打印到控制台。然而,错误的行号是 kmeans()+1,所以我只是通过在那里放置一个通用 cout 才发现这一点。

4

1 回答 1

0

所以我找到了答案:

因为我使用的是CV32_F 类型,所以我必须将其作为浮动垫访问。

所以改变data_mat.at<double>(rows, cols) = all_data[rows][cols];data_mat.at<float>(rows, cols) = all_data[rows][cols];我完成了这项工作。

最初我想使用 CV64_F,所以我有双倍的结果,但我发现 OpenCV-k-means 只适用于 CV32_F。然后我也忘了更改它,这导致执行第一个聚类步骤,但在第二个之后它崩溃了。

于 2018-05-15T12:15:23.420 回答