python - Python中2D平面中点的透视变换
问题描述
我有以下图像,其中牛舍的四个角是 -[(x1,y1), (x2,y2), (x3,y3), (x4,y4)]。捕捉图像的相机位于 (x1,y1) 和 (x4,y4) 的中间。由于 (x3,y3) 和 (x2,y2) 距离相机较远,因此在图像中,x1-x4 不等于 x2-x3。
我需要将外壳重新投影到一个 2d 矩形平面中,其角为 [(x1,y1), (x2,y2), (x3,y3), (x4,y4)] 并且不太可能是原始图像,这个新平面将具有x1-x4 = x2-x3。有没有可行的选择来做到这一点?OpenCV 带有只能应用于图像的透视变换功能。但是,在这种情况下,我将在原始平面上有一些牛的 x,y 位置,这些位置需要转换并绘制到矩形 2d 平面中以显示牛的位置。
解决方案
这个问题更多的是线性代数而不是编程。你在一个简单的四边形上有一个线性变换。数学更简单,因为您有两条平行于图像边缘的边缘。
首先,我们需要重新定义一些符号:例如,您使用 (x2, y2) 来指代发布图像上的两个点,以及转换后图像左上角的所需位置。我将通过将转换后的点声明为 A = (x1, y2) 和 B = (x4, y3) 来简化这一点:我们正在水平拉伸梯形的顶部以形成一个矩形。
另请注意,从一开始就 y1=y4 和 y2=y3;这简化了计算。可视化重叠的新旧图像,Q
内部有一个问题点,其坐标标记在边界上。我们需要在“拉伸”之后找到Q
的变换点的一般方程。R
我还标记了原始图像的中位数,MN
. 这条线上的点在拉伸过程中不会移动。作为旁注,沿底部边缘的点1-4
不会移动。外边缘的点2-3
移动最多。让y 坐标与(and, later, )具有相同 y 坐标的C
边缘上的点;让成为 上的对应点。1-2
Q
R
D
MN
A-----2-----M-----3---B
| |
Qy CR Q D |
| |
| |
1----Rx-Qx-N----------4
我们只需要按比例计算所选点移动的数量。寻找 和 的方程MN
是1-2
众所周知的(两点公式)。代Qy
入这些方程中的每一个以获得Cx
和Dx
。
“拉伸”因素,在转换CD
为(x1, Qy) D
是它们的长度比:(Dx-x1) / (Dx-Cx)
。 Q
将根据其与 D: 的距离向左移动该拉伸因子的一部分(Dx-Qx) / (Dx-x1)
。将它们相乘以获得 Q 移动的距离。减去那个数额Qx
得到Rx
。
是的,您现在在最终的组合方程中有几个常数:x1、x2、x3、x4、y1、y2。您还有变量 Qx 和 Qy。这是应该的。这为您提供了一个通用方程来转换图像中任何点的 Qx => Rx。
如果您也计划垂直拉伸,则相同的比例将适用于垂直方向。我建议你一次做一个拉伸;这将保持数学模块化:在不同的阶段更容易检查和调试。
这会让你感动吗?
D
不会动;
推荐阅读
- javascript - 我必须将令牌存储在 cookie 或本地存储或会话中吗?
- mysql - 查询制造商过去一年的收入
- express - 如何在对 koa 服务器的同一个请求中立即设置和使用 cookie?
- python - 如何在通过逆 FFT 重建信号时提取时域信息
- c++ - 警告:ISO C++ 禁止将静态“constexpr char*”数据成员的字符串常量转换为“char*”
- r - R Shiny:用户更改输入后更新数据框
- python - 如何在不同范围之间的熊猫数据框中的列上应用多个规范化
- r - 如何使用具有已知日期格式的因子级别来通知我的数据框的其余部分?
- rust - 如何在关联类型上定义特征界限?
- airflow - 触发的 DAG 无法从 TriggerDagRunOperator 获取参数