OpenCV: утверждение не выполнено " dst.data == widget->original_image->data.ptr в функции 'cvImageWidgetSetImage' "

ВАЖНО: я исправил проблему. Решение в конце.

Чего я пытаюсь достичь? Отобразить изображение с помощью метода OpenCV cv:: imshow. ( imshow Документация)

Изображение, представляющее собой матрицу 3х3, создается примерно так:

Mat mask(3, 3, CV_32F, new float[9]{0, 1, 0, 1, -4, 1, 0, 1, 0});

Для отображения изображения я звоню imshow("mask", mask);

В чем моя проблема? Как я уже упоминал в заголовке, при попытке отобразить изображение возникает исключение. Полное сообщение об ошибке:

terminate called after throwing an instance of 'cv::Exception' what():  
OpenCV(4.0.0-pre) /home/mrlab/Libraries/opencv_source/modules/highgui
/src/window_gtk.cpp:146: error: (-215:Assertion failed) 
dst.data == widget->original_image->data.ptr in function 'cvImageWidgetSetImage'

Ссылка на window_gtk.cpp

Что я уже пробовал?

  1. Ищем ошибку в интернете. Может быть, кто-то еще уже столкнулся с той же проблемой. Нету. ничего такого
  2. Изменена матрица, чтобы она содержала только положительные значения с плавающей запятой (от 0 до 1), если у нее есть проблемы с отрицательным вводом Инициализация: Mat mask(3, 3, CV_32F, new float[9]{0, 1, 0, 1, 0, 1, 0, 1, 0}); та же ошибка
  3. Вызов двух методов в разных местах на случай, если во время моего другого кода будут внесены изменения. та же ошибка
  4. Написание небольшой OpenCV-программы для запуска этих двух строк. та же ошибка
  5. Различные комбинации вышеупомянутых идей. та же ошибка
  6. Отображая другие изображения, которые я читаю по памяти, вместо того, чтобы создавать их самому. работал отлично
  7. Сохранение изображения через imwrite("mask.png", mask) Похоже на это. Довольно маленький, я знаю. Я масштабировал значения в диапазоне от 0 до 255, так как это то, что нужно PNG. отлично работает

Полный код вокруг моих поврежденных строк:

void high_pass(){

  Mat src_f;
  // Fourier transform src_bw
  src_f = fourier(src_bw);

  // Create Laplace High Pass Kernel
  Mat mask(3, 3, CV_32F, new float[9]{0, 1, 0, 1, -4, 1, 0, 1, 0});
  // In case of using fp values (0 to 1) initialize like this:
  // Mat mask(3, 3, CV_32F, new float[9]{0, 1, 0, 1, 0, 1, 0, 1, 0});
  imshow("mask", mask);

  // Fourier transform kernel
  Mat mask_f = fourier_kernel(mask, src_f.size());

  Mat hp_filtered;
  // Apply filter
  mulSpectrums(src_f, mask_f, hp_filtered, DFT_ROWS);

  // Transform it back
  dst = fourier_inv(hp_filtered);

  // Swap quadrants after applying filter
  dst = swap_quadrants(dst);

  // Show result
  //imshow(WINDOW_NAME + "high pass", dst);
}

К вашему сведению: последняя строка вызвала то же исключение, поэтому оно закомментировано. Я задаю вопрос с "маской", потому что это проще.

После написания вопроса у меня появилась другая идея.

Решение: я преобразовал CV_32F тип матрицы для CV_8U матрица и масштабировать все значения в диапазоне от 0 до 255. Это решило проблему.

Это то, о чем я должен был подумать первым. По какой-то причине мне потребовался один час, чтобы понять. На всякий случай, если кто-то еще сталкивается с той же ошибкой или умственным блокированием, я все еще публикую это здесь.

1 ответ

Решение

Решение: Я преобразовал матрицу типа CV_32F в матрицу CV_8U и масштабировал все значения в диапазоне от 0 до 255. Это решило проблему.

Редактировать: Как заявил Николай Фог, также можно вернуться к OpenCV версии 3.4.3. Я не проверял это сам.

Для полноты, вот как реализовать решение Филиппа (используя переменные его программы):

cv::Mat dist_8U; // to store the scaled image with appropriate type
double Min,Max;
cv::minMaxLoc(rgb,&Min,&Max);
dist -= Min;
dist.convertTo(dist_8U,CV_8U,255.0/(Max-Min));

затем dist_8U может быть показано с imshow в opencv 4.0.0. Проверено на малиновом пи.

Другие вопросы по тегам