专栏简介 | ||
💒个人主页 | 📖心灵鸡汤📖 我们唯一拥有的就是今天,唯一能把握的也是今天 建议把本文当作笔记来看,据说专栏目录里面有相应视频🤫 | 📰专栏目录 |
Imgproc之点集拟合
- 一、拟合直线
- 1.字段
- 2.方法说明
- 二、拟合椭圆
- 1.最佳拟合
- 2.最小面积拟合
一、拟合直线
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是一个不错的默认值 |
拟合给定点集的直线.
根据自身需求选择合适的距离计算类型,此处仅给出使用示例
//创建矩阵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之图形绘制 | 下一篇: Imgproc之图像阈值化 |