一、各类距离公式总结
常见距离公式
欧氏距离:
曼哈顿距离(L1):
切比雪夫距离(Chessboard):
1、点与点距离(欧氏距离)
-
二维空间
设两点坐标为 P1(x1,y1)、P2(x2,y2),其距离为: -
三维空间
设两点坐标为 P1(x1,y1,z1)、P2(x2,y2,z2),距离公式为:
2、点与直线距离
-
二维直线
已知直线方程 Ax+By+C=0,点 P(x0,y0)P(x0,y0),距离公式为: -
三维直线
若直线由参数方程表示,可通过向量叉乘计算。设直线上一点 M,方向向量,点 P 到直线的距离为:
3、点与平面距离
三维空间
已知平面方程 Ax+By+Cz+D=0Ax+By+Cz+D=0,点 P(x0,y0,z0)P(x0,y0,z0),距离公式为:
4、点与不规则曲面距离
不规则曲面通常无统一解析式,需采用以下方法近似计算:
- 数值优化:通过迭代算法(如梯度下降)寻找曲面上与点距离最小的位置。
- 参数化投影:若曲面可参数化,将点投影至参数空间求解。
- 离散逼近:将曲面离散为网格,计算点到各网格面的最小距离。
二、OpenCV距离公式
1. 点与点之间的距离
在二维或三维空间中,计算两个点之间的欧氏距离是最直接的。
#include <opencv2/opencv.hpp>
#include <iostream>
#include <cmath>double distancePointToPoint(const cv::Point& p1, const cv::Point& p2) {return std::sqrt(std::pow(p2.x - p1.x, 2) + std::pow(p2.y - p1.y, 2));
}int main() {cv::Point p1(1, 2);cv::Point p2(4, 6);// 方法1:直接利用公式计算std::cout << "Distance: " << distancePointToPoint(p1, p2) << std::endl;// 方法2:使用cv::norm函数 欧氏距离
double distance = cv::norm(p2-p1, cv::NORM_L2);//方法2:使用cv::norm函数 曼哈顿距离
double l1_distance = cv::norm(pt2 - pt1, cv::NORM_L1);//方法2:使用cv::norm函数 切比雪夫距离
double chessboard_distance = cv::norm(pt2 - pt1, cv::NORM_INF);return 0;
}
2. 点到直线的距离
点到直线的距离可以通过多种方式计算,这里介绍一种常见的方法,使用点到直线的垂直距离公式。假设直线由两点确定(A和B),或者通过一个点和斜率(y = mx + c)。
使用两点定义直线:
double distancePointToLine(const cv::Point& p, const cv::Point& A, const cv::Point& B) {double numerator = std::abs((B.y - A.y) * p.x - (B.x - A.x) * p.y + B.x * A.y - A.x * B.y);double denominator = std::sqrt(std::pow(B.y - A.y, 2) + std::pow(B.x - A.x, 2));return numerator / denominator;
}
使用点和斜率定义直线:
double distancePointToLine(const cv::Point& p, double m, double c) { // y = mx + creturn std::abs(m * p.x - p.y + c) / std::sqrt(m * m + 1);
}
3. 点到面的距离
点到面的距离计算涉及到三维空间中的点、直线和平面。在三维空间中,一个平面可以通过一个点和法向量来定义。点到平面的距离可以通过以下公式计算:
double distancePointToPlane(const cv::Point3f& p, const cv::Point3f& planePoint, const cv::Vec3f& normal) {return std::abs(normal.dot(p - planePoint)); // 使用OpenCV的Vec3f的dot()方法计算点积并取绝对值
}
示例代码:
int main() {cv::Point p(3, 3);cv::Point A(1, 1), B(4, 4); // 两点定义直线ABstd::cout << "Distance from point to line: " << distancePointToLine(p, A, B) << std::endl;cv::Point3f point3d(2, 2, 2); // 三维点cv::Point3f planePoint(0, 0, 0); // 平面上的一点cv::Vec3f normal(0, 0, 1); // 法向量,例如z轴方向上的单位向量 (0, 0, 1)std::cout << "Distance from point to plane: " << distancePointToPlane(point3d, planePoint, normal) << std::endl;return 0;
}
4.图像的距离变换(Distance Transform)
用于计算二值图像中每个像素到最近背景像素的距离。OpenCV支持多种距离类型:
DIST_L1
:曼哈顿距离(快速计算)DIST_L2
:欧氏距离(精确计算)DIST_C
:棋盘距离(切比雪夫距离)cv::Mat binaryImage; // 输入二值图像(0表示背景,非0表示前景) cv::Mat distImage;cv::distanceTransform(binaryImage, distImage, cv::DIST_L2, 5);
5. 轮廓/形状之间的距离
使用 cv::matchShapes()
计算两个形状的相似性(基于Hu矩):
double similarity = cv::matchShapes(contour1, contour2, cv::CONTOURS_MATCH_I1, 0);