单目相机测距

  1. 三角测距
    专业画法
    个人理解
void getCoord(cv::Point &point, float coord[2]){
	float y;
	float x;
	if (point.y > IMG_HEIGHT / 2) {
		y = h / tan(theta + atan((point.y - IMG_HEIGHT / 2) * 2 * tan(beta) / IMG_HEIGHT));
	}
	else {
		float alpha = theta - atan((IMG_HEIGHT / 2 - point.y) * 2 * tan(beta) / IMG_HEIGHT);
		if (alpha < 0) {
			y = 10;
		}
		else {
			y = h / tan(alpha);
		}
	}
	//x方向畸变 桶形畸变,暂未考虑枕形畸变,用sqrt平方根来近似
	float rate = 1.0 - (point.y - IMG_HEIGHT / 2) * 2 / IMG_HEIGHT;
	float gama0 = gama1 + sqrt(rate) * (gama - gama1);
	x = sqrt(h *h + y * y) * (point.x - IMG_WIDTH / 2) * tan(gama0) * 2 / IMG_WIDTH;
	coord[0] = x;
	coord[1] = y;
	return;
}


void getDistance(cv::Point &point, float &dis) {
	float coord[2];
	getCoord(point, coord);
	dis = sqrt(pow(coord[0], 2) + pow(coord[1], 2));
	return;
}
  1. PnP测距
    参考:【RoboMaster】我是这样搞定第一次单目相机测距的
    原理(PnP函数求解):
bool cv::solvePnP(
  cv::InputArray  objectPoints,     //三维点坐标矩阵,至少四个(世界坐标系) 必填
  cv::InputArray  imagePoints,      //该四个点在图像中的像素坐标	必填
  cv::InputArray  cameraMatrix,     //相机内参矩阵(3*3)	选填
  cv::InputArray  distCoeffs,       //相机畸变系数(5*1)或(4*1) 选填
  cv::OutputArray rvec,             //输出旋转矩阵(3*1) 
  cv::OutputArray tvec,             //输出平移矩阵 (3*1) ***这就可以实现测距目的***
  bool        useExtrinsicGuess = false,  
  int        flags = cv::SOLVEPNP_ITERATIVE
);

应用:

vector<Point3f> obj = vector<Point3f>{
        cv::Point3f(-HALF_LENGTH, -HALF_LENGTH, 0),  //tl
        cv::Point3f(HALF_LENGTH, -HALF_LENGTH, 0),  //tr
        cv::Point3f(HALF_LENGTH, HALF_LENGTH, 0),  //br
        cv::Point3f(-HALF_LENGTH, HALF_LENGTH, 0)  //bl
    };   //自定义二维码四个点坐标
    cv::Mat rVec = cv::Mat::zeros(3, 1, CV_64FC1);//init rvec 
    cv::Mat tVec = cv::Mat::zeros(3, 1, CV_64FC1);//init tvec
    cv::solvePnP(obj, pnts, cameraMatrix, distCoeff, rVec, tVec, false, SOLVEPNP_ITERATIVE);

不建议使用原因如下:
2.1 需要知晓目标物的尺寸,比如上面代码里的HALF_LENGTH
2.2 虽然相机内外参是选填的,但如果内外参准确的话会大大提高测距精度
2.3 目标形状变化太大或部分遮挡或特征点不明显等均会影响测距精度
3. 是

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值