2016-04-18 4 views
0

Я пытаюсь запустить алгоритм kmeans на n-мерных данных.opencv multimimensional kmeans

У меня есть N точек и каждая точка имеют { x, y, z, ... , n } функции.

мой код выглядит следующим образом:

cv::Mat points(N, n, CV_32F); 

// fill the data points 

cv::Mat labels; cv::Mat centers; 

cv::kmeans(points, k, labels, cv::TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 1000, 0.001), 10, cv::KMEANS_PP_CENTERS, centers); 

проблема заключается в том, что алгоритм kmeans впадать в ошибки сегментации.

любая помощь ценится

обновления

Как Miki и Micka сказал выше код был правильным!

я допустил ошибку в «заполнить точки данных», так что я разлагает к объему памяти

+0

код кажется нормально. Пожалуйста, предоставьте [mcve] – Miki

ответ

1

код выглядит нормально. Вы должны выбрать данные как 1 размер за столбец.

Можете ли вы попытаться запустить этот пример?

// k-means 
int main(int argc, char* argv[]) 
{ 

    cv::Mat projectedPointsImage = cv::Mat(512, 512, CV_8UC3, cv::Scalar::all(255)); 

    int nReferenceCluster = 10; 
    int nSamplesPerCluster = 100; 

    int N = nReferenceCluster*nSamplesPerCluster; // number of samples 
    int n = 10; // dimensionality of data 

    // fill the data points 
    // create n artificial clusters and randomly seed 100 points around them 

    cv::Mat referenceCenters(nReferenceCluster, n, CV_32FC1); 

    //std::cout << referenceCenters << std::endl; 
    cv::randu(referenceCenters, cv::Scalar::all(0), cv::Scalar::all(512)); 
    //std::cout << "FILLED:" << "\n" << referenceCenters << std::endl; 

    cv::Mat points = cv::Mat::zeros(N, n, CV_32FC1); 
    cv::randu(points, cv::Scalar::all(-20), cv::Scalar::all(20)); // seed points around the center 

    for (int j = 0; j < nReferenceCluster; ++j) 
    { 
     cv::Scalar clusterColor = cv::Scalar(rand() % 255, rand() % 255, rand() % 255); 
     //cv::Mat & clusterCenter = referenceCenters.row(j); 
     for (int i = 0; i < nSamplesPerCluster; ++i) 
     { 
      // creating a sample randomly around the artificial cluster: 
      int index = j*nSamplesPerCluster + i; 
      //samplesRow += clusterCenter; 
      for (int k = 0; k < points.cols; ++k) 
      { 
       points.at<float>(index, k) += referenceCenters.at<float>(j, k); 
      } 

      // projecting the 10 dimensional clusters to 2 dimensions: 
      cv::circle(projectedPointsImage, cv::Point(points.at<float>(index, 0), points.at<float>(index, 1)), 2, clusterColor, -1); 

     } 
    } 


    cv::Mat labels; cv::Mat centers; 
    int k = 10; // searched clusters in k-means 

    cv::kmeans(points, k, labels, cv::TermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 1000, 0.001), 10, cv::KMEANS_PP_CENTERS, centers); 

    for (int j = 0; j < centers.rows; ++j) 
    { 
     std::cout << centers.row(j) << std::endl; 
     cv::circle(projectedPointsImage, cv::Point(centers.at<float>(j, 0), centers.at<float>(j, 1)), 30, cv::Scalar::all(0), 2); 
    } 

    cv::imshow("projected points", projectedPointsImage); 
    cv::imwrite("C:/StackOverflow/Output/KMeans.png", projectedPointsImage); 
    cv::waitKey(0); 
    return 0; 
} 

Я создаю 10-мерные данные вокруг центров искусственного кластера. Для отображения я проецировать их в 2D, получение этого результата:

enter image description here

+0

спасибо Микке за ответ. У меня есть эта ошибка компиляции в вашем коде. kmean.cpp: 43: 55: ошибка: недействительная инициализация неконстантной ссылки типа 'cv :: Mat &' из rvalue типа 'cv :: Mat' cv :: Mat & clusterCenter = referenceCenters.row (j) ; ^ kmean.cpp: 50: 46: error: недействительная инициализация неконстантной ссылки типа 'cv :: Mat &' из rvalue типа 'cv :: Mat' cv :: Mat & samplesRow = points.row (индекс); – thewoz

+0

попробуйте обновленный код, пожалуйста, – Micka

+0

он отлично работает !!!! – thewoz

Смежные вопросы