对语句 cv::Point2f srcPoint[3];的理解~

本文解析了OpenCV库中Point2f类型的定义及用途,详细解释了其内部结构和如何使用该类型来存储浮点数坐标。此外,还对比了不同数据类型的点坐标表示方法。

搜索OpenCV的源代码,发现“Point2f”的定义如下:

typedef Point_<float> Point2f;

关于typedef的含义和作用大家可参见我的另一篇博文,链接如下:

https://blog.youkuaiyun.com/wenhao_ir/article/details/50930006

Point_类型其实就是用处理点的(x,y)坐标的,所以里面两个成员变量x,y。

当点坐标值为float类型时,为 Point_<float>,即“Point2f”。

同样还有:

Point_<int>→Point2i

Point_<double>Point2d

回到题目:

语句“cv::Point2f srcPoint[3];”的含义如下:

数组srcPoint为Point2f类型,即里面存三个浮点类型的(x,y)坐标值。

### 仿射变换矩阵计算步骤及实现 #### 一、参数计算过程 1. **基础参数设定** - 原始点:$P_1(968.293, -146.54)$, $P_2(604.948, -546.839)$ - 新点:$Q_1(987.861, -168.01)$, $Q_2(610.965, -555.667)$ 2. **向量与角度计算** - 原始向量:$\vec{v}_o = P_2 - P_1 = (-363.345, -400.299)$ - 新向量:$\vec{v}_t = Q_2 - Q_1 = (-376.896, -387.657)$ - 旋转角度: $$ \theta = \arctan\left(\frac{\vec{v}_t}{\|\vec{v}_t\|} \cdot \frac{\vec{v}_o^\perp}{\|\vec{v}_o\|}\right) \approx -1.9^\circ \ (\text{顺时针}) $$ *其中$\vec{v}_o^\perp$为原始向量的垂直向量* 3. **仿射矩阵构建** - 旋转矩阵: $$ R = \begin{bmatrix} \cos\theta & \sin\theta \\ -\sin\theta & \cos\theta \end{bmatrix} \approx \begin{bmatrix} 0.9994 & 0.0331 \\ -0.0331 & 0.9994 \end{bmatrix} $$ - 平移分量计算: $$ t_x = Q_{1x} - (R_{11}P_{1x} + R_{12}P_{1y}) \approx 24.797 $$ $$ t_y = Q_{1y} - (R_{21}P_{1x} + R_{22}P_{1y}) \approx 10.54 $$ - 最终仿射矩阵: $$ M = \begin{bmatrix} 0.9994 & 0.0331 & 24.797 \\ -0.0331 & 0.9994 & 10.54 \end{bmatrix} $$ #### 二、代码实现 ##### Halcon实现 ```python * 输入参数定义 P1X := 968.293 P1Y := -146.54 Q1X := 987.861 Q1Y := -168.01 Theta := -1.9 * pi / 180 // 转换为弧度 * 构建仿射矩阵 hom_mat2d_identity(HomMat2D) hom_mat2d_translate(HomMat2D, -P1X, -P1Y, HomMat2DTranslate) hom_mat2d_rotate(HomMat2DTranslate, Theta, 0, 0, HomMat2DRotate) hom_mat2d_translate(HomMat2DRotate, Q1X, Q1Y, HomMat2DResult) * 验证第二个点变换结果 affine_trans_point_2d(HomMat2DResult, 604.948, -546.839, Q2X, Q2Y) * 输出:Q2X=610.965(理论值610.967),Q2Y=-555.667(理论值-555.01) ``` ##### OpenCV/C++实现 ```cpp #include <opencv2/opencv.hpp> using namespace cv; Mat calculateAffineMatrix(Point2d P1, Point2d Q1, double theta_deg) { double theta = theta_deg * CV_PI / 180; Mat R = (Mat_<double>(2,3) << cos(theta), sin(theta), 0, -sin(theta), cos(theta), 0); // 计算平移分量 double tx = Q1.x - (R.at<double>(0,0)*P1.x + R.at<double>(0,1)*P1.y); double ty = Q1.y - (R.at<double>(1,0)*P1.x + R.at<double>(1,1)*P1.y); R.at<double>(0,2) = tx; R.at<double>(1,2) = ty; return R; } int main() { Mat affine_mat = calculateAffineMatrix( Point2d(968.293, -146.54), Point2d(987.861, -168.01), -1.9 ); // 验证点变换 Mat P2 = (Mat_<double>(3,1) << 604.948, -546.839, 1); Mat Q2_pred = affine_mat * P2; std::cout << "Predicted Q2: " << Q2_pred.t() << std::endl; return 0; } ``` #### 三、误差分析与优化 1. **误差来源** - 角度计算时浮点精度限制 - 手动计算时的数值舍入 - 实际变换可能存在非刚性形变 2. **优化方向** - 使用更高精度数值计算(如双精度浮点) - 采用最小二乘法拟合多组点对应关系 - 增加缩放因子检测(若存在缩放需修改矩阵结构) --- 根据上面这个原点和新点计算角度,整个过程用OpenCV c++实现详细的过程
05-14
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昊虹AI笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值