本次实验包含两个题目
- 砖块的检测与位姿估计
- 窗户的检测与位姿估计
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.avi,brick-large.bag.rgbdepth.avi,brick-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:之前数据没有对齐,现在视频均已对齐。
对数据读写,图片对应有问题欢迎在评论区讨论,我会第一时间进行解答。