我有一个校准过的相机(内在矩阵和失真系数),我想知道相机位置知道一些3d点及其在图像中的对应点(2d点).
我知道,cv::solvePnP能帮助我,看完这个和这个我明白solvePnP的,我的产出rvec和tvec是对象在相机的旋转和平移坐标系.
所以我需要找出世界坐标系中的摄像机旋转/平移.
从上面的链接看来,代码在python中是直截了当的:
found,rvec,tvec = cv2.solvePnP(object_3d_points, object_2d_points, camera_matrix, dist_coefs)
rotM = cv2.Rodrigues(rvec)[0]
cameraPosition = -np.matrix(rotM).T * np.matrix(tvec)
Run Code Online (Sandbox Code Playgroud)
我不知道python/numpy东西(我正在使用C++),但这对我来说没有多大意义:
glTranslatef和glRotate调用?我在视频(或图像)中有4个共面点代表一个四边形(不一定是方形或矩形),我希望能够在它们顶部显示一个虚拟立方体,其中立方体的角正好位于角落视频四边形.
由于这些点是共面的,我可以计算单位平方的角(即[0,0] [0,1] [1,0] [1,1])和四边形的视频坐标之间的单应性.
根据这个单应性,我应该能够计算出正确的相机姿势,即[R | t],其中R是3x3旋转矩阵,t是3x1平移向量,因此虚拟立方体位于视频四边形上.
我已经阅读了很多解决方案(其中一些是关于SO的)并试图实现它们,但它们似乎仅在一些"简单"的情况下工作(例如当视频四边形是正方形时)但在大多数情况下不起作用.
以下是我尝试过的方法(大多数是基于相同的原理,只是翻译的计算略有不同).设K是摄像机的内在矩阵,H是单应性.我们计算:
A = K-1 * H
Run Code Online (Sandbox Code Playgroud)
设a1,a2,a3为A和r1,r2,r3的列向量,即旋转矩阵R的列向量.
r1 = a1 / ||a1||
r2 = a2 / ||a2||
r3 = r1 x r2
t = a3 / sqrt(||a1||*||a2||)
Run Code Online (Sandbox Code Playgroud)
问题是在大多数情况下这不起作用.为了检查我的结果,我将R和t与OpenCV的solvePnP方法获得的结果进行了比较(使用以下3D点[0,0,0] [0,1,0] [1,0,0] [1,1 ,0]).
由于我以相同的方式显示立方体,我注意到在每种情况下solvePnP都提供了正确的结果,而从单应性中获得的姿势大多是错误的.
理论上,因为我的点是共面的,所以可以从单应性计算姿势,但是我找不到从H计算姿势的正确方法.
我对错误的看法有何见解?
尝试@Jav_Rock的方法后编辑
嗨Jav_Rock,非常感谢你的答案,我尝试了你的方法(以及其他许多方法)似乎或多或少都可以.然而,在基于4个共面点计算姿势时,我仍然遇到一些问题.为了检查结果,我将与solvePnP的结果进行比较(由于迭代重投影误差最小化方法,这将更好).
这是一个例子:

