Kinect Azure开发系列(一):深度图的获取及转换显示 |
您所在的位置:网站首页 › 深度图像转化成可视点云 › Kinect Azure开发系列(一):深度图的获取及转换显示 |
首先,图像的深度一般是16位的,因为8位的只能表示256个不同的深度值,分辨率太低.对于16位深度数据的显示 法1:16位可以直接转成8位的显示 depth_frame = cv::Mat(depthImage.get_height_pixels(), depthImage.get_width_pixels(), CV_16U, depthImage.get_buffer()); depth_frame.convertTo(depth_out, CV_8U, 1);这种是直接将16位转成8位,然后,后面设置的是1,也就是低于255的不变,高于的全部转位255,数据的实际信息会丢失.如果设置为很大的值,数据丢失的会更大,详见参考资料中这个函数的原理. 法2: 16位归一化后显示由于imshow只认0~255的数值,16位的数据可以归一化到0 ~255. depth_frame = cv::Mat(depthImage.get_height_pixels(), depthImage.get_width_pixels(), CV_16U, depthImage.get_buffer()); normalize(depth_frame, depth_out, 0, 256* 256, NORM_MINMAX); 显示结果
参考这位博主的 里面详细介绍了: (1) cv::Mat的各种类型(位数+基本类型+通道)对应的type的返回值 (2) 不同的通道数对应的单个像素点的数据类型,比如3通道的图像,在单个像素点(i,j)处是一个3维向量,该向量的元素的具体的基本的数据类型才是uchar 或者 short等 2.imshow和imwrite函数 imshowopencv的imshow函数都只能对像素值处于0-255范围内的图像进行显示。也就是说,无法使用OpenCV提供的接口函数显示诸如CV_16S等非8位数据格式的视差图/深度图,只能转换成CV_8U格式进行操作。 其实,人眼对灰度级的敏感度比较低、根本无法分辨256级灰度值。而对视差图/深度图进行显示,也只是为了比较直观的验证视差图/深度图的准确性(如颜色随距离逐层变化),所以说完全没必要对216 =65536级灰度进行显示,转换成CV_8U格式就能完全满足需求,这也许就是为什么OpenCV没有提供这样接口的原因之一吧。 https://blog.csdn.net/YunLaowang/article/details/86583351 imwrite而存储的话,imwrite函数在关于保存为不同深度格式时候的图像类型支持说明如下: 8位的图像(CV_8U),支持png/jpg/bmp/webp等各种常见图像格式 16位的图像(CV_16U),支持png/jpeg2000/TIFF格式 32位的图像(CV_32F),支持PFM/TIFF/OpenEXR/TIFF/HDR 在要保存为指定格式之前,可以通过convertTo或者cvtCOLOR进行图像类型或者通道转换之后,再调用imwrite进行保存。 为了显示,利用自带的cv::convertTo函数 参考1 参考2 convertTo的用法 src.convertTo(dst, type, scale, shift)函数 convertTo()函数负责转换数据类型不同的Mat,即可以将类似float型的Mat转换到uchar型的, imwrite()函数能够接受的类型。 而cvtColor()函数是负责转换不同通道的Mat,因为该函数的第4个参数就可以设置目的Mat数据的通道数(只是我们一般没有用到它,一般情况下这个函数是用来进行色彩空间转换的)。 另外也可以不用imwrite()函数来存图片数据,可以直接用通用的XML IO接口函数将数据存在XML或者YXML中。 参考3 注: 函数template _Tp saturate_cast(_Tp2 v) 将参数v转换成模板中的类型,比如说: uchar a = saturate_cast(-100);4.对非8位的图像数据进行保存 xml文件的格式存储原始数据 txt文件直接存储原始数据,这个其实就是索引到Mat的具体位的元素值,然后存储.实际使用注意修改at后面的数据类型,是uint,float等 这里的方法2是逐个像素的转换,会有信息的丢失,就是超过255的数据会变为255, 16位或32位数据转8位后保存,直接转和归一化以后转,其c++代码如下: 16位图像保存 转换成16位数据后,直接保存,不会引起数据的丢失 // 加载图像 Mat src = imread( "D:/flower.png", IMREAD_UNCHANGED);// IMREAD_UNCHANGED确保按照图像未做任何改变读入,不如按照原位数 printf( "depth %d n", src.depth()); // 转为16位图像 Mat dst; src.convertTo(dst, CV_16U); imshow( "flower16", dst);//未进行归一化,显示是全黑的 imwrite( "D:/flower-16.png", dst);//但是保存的是原始的数据转换后,归一化以后再保存 Mat src = imread( "D:/flower.png", IMREAD_UNCHANGED); printf( "depth %d n", src.depth()); // 转为16位图像 Mat dst; src.convertTo(dst, CV_16U); // 归一化再保存 normalize(dst, dst, 0, 256* 256, NORM_MINMAX); imwrite( "D:/flower-16.png", dst);//进行了0~255的归一化以后,可以显示 imshow( "flower-16", dst);32位图像保存 // 加载图像 Mat src = imread( "D:/flower.png", IMREAD_UNCHANGED); printf( "depth %d n", src.depth()); // 转32位图像 Mat dst; src.convertTo(dst, CV_32F); // 归一化再保存 normalize(dst, dst, 0, 1.0, NORM_MINMAX); imwrite( "D:/flower-32.png", dst); imshow( "flower-32", dst); |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |