专栏简介 | ||
💒个人主页 | 📖心灵鸡汤📖 我们唯一拥有的就是今天,唯一能把握的也是今天 建议把本文当作笔记来看,据说专栏目录里面有相应视频🤫 | 📰专栏目录 |
一、拟合直线
1.字段
列举部分,更多请查看官方文档。
DIST_L1 | 这是L1距离度量。它计算两点之间的绝对差值之和 |
DIST_L12 | 这是加权L1距离度量。它结合了L1和L2距离的特性 |
DIST_L2 | 这是欧几里得距离,也就是L2距离度量。它计算两点之间的平方差之和的平方根 |
2.方法说明
1.拟合给定点集的直线
fitLine(Mat points, Mat line, int distType, double param, double reps, double aeps) | |
参数: | |
points | 输入的2D或3D点向量 |
line | 输出参数,表示拟合得到的直线的参数。在2D拟合的情况下,它应该是一个4个元素的向量(如Vec4f) - (vx,vy,x0,y0),其中(vx,vy)是与直线共线的归一化向量,(x0,y0)是直线上的点。在3D拟合的情况下,它应该是一个6个元素的向量(如Vec6f) - (vx,vy,vz,x0,y0,z0),其中(vx,vy,vz)是与直线共线的归一化向量,(x0,y0,z0)是直线上的点 |
distType | 距离度量方式,用于M估计。参见DIST_* |
param | 可选参数,对于某些距离类型,它表示数值参数C。如果为0,则选择最优值 |
reps | 足够精度下的半径(坐标原点到直线的距离) |
aeps | 对于角度的足够精度。对于reps和aeps,0.01是一个不错的默认值 |
拟合给定点集的直线,该函数通过最小化
∑
i
ρ
(
r
i
)
\sum_i \rho(r_i)
i∑ρ(ri)
来拟合一条直线到2D或3D点集,其中
r
i
是第
i
t
h
个点到线和
ρ
(
r
)
的距离函数
,
r_i 是第 i^{th}个点到线和 \rho(r) 的距离函数,
ri是第ith个点到线和ρ(r)的距离函数,
可以是以下之一:
DIST_L2
ρ
(
r
)
=
r
2
/
2
(最简单且最快的最小二乘法方法)
\rho (r) = r^2/2 \quad \text{(最简单且最快的最小二乘法方法)}
ρ(r)=r2/2(最简单且最快的最小二乘法方法)
DIST_L1
ρ
(
r
)
=
r
\rho (r) = r
ρ(r)=r
DIST_L12
ρ
(
r
)
=
2
⋅
(
1
+
r
2
2
−
1
)
\rho (r) = 2 \cdot ( \sqrt{1 + \frac{r^2}{2}} - 1)
ρ(r)=2⋅(1+2r2−1)
DIST_FAIR
ρ
(
r
)
=
C
2
⋅
(
r
C
−
log
(
1
+
r
C
)
)
其中
C
=
1.3998
\rho \left (r \right ) = C^2 \cdot \left ( \frac{r}{C} - \log{\left(1 + \frac{r}{C}\right)} \right ) \quad \text{其中} \quad C=1.3998
ρ(r)=C2⋅(Cr−log(1+Cr))其中C=1.3998
DIST_WELSCH
ρ
(
r
)
=
C
2
2
⋅
(
1
−
exp
(
−
(
r
C
)
2
)
)
其中
C
=
2.9846
\rho \left (r \right ) = \frac{C^2}{2} \cdot \left ( 1 - \exp{\left(-\left(\frac{r}{C}\right)^2\right)} \right ) \quad \text{其中} \quad C=2.9846
ρ(r)=2C2⋅(1−exp(−(Cr)2))其中C=2.9846
DIST_HUBER
ρ
(
r
)
=
{
r
2
2
if
r
l
t
;
C
C
⋅
(
r
−
C
2
)
其它
其中
C
=
1.345
\rho (r) = \begin{cases} \frac{r^2}{2} & \text{if } r < C \\ C \cdot (r - \frac{C}{2}) & \text{其它} \end{cases} \quad \text{其中} \quad C = 1.345
ρ(r)={2r2C⋅(r−2C)if r其它lt;C其中C=1.345
根据自身需求选择合适的距离计算类型,此处仅给出使用示例
//创建矩阵
Mat mat = new Mat(300,300, CvType.CV_8UC3);
mat.setTo(new Scalar(255,255,255));
//创建点集
MatOfPoint points = new MatOfPoint();
points.fromArray(new Point(30,30),
new Point(55,30),
new Point(110,88),
new Point(150,200),
new Point(100,250)
);
Mat line = new Mat();
//拟合直线
Imgproc.fitLine(points,line,Imgproc.DIST_L1,0,0.01,0.01);
//获取拟合结果
double vx = line.get(0, 0)[0];
double vy = line.get(1, 0)[0];
double x = line.get(2, 0)[0];
double y = line.get(3, 0)[0];
System.out.println("line.dump() = \n" + line.dump());
//绘制点集
for (Point point : points.toArray()) {
Imgproc.circle(mat,point,2,new Scalar(0,0,255),-1,Imgproc.LINE_AA);
}
//根据拟合结果绘制直线
Point p1 = new Point(x,y);
Point p2 = new Point(x+200*vx,y+200*vy);
Imgproc.line(mat,p1,p2,new Scalar(255,0,0),2);
HighGui.imshow("mat",mat);
HighGui.waitKey();
结果:
二、拟合椭圆
1.最佳拟合
该函数的作用是在给定的2D点集上找到一个最佳拟合
的旋转椭圆,并返回表示该椭圆的 RotatedRect 对象
fitEllipse(MatOfPoint2f points) | |
参数: | |
points | 一个包含2D点的 MatOfPoint2f 对象 |
public static void main(String[] args) {
// 创建一个二维点集
MatOfPoint2f points = new MatOfPoint2f(
new Point(100, 50),
new Point(150, 100),
new Point(200, 50),
new Point(150, 0),
new Point(100, 50)
);
// 调用fitEllipse方法拟合椭圆
RotatedRect rotatedRect = Imgproc.fitEllipse(points);
// 打印拟合的椭圆信息
System.out.println("Center: " + rotatedRect.center);
System.out.println("Size: " + rotatedRect.size);
System.out.println("Angle: " + rotatedRect.angle);
}
请自行绘制查看结果
fitEllipseDirect(Mat points) | |
参数: | |
points | 一个包含2D点的 MatOfPoint2f 对象 |
这里使用了由 Fitzgibbon1999 提出的直接最小二乘法(Direct)算法
public static void main(String[] args) {
// 假设有一组点集合,这里只是举例,实际应用中需要替换为真实数据
Point[] pointsArray = {
new Point(100, 50),
new Point(150, 100),
new Point(200, 50),
new Point(150, 0),
new Point(100, 50)
};
MatOfPoint points = new MatOfPoint(pointsArray);
// 调用 fitEllipseAMS 方法拟合椭圆
RotatedRect rotatedRect = Imgproc.fitEllipseDirect(points);
// 输出椭圆的信息
System.out.println("Center: " + rotatedRect.center);
System.out.println("Size: " + rotatedRect.size);
System.out.println("Angle: " + rotatedRect.angle);
//绘制
Mat mat = new Mat(300,300, CvType.CV_8UC3,new Scalar(255,255,255));
List pts = new ArrayList<>();
pts.add(points);
Imgproc.polylines(mat,pts,true,new Scalar(255,0,0));
Imgproc.ellipse(mat,rotatedRect,new Scalar(0,255,0));
//显示
HighGui.imshow("mat",mat);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
}
2.最小面积拟合
fitEllipseAMS根据输入的点集拟合出一个最小面积
的椭圆,采用 AMS (Algebraic Method) 算法. 该函数支持更多类型的points
fitEllipse(MatOfPoint2f points) | |
参数: | |
points | 输入的点坐标集合 |
// 假设有一组点集合,这里只是举例,实际应用中需要替换为真实数据
Point[] pointsArray = {
new Point(100, 50),
new Point(150, 100),
new Point(200, 50),
new Point(150, 0),
new Point(100, 50)
};
MatOfPoint points = new MatOfPoint(pointsArray);
// 调用 fitEllipseAMS 方法拟合椭圆
RotatedRect rotatedRect = Imgproc.fitEllipseAMS(points);
// 输出椭圆的信息
System.out.println("Center: " + rotatedRect.center);
System.out.println("Size: " + rotatedRect.size);
System.out.println("Angle: " + rotatedRect.angle);
//绘制
Mat mat = new Mat(300,300,CvType.CV_8UC3,new Scalar(255,255,255));
List pts = new ArrayList<>();
pts.add(points);
Imgproc.polylines(mat,pts,true,new Scalar(255,0,0));
Imgproc.ellipse(mat,rotatedRect,new Scalar(0,255,0));
//显示
HighGui.imshow("mat",mat);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
万水千山总是情,本栏完全公开免费。点赞+收藏过30,瞬更下一篇 | |
上一篇:Imgproc之图形绘制 | 下一篇:边缘检测 |