深度图

深度图

深度图表示

32 bits images should be in meters, and 16 bits should be in mm
深度图:32位的值表示米,16位的值表示mm.
因为无符型16位置图像能表示的范围为:(0~65535)且是整数.为了表示带小数的深度值,16位的值只能以mm为单位,即只能表示0m ~ 65.5m的范围.

用16位存储深度图的方便是,它能够被存为png格式.而32位的图像只能被存为tif格式.
如果用opencv导出的话,Mat类型为CV_32FC1或CV_16UC1(注意imwrite时不要用CV_16SC1,但在读取像素值时可以用at< short>())

32位深度图与16位深度图的转换

cv::Mat cvtDepthFromFloat(const cv::Mat & depth32F)
{
	UASSERT(depth32F.empty() || depth32F.type() == CV_32FC1);
	cv::Mat depth16U;
	if(!depth32F.empty())
	{
		depth16U = cv::Mat(depth32F.rows, depth32F.cols, CV_16UC1);
		int countOverMax = 0;
		for(int i=0; i<depth32F.rows; ++i)
		{
			for(int j=0; j<depth32F.cols; ++j)
			{
				float depth = (depth32F.at<float>(i,j)*1000.0f);
				unsigned short depthMM = 0;
				if(depth > 0 && depth <= (float)USHRT_MAX)
				{
					depthMM = (unsigned short)depth;
				}
				else if(depth > (float)USHRT_MAX)
				{
					++countOverMax;
				}
				depth16U.at<unsigned short>(i, j) = depthMM;
			}
		}
		if(countOverMax)
		{
			UWARN("Depth conversion error, %d depth values ignored because "
				  "they are over the maximum depth allowed (65535 mm). Is the depth "
				  "image really in meters? 32 bits images should be in meters, "
				  "and 16 bits should be in mm.", countOverMax);
		}
	}
	return depth16U;
}

cv::Mat cvtDepthToFloat(const cv::Mat & depth16U)
{
	UASSERT(depth16U.empty() || depth16U.type() == CV_16UC1);
	cv::Mat depth32F;
	if(!depth16U.empty())
	{
		depth32F = cv::Mat(depth16U.rows, depth16U.cols, CV_32FC1);
		for(int i=0; i<depth16U.rows; ++i)
		{
			for(int j=0; j<depth16U.cols; ++j)
			{
				float depth = float(depth16U.at<unsigned short>(i,j))/1000.0f;
				depth32F.at<float>(i, j) = depth;
			}
		}
	}
	return depth32F;
}

视差图转深度图

cv::Mat depthFromDisparity(const cv::Mat & disparity,
		float fx, float baseline,
		int type)
{
	UASSERT(!disparity.empty() && (disparity.type() == CV_32FC1 || disparity.type() == CV_16SC1));
	UASSERT(type == CV_32FC1 || type == CV_16UC1);
	cv::Mat depth = cv::Mat::zeros(disparity.rows, disparity.cols, type);
	int countOverMax = 0;
	for (int i = 0; i < disparity.rows; i++)
	{
		for (int j = 0; j < disparity.cols; j++)
		{
			float disparity_value = disparity.type() == CV_16SC1?float(disparity.at<short>(i,j))/16.0f:disparity.at<float>(i,j);
			if (disparity_value > 0.0f)
			{
				// baseline * focal / disparity
				float d = baseline * fx / disparity_value;
				if(d>0)
				{
					if(depth.type() == CV_32FC1)
					{
						depth.at<float>(i,j) = d;
					}
					else
					{
						if(d*1000.0f <= (float)USHRT_MAX)
						{
							depth.at<unsigned short>(i,j) = (unsigned short)(d*1000.0f);
						}
						else
						{
							++countOverMax;
						}
					}
				}
			}
		}
	}
	if(countOverMax)
	{
		UWARN("Depth conversion error, %d depth values ignored because they are over the maximum depth allowed (65535 mm).", countOverMax);
	}
	return depth;
}

opencv读取深度图

因为深度图都是png或tiff的,所以要用IMREAD_ANYDEPTH

    cv::Mat result = cv::imread("1.png",cv::IMREAD_ANYDEPTH);
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值