c++csvopencvk-meansn-dimensional

Performing OpenCV k-means on data from csv-file


I am trying to read a time-series from a csv-file.

Each row contains 256 (may vary in the future) elements I want to handle as a point in 256-dimensional space.

Then I want to perform k-means-clustering on it to find the most k significant time-series describing the data.

I am currently reading the csv-file, storing each row in a

std::vector<double> temprow

and then end up having a

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

I am then converting to a

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

by looping over the vectors using

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;

This leaves me with the cv::Mat with the following properities:

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

I then perform k-means clustering as follows:

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);

which in my understanding should fill centers with the values of the center of each cluster, leaving me with a k*n matrix (in this case 256*256).

However, when I call

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

I get this generic error message:

Exception thrown at 0x00007FF806C86020 (opencv_world341.dll) in Project1.exe: 0xC0000005: Access violation reading location 0x0000024B9ECAFC80.

The properties of centers at this point of the program are:

    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

So it seems centers is NULL. So maybe the input data_mat is in the wrong shape, so that kmeans() is not outputting anything into centers, but then again I am not getting any error message for the kmeans()

Thank you very much in advance for your efford and help,

Timo

Edit 1: The error is occuring inside kmeans(), because

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

the cout is not printed to console. However the the linenumber of the error was kmeans()+1, so I did just find that out by placing a generic cout there.


Solution

  • So I found the Answer:

    Beacause I am using Type CV32_F I had to access it as a float Mat.

    so changing data_mat.at<double>(rows, cols) = all_data[rows][cols]; to data_mat.at<float>(rows, cols) = all_data[rows][cols]; did the job for me.

    Originally I wanted to work with CV64_F, so I had double all over, but I found out, that OpenCV-k-means does only work up to CV32_F. Then I forgot to change that aswell, which lead to the first clustering step beeing performed, but after the second it crashed.