我想在x,y,z米相机上增加一个虚拟对象.OpenCV有摄像机校准功能,但我不明白我究竟能以米为单位给出坐标
我尝试在Unity中模拟相机,但没有得到预期的结果.
我按如下方式设置投影矩阵,并在z = 2.415 + 0.5处创建单位立方体.2.415是眼睛和投影平面之间的距离(针孔摄像机模型)由于立方体的面位于前剪裁平面,它的尺寸是单位,它不应覆盖整个视口吗?
Matrix4x4 m = new Matrix4x4();
m[0, 0] = 1;
m[0, 1] = 0;
m[0, 2] = 0;
m[0, 3] = 0;
m[1, 0] = 0;
m[1, 1] = 1;
m[1, 2] = 0;
m[1, 3] = 0;
m[2, 0] = 0;
m[2, 1] = 0;
m[2, 2] = -0.01f;
m[2, 3] = 0;
m[3, 0] = 0;
m[3, 1] = 0;
m[3, 2] = -2.415f;
m[3, 3] = 0;
Run Code Online (Sandbox Code Playgroud) 我想估计采用两种不同的方法相对位置:solvePNP 和recoverPose,和好像[R矩阵是看起来不错相对于一定的误差,但翻译载体是完全不同的.我究竟做错了什么?通常,我需要使用两种方法找到从第1帧到第2帧的相对位置.
cv::solvePnP(constants::calibration::rig.rig3DPoints, corners1,
cameraMatrix, distortion, rvecPNP1, tvecPNP1);
cv::solvePnP(constants::calibration::rig.rig3DPoints, corners2,
cameraMatrix, distortion, rvecPNP2, tvecPNP2);
Mat rodriguesRPNP1, rodriguesRPNP2;
cv::Rodrigues(rvecPNP1, rodriguesRPNP1);
cv::Rodrigues(rvecPNP2, rodriguesRPNP2);
rvecPNP = rodriguesRPNP1.inv() * rodriguesRPNP2;
tvecPNP = rodriguesRPNP1.inv() * (tvecPNP2 - tvecPNP1);
Mat E = findEssentialMat(corners1, corners2, cameraMatrix);
recoverPose(E, corners1, corners2, cameraMatrix, rvecRecover, tvecRecover);
Run Code Online (Sandbox Code Playgroud)
输出:
solvePnP: R:
[0.99998963, 0.0020884471, 0.0040569459;
-0.0020977913, 0.99999511, 0.0023003994;
-0.0040521105, -0.0023088832, 0.99998915]
solvePnP: t:
[0.0014444492; 0.00018377086; -0.00045027508]
recoverPose: R:
[0.9999900052294586, 0.0001464890570028249, 0.004468554816042664;
-0.0001480011106435358, 0.9999999319097322, 0.0003380476328946509;
-0.004468504991498534, -0.0003387056052618761, 0.9999899588204144]
recoverPose: …Run Code Online (Sandbox Code Playgroud) opencv linear-algebra computer-vision pose-estimation opencv-solvepnp
我正在使用函数solvePnP通过视觉标记来估计机器人的姿势.有时我在两个连续帧中得到错误的结果.在文件problem.cpp中,您可以看到其中一个结果.
点集对应于两个连续帧中的相同标记.它们之间的差异很小,solvePnP的结果非常不同,但只在旋转矢量中.翻译矢量还可以.
这种情况每30帧大约发生一次.我用相同的数据测试了CV_ITERATIVE和CV_P3P方法,它们返回相同的结果.
这是问题的一个例子:
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(){
vector<Point2f> points1, points2;
//First point's set
points1.push_back(Point2f(384.3331f, 162.23618f));
points1.push_back(Point2f(385.27521f, 135.21503f));
points1.push_back(Point2f(409.36746f, 139.30315f));
points1.push_back(Point2f(407.43854f, 165.64435f));
//Second point's set
points2.push_back(Point2f(427.64938f, 158.77661f));
points2.push_back(Point2f(428.79471f, 131.60953f));
points2.push_back(Point2f(454.04532f, 134.97353f));
points2.push_back(Point2f(452.23096f, 162.13156f));
//Real object point's set
vector<Point3f> object;
object.push_back(Point3f(-88.0f,88.0f,0));
object.push_back(Point3f(-88.0f,-88.0f,0));
object.push_back(Point3f(88.0f,-88.0f,0));
object.push_back(Point3f(88.0f,88.0f,0));
//Camera matrix
Mat cam_matrix = Mat(3,3,CV_32FC1,Scalar::all(0));
cam_matrix.at<float>(0,0) = 519.0f;
cam_matrix.at<float>(0,2) = 320.0f;
cam_matrix.at<float>(1,1) = 522.0f;
cam_matrix.at<float>(1,2) = 240.0f;
cam_matrix.at<float>(2,2) = 1.0f;
//PnP
Mat rvec1i,rvec2i,tvec1i,tvec2i;
Mat rvec1p,rvec2p,tvec1p,tvec2p;
solvePnP(Mat(object),Mat(points1),cam_matrix,Mat(),rvec1i,tvec1i,false,CV_ITERATIVE); …Run Code Online (Sandbox Code Playgroud) 我们正在开发一个 AR 应用程序,其中需要将对象的 3D 模型叠加到对象的视频流上。Unity 场景包含 3D 模型,并且相机正在拍摄 3D 对象。相机姿势最初未知。
\n\n\xe2\x96\xb6我们尝试过的
\n\n我们没有找到一个好的解决方案来直接在 Unity 中估计相机位姿。因此,我们使用了OpenCV,它提供了广泛的计算机视觉函数库。特别是,我们找到Aruco 标签,然后将其匹配的 3D-2D 坐标传递给solvePnp.
solvePnp返回与现实相符最多几厘米的相机位置。我们还验证了较低的重投影误差。
每个使用过的标签角都会被重新投影并在图像上显示为红点。如您所见,差异很小。
\n\n这些结果看起来不错,应该足以满足我们的用例。\n因此,我们根据现实和 OpenCV 验证相机姿势。
\n\n\xe2\x96\xb6问题
\n\n然而,当将相机放置在 Unity 场景中的估计姿势时,3D 对象无法很好地对齐。
\n\n\n\n在此 Unity 屏幕截图中,您可以看到虚拟(Unity 对象)绿色标签的视图与视频源中的真实标签不匹配。
\n\n\xe2\x96\xb6可能的根本原因
\n\n我们确定了可以解释 Unity 和 OpenCV 之间不匹配的不同可能根本原因:
\n\n\n\n …opencv computer-vision unity-game-engine pose-estimation opencv-solvepnp
我正在为我的游戏制作姿势估计脚本。然而,即使没有 fps 限制,它也能以 20-30 fps 运行,并且不会使用整个 CPU。它也没有使用整个 GPU。有人能帮我吗?
\n以下是播放舞蹈视频时的资源使用情况:https://i.stack.imgur.com/6L8Rj.jpg
\n这是我的代码:
\nimport cv2\nimport mediapipe as mp\nimport time\n\ninFile = \'/dev/video0\'\n\ncapture = cv2.VideoCapture(inFile)\nFramesVideo = int(capture.get(cv2.CAP_PROP_FRAME_COUNT)) # Number of frames inside video\nFrameCount = 0 #\xc2\xa0Currently playing frame\nprevTime = 0\n\n# some objects for mediapipe\nmpPose = mp.solutions.pose\nmpDraw = mp.solutions.drawing_utils\npose = mpPose.Pose()\n\nwhile True:\n FrameCount += 1\n #read image and convert to rgb\n success, img = capture.read()\n imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n \n #process image\n results = pose.process(imgRGB)\n\n if results.pose_landmarks:\n mpDraw.draw_landmarks(img, results.pose_landmarks, mpPose.POSE_CONNECTIONS)\n #get landmark …Run Code Online (Sandbox Code Playgroud) python artificial-intelligence python-3.x pose-estimation mediapipe
我正在尝试使用OpenCV通过SIFT特征跟踪,FLANN匹配以及基本矩阵和基本矩阵的后续计算来估计摄像机相对于另一摄像机的一个姿势。分解基本矩阵后,我检查退化的配置并获得“正确的” R和t。
问题是,它们似乎永远都不对。我包括几个图像对:
结果
结果
在第二种情况下,平移矢量似乎高估了Y方向的运动,而低估了X方向的运动。将旋转矩阵转换为Euler角时,在两种情况下均得出错误的结果。许多其他数据集也会发生这种情况。我尝试过在RANSAC,LMEDS等之间切换基本矩阵计算技术,现在使用RANSAC进行此操作,并且仅使用8点法的内点进行第二次计算。更改特征检测方法也无济于事。对极线似乎是正确的,并且基本矩阵满足x'.Fx = 0
我在这里错过根本上是错的东西吗?假设程序正确理解了对极几何,那么可能发生什么导致完全错误的姿势?我正在检查以确保点都位于两个摄像头的前面。任何想法/建议都将非常有帮助。谢谢!
编辑:尝试使用相同技术,将两个不同的校准摄像机间隔开;并将基本矩阵计算为K2'.F.K1,但平移和旋转仍然相去甚远。
参考代码
import cv2
import numpy as np
from matplotlib import pyplot as plt
# K2 = np.float32([[1357.3, 0, 441.413], [0, 1355.9, 259.393], [0, 0, 1]]).reshape(3,3)
# K1 = np.float32([[1345.8, 0, 394.9141], [0, 1342.9, 291.6181], [0, 0, 1]]).reshape(3,3)
# K1_inv = np.linalg.inv(K1)
# K2_inv = np.linalg.inv(K2)
K = np.float32([3541.5, 0, 2088.8, 0, 3546.9, 1161.4, 0, 0, 1]).reshape(3,3)
K_inv = np.linalg.inv(K)
def in_front_of_both_cameras(first_points, second_points, rot, trans): …Run Code Online (Sandbox Code Playgroud) python opencv computer-vision rotational-matrices pose-estimation
我有一个面向棋盘的相机。我知道点的世界 3d 位置以及相机图像上相应投影点的 2d 位置。所有世界点都属于同一平面。我使用solvePnP:
Matx33d camMat;
Matx41d distCoeffs;
Matx31d rvec;
Matx31d tvec;
std::vector<Point3f> objPoints;
std::vector<Point2f> imgPoints;
solvePnP(objPoints, imgPoints, camMat, distCoeffs, rvec, tvec);
Run Code Online (Sandbox Code Playgroud)
然后我可以使用 projectPoints 从 3d 世界点到 2d 图像点:
std::vector<Point2f> projPoints;
projectPoints(objPoints, rvec, tvec, camMat, distCoeffs, projPoints);
Run Code Online (Sandbox Code Playgroud)
projPoints 非常接近 imgPoints。
如何使用与属于同一平面的 3d 世界点相对应的屏幕点进行相反的操作。我知道从单一的角度来看,不可能重建 3d 位置,但在这里我在同一平面上,所以这确实是一个 2d 问题。我可以计算反向旋转矩阵以及反向平移向量,但是我该如何进行呢?
Matx33d rot;
Rodrigues(rvec, rot);
Matx33d camera_rotation_vector;
Rodrigues(rot.t(), camera_rotation_vector);
Matx31d camera_translation_vector = -rot.t() * tvec;
Run Code Online (Sandbox Code Playgroud) 我已经为一个问题苦苦挣扎了一个星期,我无法像这张图片中的左脸一样将一张脸从非正面旋转到同一张图片中的右脸一样的正面。
1)。我在learnopencv网站上使用了一个关于delaunay的教程来获取左面的所有三角形(大约138个三角形),如下所示:
...
triangle num 4: [100, 383] | [120, 374] | [112, 385]
triangle num 5: [120, 374] | [100, 383] | [92, 345]
triangle num 6: [136, 396] | [137, 379] | [151, 394]
triangle num 7: [137, 379] | [136, 396] | [118, 395]
triangle num 8: [92, 345] | [86, 414] | [80, 451]
triangle num 9: [86, 414] | [92, 345] | [100, 383]
triangle num 10: [86, 414] | [100, 383] | …Run Code Online (Sandbox Code Playgroud) 我对OpenCV相机姿态估计进行简单测试.将照片和相同的照片放大(放大)我用它们来检测特征,计算基本矩阵并恢复相机姿势.
Mat inliers;
Mat E = findEssentialMat(queryPoints, trainPoints, cameraMatrix1, cameraMatrix2,
FM_RANSAC, 0.9, MAX_PIXEL_OFFSET, inliers);
size_t inliersCount =
recoverPose(E, queryGoodPoints, trainGoodPoints, cameraMatrix1, cameraMatrix2, R, T, inliers);
Run Code Online (Sandbox Code Playgroud)
因此,当我将原始图像指定为第一个,并将缩放图像指定为第二个时,我得到平移T接近[0; 0; -1].然而,第二个相机(缩放)实际上比第一个更接近物体.因此,如果Z轴从图像平面进入场景,则第二个摄像机应沿Z轴具有正偏移.对于我得到的结果,Z轴从图像平面朝向摄像机,其中与其他轴(X向右,Y向下)形成左手坐标系.真的吗?为什么这个结果与此处所示的坐标系不同?
c++ opencv computer-vision pose-estimation structure-from-motion
如何为WongKinYiu/yolov7准备自定义关键点数据集?