Подтвердить что ты не робот

Каковы различия между CV_8U и CV_32F и что я должен беспокоиться при конвертации между ними?

У меня есть код, который действует, и я подозреваю, потому что я работаю с неправильными типами данных или плохо переключаюсь между ними.

Он смешивает объекты cv::Mat типов CV_8U (это то, что создается при чтении jpg в оттенках серого с помощью cv::imread), CV_32F и CV_32S.

Каковы различия между этими типами данных и что мне нужно знать при конвертации между ними?

4b9b3361

Ответ 1

CV_8U без знака 8 бит/пиксель - то есть пиксель может иметь значения 0-255, это нормальный диапазон для большинства форматов изображений и видео.

CV_32F - float - пиксель может иметь любое значение между 0-1.0, это полезно для некоторых наборов вычислений данных - но его нужно преобразовать в 8 бит для сохранения или отображения путем умножения каждого пикселя на 255.

CV_32S - это подписанное 32-битное целочисленное значение для каждого пикселя - снова полезно, что вы делаете целочисленные математические вычисления на пикселях, но снова необходимо преобразовать в 8 бит для сохранения или отображения. Это сложнее, так как вам нужно решить, как преобразовать гораздо больший диапазон возможных значений (+/- 2billion!) В 0-255

Ответ 2

В основном они просто описывают, что представляют собой отдельные компоненты:

  • CV_8U: 1-байтовое целое без знака (unsigned char).

  • CV_32S: 4-байтовое целое число со знаком (int).

  • CV_32F: 4-байтная с плавающей запятой (float).

Что вы всегда должны иметь в виду, так это то, что вы не можете просто отбрасывать их из одного в другой (или, вероятно, не будет делать то, что вы хотите), особенно между типами разных размеров.

Поэтому всегда убедитесь, что вы используете реальные функции преобразования для преобразования между ними, например cv::convert или cv::Mat::convertTo. Не просто пытайтесь получить доступ к элементам, например. a cv::Mat типа CV_8U с использованием, например, cv::Mat::at<float> или cv::Mat_<float>.

Или, если вы просто хотите преобразовать отдельные элементы и не хотите создавать новую матрицу другого типа, обратитесь к элементам с помощью соответствующей функции (в примере cv::Mat::at<unsigned char>) и преобразуйте результат в float.

Кроме того, существует также разница между количеством компонентов и типом cv::Mat типа CV_8UC3, отличным от образа типа CV_8UC1 и не должен (как правило,) недоступен cv::Mat::at<unsigned char>, а через cv::Mat::at<cv::Vec3b>.

РЕДАКТИРОВАТЬ: Увидев ответ Мартина, возможно, вы знаете об этом, и его объяснения - это то, что вы искали.