OpenCV实验(一):砖块的检测与位姿估计,窗户的检测与位姿估计

本次实验包含两个题目

  • 砖块的检测与位姿估计
  • 窗户的检测与位姿估计

2019-4-28更新:

  • 针对4类RGB-D数据,已将深度数据和可见光数据进行对齐
  • 给出数据读取的代码demo
  • 给出相机的内参信息
  • 注:此次更新将会替换之前数据集的说明

数据下载链接:https://pan.baidu.com/s/1Zu7l5GCHbzP-dxHvSba5Fg 提取码:34xe
在文件夹OpenCV实验1中2019-4-27更新中,为一个压缩包

1 砖块的检测与位姿估计

现有三种尺寸的砖块,尺寸信息已知,要求检测出砖块,并计算出其姿态信息。

  • 砖(小):尺寸0.30m×0.20m×0.20m。其中,RGB数据存储在视频文件brick-small.bag.rgb.avi,可使用cv::VideoCapture进行读取。深度数据存储在brick-small.bagdepth.txt,此文件为二进制文件,读取方法在后面的demo代码中。视频文件brick-small.bag.rgbdepth.avi为深度数据彩色化结果。

在这里插入图片描述

  • 砖(中):尺寸0.60m×0.20m×0.20m。其中,RGB数据存储在视频文件brick-medium.bag.rgb.avi,可使用cv::VideoCapture进行读取。深度数据存储在brick-medium.bagdepth.txt。视频文件brick-medium.bag.rgbdepth.avi为深度数据彩色化结果。

  • 砖(大):尺寸1.20m×0.20m×0.20m。其中,RGB数据存储在视频文件brick-large.bag.rgb.avi,可使用cv::VideoCapture进行读取。深度数据存储在brick-large.bagdepth.txt。视频文件brick-large.bag.rgbdepth.avi为深度数据彩色化结果。

注:每个砖块颜色和尺寸固定,可以基于这个合作信息进行处理

2 窗户的检测与位姿估计

采集的是新主楼的室内窗户,暂无尺寸信息,可以自己去量下。

RGB数据存储在视频文件windows-close.bag.rgb.avi,可使用cv::VideoCapture进行读取。深度数据存储在windows-close.bagdepth.txt。视频文件windows-close.bag.rgbdepth.avi为深度数据彩色化结果。

在这里插入图片描述

3 相关资料

3.1 数据读取代码

下面给出每组数据的读取方法,每组视频共有3个文件,brick-large.bag.rgb.avibrick-large.bag.rgbdepth.avibrick-large.bagdepth.txt,可见光数据存储在imgC中,数据类型为CV_8UC3,深度数据存储在imgD中,数据类型为CV_16UC1。

int main()
{
	string root_path = "E:\\深度数据\\";
	string base_name = "windows-close.bag";

	VideoCapture caprgb(root_path + base_name + ".rgb.avi"); // 打开可见光视频
	if (!caprgb.isOpened())
	{
		cout << "无法打开可见光视频:" << root_path + base_name + ".rgb.avi" << endl;
	}
	
	VideoCapture capdeprgb(root_path + base_name + ".rgbdepth.avi"); // 打开深度图可视化视频
	if (!capdeprgb.isOpened())
	{
		cout << "无法打开深度图可视化视频:" << root_path + base_name + ".rgbdepth.avi" << endl;
	}

	ifstream infile(root_path + base_name + "depth.txt", ios::binary); // 打开深度数据
	if (!infile.is_open())
	{
		cout << "无法打开深度图数据:" << root_path + base_name + "depth.txt" << endl;
	}


	int width = caprgb.get(cv::CAP_PROP_FRAME_WIDTH);
	int height = caprgb.get(cv::CAP_PROP_FRAME_HEIGHT);
	Mat imgC(height, width, CV_8UC3), imgDrgb(height, width, CV_8UC3), imgD(height, width, CV_16UC1), imgDt;
	while (1)
	{
		caprgb >> imgC; // 读取可见光视频
		if (imgC.empty())
		{
			cout << "到达视频尾部,结束" << endl;
			break;
		}


		capdeprgb >> imgDrgb; // 读取深度可视化视频

		infile.read((char*)imgD.data, height * width * sizeof(unsigned short)); // 读取深度数据
		
		imgD.convertTo(imgDt, CV_8UC1, 0.05); // 深度数据灰度可视化


		imshow("Visible", imgC);
		imshow("DepthRGB", imgDrgb);
		imshow("DepthGray", imgDt);


		waitKey();
	}
	infile.close();
	caprgb.release(), capdeprgb.release();
	return 0;
}

3.2 相机内参信息

相机内参信息:

变量名描述
width图像像素宽度1280
height图像像素高度720
fx图像x方向的焦距639.2278
fy图像y方向的焦距639.2278
ppx图像主点(principal point)的水平坐标640.4396
ppy图像主点(principal point)的竖直坐标335.2707

其余参数,比如畸变之类,均为0。下面给出内参的使用方法:
先定义一个相机内参结构体,这里的变量按照上面的方法定义即可,其中coeffs全为0。

typedef struct intrinsics
{
	int           width;     /**< Width of the image in pixels */
	int           height;    /**< Height of the image in pixels */
	float         ppx;       /**< Horizontal coordinate of the principal point of the image, as a pixel offset from the left edge */
	float         ppy;       /**< Vertical coordinate of the principal point of the image, as a pixel offset from the top edge */
	float         fx;        /**< Focal length of the image plane, as a multiple of pixel width */
	float         fy;        /**< Focal length of the image plane, as a multiple of pixel height */
	float         coeffs[5]; /**< Distortion coefficients, order: k1, k2, p1, p2, k3 */
} intrinsics;

下面给出一个函数,这个函数将图像上一个像素点映射到相机坐标系下的空间点。
intrin为相机内参,pixel为图像上的一个像素坐标,depth,为对应的深度,计算的空间点3D坐标存储在point中。

/* Given pixel coordinates and depth in an image with no distortion or inverse distortion coefficients, 
compute the corresponding point in 3D space relative to the same camera */
void rs2_deproject_pixel_to_point(float point[3], const struct intrinsics * intrin, const float pixel[2], float depth)
{
	float x = (pixel[0] - intrin->ppx) / intrin->fx;
	float y = (pixel[1] - intrin->ppy) / intrin->fy;

	float r2 = x * x + y * y;
	float f = 1 + intrin->coeffs[0] * r2 + intrin->coeffs[1] * r2*r2 + intrin->coeffs[4] * r2*r2*r2;
	float ux = x * f + 2 * intrin->coeffs[2] * x*y + intrin->coeffs[3] * (r2 + 2 * x*x);
	float uy = y * f + 2 * intrin->coeffs[3] * x*y + intrin->coeffs[2] * (r2 + 2 * y*y);
	x = ux;
	y = uy;

	point[0] = depth * x;
	point[1] = depth * y;
	point[2] = depth;
}

4 FAQ

  • Q:数据视频是否对齐
    A:之前数据没有对齐,现在视频均已对齐。

对数据读写,图片对应有问题欢迎在评论区讨论,我会第一时间进行解答。

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值