正如你所看到的,黑色立方体或多或少都可以,但看起来并不均匀,尽管矢量看似正交.
EDIT2:我在计算它之后对v3进行了规范化(为了强制执行正交性),它似乎也解决了一些问题.
我正在尝试使用单应性校准并在Blender 3d中找到单个虚拟相机的位置和旋转.我正在使用Blender,以便在我进入真实世界之前我可以仔细检查我的结果.我在固定相机的视野中渲染了十张不同位置的棋盘图片和旋转.使用opencv的python,我使用cv2.calibrateCamera从十个图像中检测到的棋盘角上找到内在矩阵,然后在cv2.solvePnP中使用它来查找外部参数(平移和旋转).然而,尽管估计的参数接近实际参数,但仍然存在一些可疑的参数.我对翻译的初步估计是(-0.11205481,-0.0490256,8.13892491).实际位置是(0,0,8.07105).非常接近吧?但是,当我移动并稍微旋转相机并重新渲染图像时,估计的平移变得更远了.估计:( - 0.15933154,0.13367286,9.34058867).实际:( - 1.7918,-1.51073,9.76597).Z值接近,但X和Y不接近.我完全糊涂了.如果有人能帮助我解决这个问题,我将非常感激.这是代码(它基于随opencv提供的python2校准示例):
#imports left out
USAGE = '''
USAGE: calib.py [--save <filename>] [--debug <output path>] [--square_size] [<image mask>]
'''
args, img_mask = getopt.getopt(sys.argv[1:], '', ['save=', 'debug=', 'square_size='])
args = dict(args)
try: img_mask = img_mask[0]
except: img_mask = '../cpp/0*.png'
img_names = glob(img_mask)
debug_dir = args.get('--debug')
square_size = float(args.get('--square_size', 1.0))
pattern_size = (5, 8)
pattern_points = np.zeros( (np.prod(pattern_size), 3), np.float32 )
pattern_points[:,:2] = np.indices(pattern_size).T.reshape(-1, 2)
pattern_points *= square_size
obj_points = []
img_points = []
h, w = 0, …Run Code Online (Sandbox Code Playgroud) 我想计算我的相机在世界坐标中的位置.这应该相当容易,但我没有得到我期望的结果.我相信我已经阅读了有关此主题的所有内容,但我的代码无效.这是我做的:
我有一个相机看着一个区域.
1)我画了一张该地区的地图.
2)我通过使用在我的地图上将4个图像点匹配到4个点来计算单应性 cv2.getPerspectiveTransform
3)H homography将每个世界坐标转换为摄像机坐标; 这是正常的
4)为了计算相机矩阵我遵循这个:
translation = np.zeros((3,1))
translation[:,0] = homography[:,2]
rotation = np.zeros((3,3))
rotation[:,0] = homography[:,0]
rotation[:,1] = homography[:,1]
rotation[:,2] = np.cross(homography[0:3,0],homography[0:3,1])
cameraMatrix = np.zeros((3,4))
cameraMatrix[:,0:3] = rotation
cameraMatrix[:,3] = homography[:,2]
cameraMatrix = cameraMatrix/cameraMatrix[2][3] #normalize the matrix
Run Code Online (Sandbox Code Playgroud)
5)根据这个,相机的位置应该这样计算:
x,y,z = np.dot(-np.transpose(rotation),translation)
Run Code Online (Sandbox Code Playgroud)
我得到的坐标是完全错误的.我想这个问题应该在步骤4或5的某个地方.我的方法有什么问题?
我试图通过使用我的网络摄像头从具有已知全球位置的四个基准点的图像中获得全局姿势估计.
我检查了很多stackexchange问题和一些文章,我似乎无法得到一个正确的解决方案.我得到的位置编号是可重复的,但绝不与摄像机移动成线性比例.仅供参考我使用的是C++ OpenCV 2.1.
在这个链接上描绘了我的坐标系和下面使用的测试数据.
% Input to solvePnP():
imagePoints = [ 481, 831; % [x, y] format
520, 504;
1114, 828;
1106, 507]
objectPoints = [0.11, 1.15, 0; % [x, y, z] format
0.11, 1.37, 0;
0.40, 1.15, 0;
0.40, 1.37, 0]
% camera intrinsics for Logitech C910
cameraMat = [1913.71011, 0.00000, 1311.03556;
0.00000, 1909.60756, 953.81594;
0.00000, 0.00000, 1.00000]
distCoeffs = [0, 0, 0, 0, 0]
% output of solvePnP():
tVec = [-0.3515;
0.8928;
0.1997]
rVec = [2.5279; …Run Code Online (Sandbox Code Playgroud) opencv computational-geometry camera-calibration pose-estimation extrinsic-parameters
我试图从两个视图的三角测量中得到一个点的3D坐标.我不确定我的结果是否正确.
例如,我不确定坐标的符号是否正确,因为我不确定相机框架是如何定向的.
z轴正面是进入或退出图像平面?而x和y?他们遵循右手规则吗?
在此先感谢您的澄清!