Измените тип объекта Mat с CV_32F на CV_8U

Я попытался отобразить изображение типа CV_32F с помощью функции imshow, но оно показало БЕЛОЕ изображение. В документации его, учитывая, что изображения с плавающей запятой будут отображаться в 0–255, но это просто показал белое изображение. Я попытался преобразовать его в CV_8U, используя

Мат A = Mat :: ones (300,300, CV_32FC1) * 1000;

выполнить некоторую обработку - присвоить значения с плавающей запятой пикселям в A

......

Мат Б;

A.convertTo (B, CV_8U)

Когда я показываю "B", я получаю черно-белое изображение, без оттенков серого. Правильно ли сопоставлены пиксели с плавающей запятой в A с 0–255? Я что-то не так делаю?

Немногочисленные значения в A равны 1000 как инициализированные, а остальные - это числа с плавающей запятой, которые присваиваются во время обработки.


person Karthik Murugan    schedule 26.01.2013    source источник


Ответы (1)


В OpenCV, если изображение имеет тип с плавающей запятой, то только те пиксели могут быть визуализированы с помощью imshow, которые имеют значение от 0,0 до 1,0, если значение больше 1,0, оно будет отображаться как белый пиксель, а если меньше 0.0, он будет отображаться как черный пиксель. Чтобы визуализировать изображение с плавающей запятой, масштабируйте его значения до диапазона 0.0 - 1.0.

Что касается части преобразования ... При использовании с аргументами по умолчанию функция cv::Mat::convertTo просто создает матрицу указанного типа, а затем копирует значения из исходной матрицы и затем округляет их до ближайшего возможного значения целевого типа данных. . Если значение выходит за пределы допустимого диапазона, оно ограничивается минимальным или максимальным значением.

В документации imshow написано, что:

Если изображение 32-битное с плавающей запятой, значения пикселей умножаются на 255. То есть диапазон значений [0,1] отображается на [0,255].

Это означает, что только значения в диапазоне от 0,0 до 1,0 будут сопоставлены с 0 до 255. Если значение больше 1,0 и умножено на 255, оно станет больше 255. Затем оно будет ограничено диапазоном CV_8U и в конечном итоге он также станет 255.

В вашем примере все значения, равные 1000, станут 255 в матрице назначения, поскольку тип назначения - CV_8U, а максимально возможное значение - 255. Все значения с плавающей запятой будут floored. Автоматическое сопоставление не выполняется.

Чтобы соответствующим образом сопоставить значения с диапазоном CV_8U, используйте 3-й и 4-й параметры функции cv::Mat::convertTo, чтобы значения масштабировались до выполнения преобразования.

Предположим, что матрица A имеет минимальное и максимальное значения Min и Max, где Min!=Max.

Чтобы правильно масштабировать значения от 0 до 255, вы можете сделать следующее:

if (Min!=Max){ 
    A -= Min;
    A.convertTo(B,CV_8U,255.0/(Max-Min));
}

Вы также можете сделать это прямо так:

if (Min!=Max)
    A.convertTo(B,CV_8U,255.0/(Max-Min),-255.0*Min/(Max-Min));

(отредактировано с учетом комментария zhangxaochen)

person sgarizvi    schedule 26.01.2013
comment
Спасибо sgar91, я только что обнаружил, что минимальное значение - 2.3221, а максимальное - 1000. Как сопоставить этот диапазон с 0-255? Я имею в виду, что я должен использовать для 3-го и 4-го параметра в convertTo? - person Karthik Murugan; 26.01.2013
comment
поле beta должно быть -255.0*Min/(Max-Min) вместо -255.0/Min. - person zhangxaochen; 10.05.2014
comment
но все же, чтобы увидеть понятную визуализацию, нам нужно преобразовать в форму CV_8U. - person Abc; 25.11.2017