如何将旋转后图像上的点坐标转换为容器坐标系下的坐标
解决思路
核心问题是你之前做旋转变换时,没有计算「不裁剪旋转导致的图像原点偏移」,只对点本身做了旋转,没有校正坐标系的偏移。按以下步骤处理即可:
1 基础坐标变换流程
你从EmguCV拿到的编码中心是**原图像坐标系(左上角为原点,x右y下)**下的坐标,要得到相对于容器的坐标,需要按顺序做4步变换:
- 先把原坐标平移到「以原图像中心点为原点」的临时坐标系
- 对临时坐标做旋转变换
- 把旋转后的坐标平移到「以旋转后新图像左上角为原点」的坐标系
- 最后应用缩放比例,得到最终的容器坐标系下的编码中心坐标
2 直接可用的代码实现
你可以直接用C#自带的Matrix类完成变换,不用手动计算三角函数,避免出错:
using System.Drawing; using System.Drawing.Drawing2D; // 配置参数 float originImgW = 2448f; float originImgH = 2048f; float rotateAngle = -120f; // 你的旋转角度 float scale = 3f; // 缩放比例 PointF codeOriginPoint = new PointF(x0, y0); // EmguCV拿到的原始编码中心坐标 // 计算不裁剪旋转后的新图像尺寸 float radian = (float)(rotateAngle * Math.PI / 180); float rotatedImgW = (float)(originImgW * Math.Abs(Math.Cos(radian)) + originImgH * Math.Abs(Math.Sin(radian))); float rotatedImgH = (float)(originImgW * Math.Abs(Math.Sin(radian)) + originImgH * Math.Abs(Math.Cos(radian))); // 构建完整变换矩阵 Matrix transformMatrix = new Matrix(); transformMatrix.Translate(-originImgW / 2, -originImgH / 2); // 平移到原图像中心为原点 transformMatrix.Rotate(rotateAngle); // 应用旋转 transformMatrix.Translate(rotatedImgW / 2, rotatedImgH / 2); // 平移到旋转后图像左上角为原点 transformMatrix.Scale(scale, scale); // 应用缩放 // 执行坐标变换 PointF[] points = new PointF[] { codeOriginPoint }; transformMatrix.TransformPoints(points); PointF codeContainerPoint = points[0]; // 最终得到编码中心相对于容器原点的坐标
3 后续滚动居中计算
拿到codeContainerPoint后,根据ScrollView的视口宽(viewW)高(viewH)计算滚动偏移即可:
- 滚动X轴偏移:
scrollX = Math.Max(0, codeContainerPoint.X - viewW / 2) - 滚动Y轴偏移:
scrollY = Math.Max(0, codeContainerPoint.Y - viewH / 2)
注意事项
- ScrollView的内容宽高要设置为
rotatedImgW * scale和rotatedImgH * scale,保证滚动范围正确,就算识别不到三个点,用户也可以手动滑动查看全图 - 如果你的旋转是通过UI控件的Transform属性实现,而非预先生成旋转后的图像,只需要把上述矩阵的变换顺序反过来,做逆变换即可得到正确坐标
内容的提问来源于stack exchange,提问作者Guillermo Espert
相关产品推荐
相关产品推荐

