高精度地图应用(三)单帧重建

   单帧重建是指车道线的重建,为何选择车道线是因为车道线输出稳定,每一帧图像都有,而且车道线特征很强,语义分割技术比较成熟。首先,需要对原图进行语义分割以提取车道线,如:

   然后,在语义分割基础上进行折线拟合,我这里就直接采用了opencv直线拟合的方式,代码:

std::vector<Eigen::Vector2d> utils::Fitting2d(const std::vector<cv::Point2d>& geometry2d, cv::Mat K, cv::Mat D)
{
	std::vector<Eigen::Vector2d> fitting_line;
	if (geometry2d.size() < 2)
	{
		return fitting_line;
	}

	std::vector<cv::Point2d> undistort_points;
	cv::undistortPoints(geometry2d, undistort_points, K, D, cv::noArray(), K);

	int maxRow = 0, minRow = 10000, maxCol = 0, minCol = 10000;
	for (cv::Point pix2d : undistort_points)
	{
		if (pix2d.x > maxCol) maxCol = pix2d.x;
		if (pix2d.x < minCol) minCol = pix2d.x;
		if (pix2d.y > maxRow) maxRow = pix2d.y;
		if (pix2d.y < minRow) minRow = pix2d.y;
	}

	std::vector<cv::Vec2d> to_be_fittings;
	for (size_t i = 0; i < undistort_points.size(); i++)
	{
		to_be_fittings.emplace_back(
		undistort_points[i].x,
		undistort_points[i].y);
	}

	cv::Vec4f line_args;
	cv::fitLine(to_be_fittings,
			line_args,
			7,
			0, 0.01, 0.01);

	double cos_theta = line_args[0];
	double sin_theta = line_args[1];
	double x0 = line_args[2];
	double y0 = line_args[3];
	double x1 = x0 + cos_theta;
	double y1 = y0 + sin_theta;
	Eigen::Vector3d line = Eigen::Vector3d(x0, y0, 1.0).cross(Eigen::Vector3d(x1, y1, 1.0));

	int sample_cnt = 20;
	double sample_interval = (maxRow - minRow) / sample_cnt;
	for(std::size_t i = 0; i <= sample_cnt; i++)
	{
		double row = maxRow - i * sample_interval;
		Eigen::Vector3d row_sample_line = Eigen::Vector3d(minCol, row, 1.0).cross(Eigen::Vector3d(maxCol, row, 1.0));
		Eigen::Vector3d cross_point = line.cross(row_sample_line);
		if(std::fabs(cross_point.z()) > EPS)
		{
			cross_point /= cross_point.z();
			fitting_line.emplace_back(cross_point.x(), cross_point.y());
		}
	}
	return fitting_line;
}

 

    接下来,利用前面(二)所得的四个参数,俯仰角pitch,翻滚角roll,偏航角yaw,以及车身高度h,就能将拟合的二维折线反投到三维空间中,代码:

bool utils::FittingPolyline(const std::vector<cv::Point2d>& ctour, cv::Mat K, cv::Mat D, const VMC::Camera &cam, std::vector<Eigen::Vector3d>& wSpline, double scope)
{
	auto imgToBody = [&](Eigen::Vector2d xi, Eigen::Vector3d& c3d, double sight) -> bool
	{
		cv::Mat xi3 = (cv::Mat_<double>(3, 1) << xi.x(), xi.y(), 1.0);
		cv::Mat xc3 = K.inv() * xi3;

		cv::Vec2d p;
		p[0] = xc3.at<double>(0, 0);
		p[1] = xc3.at<double>(1, 0);

		Eigen::Vector3d xc(p[0], p[1], 1.0);
		Eigen::Vector3d trans = cam.mount.translation;
		Eigen::Vector3d rot_xb = cam.mount.rotation.matrix() * xc;
		if(std::fabs(rot_xb.z()) > EPS)
		{
			double scale = - trans.z() / rot_xb.z();
			rot_xb = scale * rot_xb + trans;
			double r = rot_xb.x();

			if (r <= sight && r > 0)
			{
				c3d.x() = rot_xb.x();
				c3d.y() = rot_xb.y();
				c3d.z() = rot_xb.z();
				return  true;
			}
		}
		return false;
	};

	std::vector<Eigen::Vector2d> spline = Fitting2d(ctour, K, D);
	if (!spline.empty())
	{
		for (Eigen::Vector2d p : spline)
		{
			Eigen::Vector3d b3d;
			if (imgToBody(p, b3d, scope))
			{
				wSpline.push_back(b3d);
			}
		}
	}

	if (wSpline.size() > 1)
	{
		geometry::Resample(wSpline, 1.0);
		return true;
	}
	return false;
}

         接下来,就该将三维折线与高精度地图进行配准以求得RT,从而实现横向定位了。

重建的效果大概是这样:

二维语义图:

三维重建图:

### 单目RGBD相机重建技术概述 对于单目RGBD相机实现重建的技术,主要依赖于融合视觉几何与深度学习算法。尽管传统上认为RGB-D传感器提供更丰富的数据用于即时定位与地图构建(SLAM),但研究显示仅依靠标准RGB摄像头同样能够达成高质量的维建模效果[^3]。 #### 基础原理 核心在于通过连续帧间特征匹配计算相对位姿变化,并利用结构光或ToF(Time of Flight)获取每桢图像对应的深度信息。然而,在仅有彩色图而无额外硬件支持的情况下,则需借助多视角几何理论估计场景距离。具体来说,就是根据一系列不同位置拍摄的照片推测出物体的空间布局[^4]。 #### 关键挑战及其解决方案 - **尺度不确定性**:不同于双目或多摄像装置能直接测量实际尺寸大小,单一镜头无法独立确定远近关系。为此引入了自监督学习机制训练神经网络预测绝对尺度因子。 - **光照条件适应性差**:自然环境中光线强度频繁变动影响成像质量进而干扰后续处理流程。对此开发出了鲁棒性强的数据预处理模块以增强抗噪性能并保持细节清晰度不变。 - **运动模糊效应严重**:快速移动可能导致曝光不足造成画面失真难以解析真实形状轮廓。采用高帧率采集配合时间累积策略有效缓解此类现象带来的困扰。 #### 实现路径 一种可行方案是从开源框架出发定制化调整参数设置满足特定应用场景需求: 1. 利用ORB-SLAM2等成熟工具包初始化项目架构; 2. 集成Mask R-CNN实例分割模型辅助提取感兴趣区域内的语义标签指导配准过程; 3. 结合PointNet++点云分类器优化最终输出成果精度。 ```python import cv2 from maskrcnn_benchmark.config import cfg from predictor import COCODemo def process_frame(frame): coco_demo = COCODemo( cfg, min_image_size=800, confidence_threshold=0.7, ) predictions, _ = coco_demo.run_on_opencv_image(frame) return predictions ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神气爱哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值