Преобразовать 16-битную глубину CvMat * в 8-битную глубину - PullRequest
10 голосов
/ 02 августа 2011

Я работаю с Kinect и OpenCV. Я уже ищу в этом форуме, но я не нашел ничего похожего на мою проблему. Я сохраняю необработанные данные глубины из Kinect (16 бит), сохраняю их в CvMat *, а затем передаю их в cvGetImage для создания из них IplImage:

CvMat* depthMetersMat = cvCreateMat( 480, 640, CV_16UC1 );
[...]
cvGetImage(depthMetersMat,temp);

Но теперь мне нужно поработать над этим изображением, чтобы выполнить cvThreshdold и найти контуры. Этим двум функциям требуется 8-битная глубина изображения на входе. Как я могу преобразовать CvMat * deepMetersMat в 8-битную глубину CvMat *?

Ответы [ 2 ]

20 голосов
/ 02 мая 2012

Ответ, который дал @SSteve, почти сработал для меня, но вызов convertTo, казалось, просто отрубил байт старшего разряда вместо фактического масштабирования значений до 8-битного диапазона. Поскольку @Sirnino не указывал, какое поведение требуется, я решил опубликовать код, который будет выполнять (линейное) масштабирование, на случай, если кто-то еще захочет это сделать.

Оригинальный код SSteve:

 CvMat* depthMetersMat = cvCreateMat( 480, 640, CV_16UC1 );  
 cv::Mat m2(depthMetersMat, true);  
 m2.convertTo(m2, CV_8U);

Чтобы масштабировать значения, вам просто нужно добавить коэффициент масштабирования (1/256 или 0,00390625 для масштабирования от 16 до 8 бит) в качестве третьего параметра (альфа) к вызову convertTo

m2.convertTo(m2, CV_8U, 0.00390625);

Вы также можете добавить четвертый параметр (дельта), который будет добавляться к каждому значению после его умножения на альфа. См. документы для получения дополнительной информации.

2 голосов
/ 02 августа 2011

Это должно работать:

CvMat* depthMetersMat = cvCreateMat( 480, 640, CV_16UC1 );
cv::Mat m2(depthMetersMat, true);
m2.convertTo(m2, CV_8U);

Но в соответствии с документацией OpenCV , CvMat устарел. Вы должны использовать Мат вместо этого.

...