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

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

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

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

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

......

Мать B;

A.convertTo(В, CV_8U)

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

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

4b9b3361

Ответ 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. Все значения с плавающей запятой будут floor ed. Автоматическое сопоставление не выполняется.

Чтобы правильно сопоставить значения с диапазоном 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)