提问人:Danil Valov 提问时间:7/5/2023 最后编辑:Danil Valov 更新时间:7/5/2023 访问量:61
cv::solve 与 DECOMP_SVD 一起使用 C++ 的结果与 Python 和 Java(Kotlin) 不同
cv::solve with DECOMP_SVD using C++ has different results from Python and Java(Kotlin)
问:
我在我的项目中发现了一个有趣的问题,即 SVD(奇异值分解)的不同结果。 我需要通过线(4 点)找到交叉点。 我有 2 条垂直线和 2 条水平线。
我为 Python 编写了以下代码,它可以正常工作:
a = numpy.array([
[0.99773484, -0.06726905],
[0.02908471, 0.9995769]
])
b = numpy.array([
[180.0],
[264.66666]
])
_, (x0, y0) = cv2.solve(a, b, flags=cv2.DECOMP_SVD)
# x0 = 197.87232204
# y0 = 259.02119276
此外,我使用 Kotlin 编写了相同的代码,它也可以正常工作:
val a = Mat.zeros(2, 2, CvType.CV_32F)
a.put(0, 0, 0.99773484)
a.put(0, 1, -0.06726905)
a.put(1, 0, 0.02908471)
a.put(1, 1, 0.9995769)
val b = Mat.zeros(2, 1, CvType.CV_32F)
b.put(0, 0, 180.0)
b.put(1, 0, 264.66666)
val linearFit = Mat()
Core.solve(a, b, linearFit, Core.DECOMP_SVD)
val x0 = linearFit.get(0, 0)[0]
val y0 = linearFit.get(1, 0)[0]
// x0 = 197.87232971191406
// y0 = 259.02117919921875
但是当我使用 C++ 编写这段代码时,我得到了不同的结果:
cv::Mat a = cv::Mat::zeros(2, 2, CV_32F);
a.at<float>(0, 0) = 0.99773484;
a.at<float>(0, 1) = -0.06726905;
a.at<float>(1, 0) = 0.02908471;
a.at<float>(1, 1) = 0.9995769;
cv::Mat b = cv::Mat::zeros(2, 1, CV_32F);
b.at<float>(0, 0) = 180.0;
b.at<float>(1, 0) = 264.66666;
cv::Mat linearFit;
cv::solve(a, b, linearFit, cv::DECOMP_SVD);
double x0 = linearFit.at<cv::Vec3b>(0, 0)[0];
double y0 = linearFit.at<cv::Vec3b>(1, 0)[0];
// x0 = 81.000000
// y0 = 182.000000
这是我的语法问题还是 iOS 的 opencv2.framework 的问题? 我在 opencv2.framework v.3.4.19 和 v.4.1.0 上进行了测试。
P.S. 我在这个答案中得到的查找交叉点的函数:https://stackoverflow.com/a/46572063
答:
0赞
Danil Valov
7/5/2023
#1
ChatGPT 帮助了我。 正确的语法是:
double x0 = linearFit.at<float>(0, 0);
double y0 = linearFit.at<float>(1, 0);
1赞
Christoph Rackwitz
7/5/2023
#2
类型问题。
Vec3b
表示 的三个值。uint8_t
cv::solve()
可能返回 () 值。它可能返回了 ,即单通道,或 ,即三通道。float
CV_32F
CV_32FC1
CV_32FC3
如果生成的 Mat 是 3 通道,则可能需要使用 。如果没有,那将是正确的。Vec3f
float
如果它不是 32 位浮点数,则可能需要不同的类型。 是一种可能性。CV_64F
评论