【问题标题】:When Using estimateRigidTransform() in C++ with OpenCV, Rotation is Correct but Translation is Incorrect在 C++ 中与 OpenCV 一起使用 estimateRigidTransform() 时,旋转正确但平移不正确
【发布时间】:2018-12-10 12:17:03
【问题描述】:

我尝试在图像之间转换的图像中有两组点。为此,我使用了 OpenCV 的函数 estimateRigidTransform()。使用生成的单应矩阵(包含旋转矩阵和平移向量),我使用 OpenCV 的函数 warpAffine() 来转换图像。然后我在一个新窗口中显示这个转换后的图像。 我的代码如下:

cv::namedWindow("Transformed Blue A", CV_WINDOW_AUTOSIZE);
cv::Mat mask_image, warp_matrix;
bool fullAffine = false;

homography_matrix = estimateRigidTransform(black_A_points, blue_A_points, fullAffine);
warpAffine(image, mask_image, homography_matrix, image.size());
cv::imshow("Transformed Blue A", mask_image);

black_A_pointsblue_A_points 是包含四个 Point2f 值的向量(这些是在它们之间转换的坐标)。使用 warpAffine() 进行转换后,我将在新窗口中显示转换后的图像。

结果如下: 要转换的图像

转换后的图像

我使用 'A's 的角作为特征点在它们之间进行转换(因此为什么在它们上面画了红线和绿点以直观地确认我已经正确找到了这些点)。我在窗口中手动移动了图像,这样我可以更好地看到它并且旋转在视觉上是正确的。但是,我希望在显示原始图像(转换到该位置)的窗口中看到黑色“A”所在的蓝色“A”。

单应矩阵为:[-0.7138494567933336, 0.7193648090910907, 40.48675760211488; -0.7193648090910907,-0.7138494567933336,849.4044159834291]

因此旋转矩阵为:[-0.7138494567933336, 0.7193648090910907; -0.7193648090910907,-0.7138494567933336]

翻译向量为:[40.48675760211488; 849.4044159834291]

我是否正确使用了单应矩阵?我是否需要对单应矩阵进行数学运算才能在窗口坐标中使用它(因为在当前坐标系中是错误的)?还是我使用的 OpenCV 函数有误?

我还尝试了 OpenCV 函数 findHomography() 和 getAffineTransform() 但这两个都产生了同样的问题。

非常感谢您的宝贵时间。感谢您的帮助。

更新:

黑A角:

[(495, 515), (479, 497), (428, 646), (345, 565)]

蓝色A角:

[(57, 125), (57, 151), (200, 80), (200, 198)]

【问题讨论】:

  • 您可以编辑问题以包含点坐标吗?黑色和蓝色。
  • 嗨@api55。非常感谢您的回复。在过去的半个小时里,我一直在尝试编辑问题,但每次它都说格式化代码存在问题,即使我从未接触过代码块。无论如何,这就是你所要求的。 >黑色'A'的角像素坐标为:[495, 515; 479, 497; 428, 646; 345, 565] >蓝色'A'的角像素坐标为:[57, 125; 57, 151; 200, 80; 200, 198]
  • 我为你做了更新 :) 我会尝试代码,然后如果我发现有什么问题我可能会给出答案。可以更新原图吗?您提供的原始图像是屏幕截图
  • 干杯兄弟!你是怎么做到的???哈哈哈每次我尝试保存更改时,它一直说“代码”的格式不正确。无论如何,感谢您到目前为止的帮助!
  • @api55,这次它让我编辑,所以第一个图像链接应该是原始图像。我不知道如何判断它是否正确更新。

标签: c++ opencv


【解决方案1】:

用你的数字测试后我发现了问题:)

您将点用作 (y,x) 而不是 (x,y)。我尝试了您的原始数字,并重现了与您相同的结果。然后我做了一个小脚本在python中测试它,反转坐标:

import numpy as np
import cv2

# loads iamge and data
img = cv2.imread("test.png")
pointsBlack = np.array([(495, 515), (479, 497), (428, 646), (345, 565)])
pointsBlue = np.array([(57, 125), (57, 151), (200, 80), (200, 198)])

# inverts the points (y,x) is (x,y)
a = np.array([(x[1], x[0]) for x in pointsBlack])
b = np.array([(x[1], x[0]) for x in pointsBlue])

res = cv2.estimateRigidTransform(a, b, True)
print(res)

imgWarped = cv2.warpAffine(img, res, img.shape[1::-1])
cv2.imshow("warped", imgWarped)
cv2.imshow("s", img)
cv2.waitKey(0)

这样的结果是:

[[-7.80571429e-01 -7.46857143e-01  8.96688571e+02]
 [ 6.53714286e-01 -7.35428571e-01  8.43742857e+01]]

图像看起来像:

在 C++ 中,cv::Point2f 构造函数是 cv::Point2f(x, y)。您正在通过 (y,x)。不知道你是如何找到这些点的,但它可能会与 cv::Mat::at<T>(row, col) 函数混淆,该函数需要第一行和列,或者在笛卡尔坐标中,y 然后 x。

【讨论】:

  • 嗨@api55,非常感谢您的回复。很抱歉这么久才回复您,我只是有机会测试您所说的内容,效果很好!你对我对矩阵和笛卡尔坐标系感到困惑,我觉得很傻,我自己不这么想。无论如何,再次感谢!
  • @badcoder 不用担心,这是 OpenCV 中的一个常见错误,因为他们在某些事情中使用笛卡尔坐标,而在其他函数中使用矩阵坐标。
猜你喜欢
  • 1970-01-01
  • 2012-12-14
  • 1970-01-01
  • 2016-05-11
  • 2013-04-29
  • 1970-01-01
  • 1970-01-01
  • 2019-02-28
  • 1970-01-01
相关资源
最近更新 更多