一、各類距離公式總結
常見距離公式
?? ? 歐氏距離:
? ? 曼哈頓距離(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);