首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Kinect Azure开发系列(一):深度图的获取及转换显示

  • 23-09-26 04:21
  • 2537
  • 9733
blog.csdn.net

首先,图像的深度一般是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);
  • 1
  • 2

这种是直接将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
  • 2

显示结果

在这里插入图片描述
这里可以点开大图查看,左侧是归一化的结果,出现了很多浅灰色的值,明显起保留了全部的数据信息(细节都保留了),只是缩放到了0~255.但是后者超过255的数据都是255,所以白色面积很大.

补充资料

1.opencv的Mat类型的数据类型

参考这位博主的
里面详细介绍了:
(1) cv::Mat的各种类型(位数+基本类型+通道)对应的type的返回值

(2) 不同的通道数对应的单个像素点的数据类型,比如3通道的图像,在单个像素点(i,j)处是一个3维向量,该向量的元素的具体的基本的数据类型才是uchar 或者 short等

2.imshow和imwrite函数

imshow

opencv的imshow函数都只能对像素值处于0-255范围内的图像进行显示。也就是说,无法使用OpenCV提供的接口函数显示诸如CV_16S等非8位数据格式的视差图/深度图,只能转换成CV_8U格式进行操作。
其实,人眼对灰度级的敏感度比较低、根本无法分辨256级灰度值。而对视差图/深度图进行显示,也只是为了比较直观的验证视差图/深度图的准确性(如颜色随距离逐层变化),所以说完全没必要对216 =65536级灰度进行显示,转换成CV_8U格式就能完全满足需求,这也许就是为什么OpenCV没有提供这样接口的原因之一吧。
http://iyenn.com/rec/367150.html

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进行保存。

  1. 为了显示,利用自带的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<uchar>(-100); 
  • 1

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);//但是保存的是原始的数据
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

转换后,归一化以后再保存

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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
注:本文转载自blog.csdn.net的ChLee98的文章"https://blog.csdn.net/weixin_42696356/article/details/104864778"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top