使用OpenCV对CSV时序数据执行k-means时遇访问冲突问题求助
解决OpenCV K-Means崩溃及Centers为空的问题
嘿,我仔细看了你的代码,马上就找到了导致kmeans崩溃、centers无法正常生成的核心问题——Mat的类型与元素访问方式不匹配,这直接引发了内存访问越界,让kmeans函数内部出错。
核心错误点
你创建Mat的时候指定了CV_32F(单精度浮点型,每个元素占4字节):
cv::Mat data_mat = cv::Mat::zeros((int)all_data.size(), (int)all_data[0].size(), CV_32F);
但赋值时却用了at<double>(双精度浮点型,每个元素占8字节)去读写:
data_mat.at<double>(rows, cols) = all_data[rows][cols];
这种类型不匹配会直接破坏Mat的内存结构,后续调用kmeans时自然会触发内存访问异常,连centers都没法正常初始化,所以你看到它的属性全是空的。
修复方案(二选一即可)
方案1:保持Mat为CV_32F,用float类型访问
把赋值时的at<double>改成at<float>,同时把double类型的数据转成float:
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<float>(rows, cols) = static_cast<float>(all_data[rows][cols]); } }
方案2:将Mat改为CV_64F,用double类型访问
如果想保留双精度的精度,直接把Mat的类型改成CV_64F,这样用at<double>就没问题了:
cv::Mat data_mat = cv::Mat::zeros((int)all_data.size(), (int)all_data[0].size(), CV_64F); 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]; } }
后续验证与优化建议
- 验证Mat正确性:修复后可以先打印Mat的类型,确认和你使用的访问类型匹配:
std::cout << "Mat type code: " << data_mat.type() << std::endl; // CV_32F对应5,CV_64F对应6 - 高效批量赋值:你的数据量很大(5万多行),嵌套循环赋值效率偏低,可以用
memcpy直接拷贝数据:
比如CV_64F的情况:cv::Mat data_mat(all_data.size(), all_data[0].size(), CV_64F); for (int i = 0; i < all_data.size(); ++i) { memcpy(data_mat.ptr<double>(i), all_data[i].data(), all_data[i].size() * sizeof(double)); } - 异常捕获:给kmeans加异常捕获,方便后续定位问题:
try { cv::kmeans(data_mat, k, labels, criteria, attempts, cv::KMEANS_PP_CENTERS, centers); std::cout << "Finished k-means" << std::endl; std::cout << "Centers rows: " << centers.rows << std::endl; std::cout << "Centers cols: " << centers.cols << std::endl; } catch (const cv::Exception& e) { std::cerr << "Kmeans error: " << e.what() << std::endl; }
按照上面的步骤修复后,kmeans应该能正常运行,centers也会生成你预期的256×256矩阵啦!
内容的提问来源于stack exchange,提问作者Timo Nörnberg
相关产品推荐
相关产品推荐

