Создание кластерного изображения из данных kmeans в OpenCV - PullRequest
3 голосов
/ 11 августа 2011

Я пытаюсь создать кластерное изображение из данных, возвращаемых функцией kmeans. Я пытаюсь извлечь данные аналогичным образом из примера OpenCV, но это, похоже, дает сбой. После некоторых дальнейших исследований я увидел, что кто-то извлек данные с помощью центров, но ничего не сделал с этими данными, поэтому мой след на этом закончился.

Я включил фрагмент своего кода и то, что я делаю ниже. Любая помощь будет принята с благодарностью.

EDIT Я вернул свой код обратно в исходное состояние без каких-либо тестовых переменных. Тем не менее вышеуказанная ошибка сохраняется. Я также добавил отладочную информацию о моем изображении ниже:

Информация об изображении:

  • Размеры: 2
  • Данные изображения:
  • Размер 0: 256
  • Размер 1: 256
  • Размер 1: 12
  • Elemsize 2: 4

Пока данные равны NULL, я все еще могу просматривать данные, если позвоню на них cv::imshow.

// mImage is a cv::Mat that was created from a 256 x 256 image with the depth of
// CV_32F and 3 channels
// labels is a cv::Mat that was created by converting the image into a 256 x 256
// CV_8UC1 IplImage
kmeans(mImage, 6, labels, termcrit, 3, cv::KMEANS_PP_CENTERS, centers);
float* c = new float[6];
memcpy(c, centers.ptr<float>(0), sizeof(float)*6);

// Block of code that crashes when I do "mImage.at<cv::Point2f>(i)" with the error:
/* OpenCV Error: Assertion failed (dims <= 2 && data && (size.p[0] == 1 || 
       size.p[1] == 1) && (unsigned)i0 < (unsigned)(size.p[0] + size.p[1] - 1) && 
       elemSize() == (((((DataType<_Tp>::type) & ((512 - 1) << 3)) >> 3) + 1) << 
       ((((sizeof(size_t)/ 4+1)*16384|0x3a50) >> ((DataType<_Tp>::type) & 
       ((1 << 3) - 1))*2) & 3))) in unknown function, file 
       c:\opencv-2.3.0\modules\core\include\opencv2\core\mat.hpp, line 583 */

for(int i = 0; i < list.rows; i++)
{
    int clusterIdx = list.at<int>(i);
    cv::Point ipt = mImage.at<cv::Point2f>(i);
    circle( miplImage, ipt, 2, colorTab[clusterIdx], CV_FILLED, CV_AA );
}

1 Ответ

1 голос
/ 11 августа 2011

Вы получаете сообщение об ошибке при вызове mRegion.at ().Где определен mRegion?

Вот эквивалентный фрагмент из kmeans.cpp примера кода:

    kmeans(points, clusterCount, labels, 
           TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0),
           3, KMEANS_PP_CENTERS, centers);

    img = Scalar::all(0);

    for( i = 0; i < sampleCount; i++ )
    {
        int clusterIdx = labels.at<int>(i);
        Point ipt = points.at<Point2f>(i);
        circle( img, ipt, 2, colorTab[clusterIdx], CV_FILLED, CV_AA );
    }

Используется одна и та же переменная points для первого аргумента kmeans ив качестве источника для ipt в цикле for.Я думаю, что вы, вероятно, хотите использовать mImage в цикле for, а не mRegion.

Edit Итак, теперь вы изменили код для использования mImage в forцикл, вам нужно понять, почему вы получаете ошибку утверждения.Сообщение с утверждением очень загромождено кодом шаблона, поэтому оно взято из mat.hpp:

dims <= 2 && data && (size.p[0] == 1 || size.p[1] == 1) &&
             (unsigned)i0 < (unsigned)(size.p[0] + size.p[1] - 1) &&
             elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type)

Один или несколько из этих тестов не пройдены.Если вы используете пустой mImage, это будет неудачей, потому что data будет ноль.Вы не можете позвонить at на пустую матрицу.В любом случае, проверьте свойства mImage, чтобы определить причину ошибки подтверждения.

...