- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在使用 OpenCV 在 Python 和 C++ 中计算视频里程计的基本矩阵。我试图使两个实现中的代码完全相同。但是,我在这两个方面都得到了不同的结果。在 Python 中,它工作正常,而在 C++ 中,它显示完全错误的结果。下面是他们的代码和输出的部分示例(第一个在 Python 中,第二个在 C++ 中)
Python版本代码:
import os
import sys
import cv2
import numpy as np
import math
# Main Function
if __name__ == '__main__':
K = np.matrix([[522.4825, 0, 300.9989],
[0, 522.5723, 258.1389],
[0.0, 0.0, 1.0]])
img1 = cv2.imread(sys.argv[1] + ".jpg")
img2 = cv2.imread(sys.argv[2] + ".jpg")
# sift = cv2.SURF()
detector = cv2.FeatureDetector_create("SURF") # SURF, FAST, SIFT
descriptor = cv2.DescriptorExtractor_create("SURF") # SURF, SIFT
# kp1, des1 = sift.detectAndCompute(img1,None)
# kp2, des2 = sift.detectAndCompute(img2,None)
kp1 = detector.detect(img1)
kp2 = detector.detect(img2)
k1, des1 = descriptor.compute(img1,kp1)
k2, des2 = descriptor.compute(img2,kp2)
# BFMatcher with default params
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1,des2, k=2)
good = []
# Apply ratio test
for m,n in matches:
if m.distance < 0.7*n.distance:
good.append(m)
MIN_MATCH_COUNT = 10
if len(good)>MIN_MATCH_COUNT:
src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
F, mask = cv2.findFundamentalMat(src_pts, dst_pts, cv2.RANSAC, 5.0)
matchesMask = mask.ravel().tolist()
else:
print "Not enough matches are found - %d/%d" % (len(good),MIN_MATCH_COUNT)
matchesMask = None
print F
它的输出:
[[ -3.22706105e-07 1.12585581e-04 -2.86938406e-02]
[ -1.16307090e-04 -5.04244159e-07 5.60714444e-02]
[ 2.98839742e-02 -5.99974406e-02 1.00000000e+00]]
此处为 C++ 版本:
#include <iostream>
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/legacy/legacy.hpp>
using namespace std;
int main(int argc,char *argv[]) {
//Define intrinsic matrix
cv::Mat intrinsic = (cv::Mat_<double>(3,3) << 522.4825, 0, 300.9989,
0, 522.5723, 258.1389,
0, 0, 1);
// Read input images
string jpg1 = argv[1];
jpg1.append(".jpg");
string jpg2 = argv[2];
jpg2.append(".jpg");
cv::Mat image1 = cv::imread(jpg1,0);
cv::Mat image2 = cv::imread(jpg2,0);
if (!image1.data || !image2.data)
return 0;
// Display the images
// cv::namedWindow("Image 1");
// cv::imshow("Image 1",image1);
// cv::namedWindow("Image 2");
// cv::imshow("Image 2",image2);
// pointer to the feature point detector object
cv::Ptr<cv::FeatureDetector> detector = new cv::SurfFeatureDetector();
// pointer to the feature descriptor extractor object
cv::Ptr<cv::DescriptorExtractor> extractor = new cv::SurfDescriptorExtractor();
// Detection of the SURF features
vector<cv::KeyPoint> keypoints1, keypoints2;
detector->detect(image1,keypoints1);
detector->detect(image2,keypoints2);
// Extraction of the SURF descriptors
cv::Mat descriptors1, descriptors2;
extractor->compute(image1,keypoints1,descriptors1);
extractor->compute(image2,keypoints2,descriptors2);
// Construction of the matcher
cv::BruteForceMatcher<cv::L2<float> > matcher;
vector<vector<cv::DMatch> > matches;
vector<cv::DMatch> good_matches;
matcher.knnMatch(descriptors1, descriptors2, matches, 2);
for (vector<vector<cv::DMatch> >::iterator matchIterator= matches.begin();
matchIterator!= matches.end(); ++matchIterator) {
if ((*matchIterator)[0].distance < 0.7f * (*matchIterator)[1].distance) {
good_matches.push_back((*matchIterator)[0]);
}
}
// Convert keypoints into Point2f
vector<cv::Point2f> src_pts, dst_pts;
for (vector<cv::DMatch>::iterator it= good_matches.begin();
it!= good_matches.end(); ++it)
{
// Get the position of left keypoints
float x= keypoints1[it->queryIdx].pt.x;
float y= keypoints1[it->queryIdx].pt.y;
src_pts.push_back(cv::Point2f(x,y));
// Get the position of right keypoints
x= keypoints2[it->trainIdx].pt.x;
y= keypoints2[it->trainIdx].pt.y;
dst_pts.push_back(cv::Point2f(x,y));
}
// Compute F matrix using RANSAC
cv::Mat fundemental = cv::findFundamentalMat(
cv::Mat(src_pts),cv::Mat(dst_pts), // matching points
CV_FM_RANSAC, // RANSAC method
5.0); // distance
cout << fundemental << endl;
return 0;
}
及其输出:
[-4.310057787788129e-06, 0.0002459670522815174, -0.0413520716270485;
-0.0002531048911221476, -8.423657757958228e-08, 0.0974897887347238;
0.04566865455090797, -0.1062956485414729, 1]
我找不到原因。谁能告诉我为什么?
最佳答案
由于没有人回答,我将分享我的想法。您是只检查 F 中的数字,还是以某种方式应用它并观察到不正确的结果?正如@brandon-white 已经注意到的那样,浮点精度可能是原因之一。但实际上要复杂得多。
首先想到的是 C++ OpenCV 中的 AFAIK 使用它自己的矩阵和其他数学运算例程,而在 python 中尽可能使用 numpy。也许在幕后他们使用类似的算法/实现,但您仍然可能得到数值上不同的结果,尤其是在您处理歧义(特征向量分解、SVD 等)的情况下。
此外,您正在使用 RANSAC估计 F。为了处理(理论上)任何数量的异常值,RANSAC 从您的所有关键点中随机抽取一个小样本,并尝试找到满足某些约束的对。它多次执行此操作,然后选取最佳样本来计算最终模型。所以基本上你最终会得到不同的点来估计每次运行的 F,如果你适本地播种伪随机生成例程。但是,通常单应性和基本矩阵估计器使用更智能的方法,并且在找到最能满足约束的样本之后 - 满足该模型的所有点都将用于再次重新计算矩阵。这样你应该得到更一致的结果,如果 RANSAC 参数正常,理想情况下是相同的。我不确定它是否在 OpenCV 中使用,但我猜是。
最后还有degenerate cases ,其中无法完全估计 F - 平面运动的情况,当您的所有关键点都位于一个平面上(在 3D 世界中)时,以及纯粹的旋转相机运动。既然你说你的代码在 Python 中工作,这可能不是这种情况,但仍然是一个需要考虑的问题。
因此,如果您还没有这样做 - 尝试检查您在某些数据上获得的 F 矩阵,以确保您获得的结果确实不同。在那种情况下 - 某处应该有错误(诚然我还没有仔细检查你的代码)。
此外,显示您用于 F 计算的匹配项可能对调试有用,因为这会缩小您的代码可能表现不同的位置范围。
关于python - 使用 OpenCV 的 Python 和 C++ 计算基本矩阵的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34293973/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!