python实现坐标求取_根据相机位姿求指定点的世界坐标及其python实现

Author

shaniadolphin

求解目的

本文将展示位姿估计的一种应用,即通过单目相机对环境进行测量。简单来说,本文的工作就是利用下面的两幅图,在已知P1、P2、P3、P4四点世界坐标的情况下,计算出其它点的世界坐标。

如图所示,一个标准的标定板,标定板每个格子的尺寸是30mm,通过标定四周的4个点P1、P2、P3、P4,旁边有茶罐,有待求点为P5、P6。

77f7c0cd9ec7

这种应用可以利用一个已经尺寸物体,通过两张不同视角的照片求未知物体的尺寸。比如上图中的通过已知的标定板求茶罐的尺寸。而在现实应用中可以用这种方式来求车的尺寸,建筑的高度,货物的体积等等。

求解原理

如下图,根据P1、P2、P3、P4四点的空间坐标,通过openCV的PNP函数,可以计算出两次拍照的相机位姿,从而进一步计算出相机的坐标

math?formula=Oc_1

math?formula=Oc_2。那么将

math?formula=Oc_1

math?formula=P

math?formula=Oc_2

math?formula=P连成直线,获得两条直线方程

math?formula=A

math?formula=B,组成方程组求解得到它们的交点,即为待求目标点的坐标。

77f7c0cd9ec7

1. 求出

math?formula=P点的相机坐标系坐标

math?formula=P_c

关于P点如何从二维映射到三维,参考上图,

math?formula=O_c的坐标通过解

math?formula=PNP已经求出,待求点P在图像中的像素坐标为

math?formula=(u%2Cv)

求出

math?formula=P在相机坐标系中的坐标

math?formula=P_c(也就是上图中的

math?formula=P_c点)。具体的转换公式如下,式中

math?formula=f为相机镜头的焦距

math?formula=(mm),在本次实验中使用的是中一光学的35mm手动镜头。

math?formula=(u%2Cv)为点的像素坐标,其余为相机内参数。

math?formula=%5Cbegin%7Bcases%7Dx_c%3D(u-u_0)*f%2Ff_x%20%5C%5Cy_c%3D(v-v_0)*f%2Ff_y%20%5C%5Cz_c%3Df%20%5Cend%7Bcases%7D

输入拍到的图片的点,包括待求点的像素坐标,示例如下:

P11 = np.array([0, 0, 0])

P12 = np.array([0, 300, 0])

P13 = np.array([210, 0, 0])

P14 = np.array([210, 300, 0])

p11 = np.array([1765, 725])

p12 = np.array([3068, 1254])

p13 = np.array([1249, 1430])

p14 = np.array([2648, 2072])

p4psolver1.Points3D[0] = np.array([P11,P12,P13,P14])

p4psolver1.Points2D[0] = np.array([p11,p12,p13,p14])

#p4psolver1.point2find = np.array([4149, 671])

#p4psolver1.point2find = np.array([675, 835])

p4psolver1.point2find = np.array([691, 336])

读取标定文件中的相机内参,代码如下,在代码里预设了相机的传感器大小,笔者所用的D7000单反是DX画幅的,根据可查到的资料,传感器的规格为23.6mm*15.6mm。

笔者用在本机的镜头是中一的35mm手动定焦镜头。

def getudistmap(self, filename):

with open(filename, 'r',newline='') as csvfile:

spamreader = csv.reader(csvfile, delimiter=',', quotechar='"')

rows = [row for row in spamreader]

self.cameraMatrix = np.zeros((3, 3))

#Dt = np.zeros((4, 1))

size_w = 23.6

size_h = 15.6

imageWidth = int(rows[0][1])

imageHeight = int(rows[0][2])

self.cameraMatrix[0][0] = rows[1][1]

self.cameraMatrix[1][1] = rows[1][2]

self.cameraMatrix[0][2] = rows[1][3]

self.cameraMatrix[1][2] = rows[1][4]

self.cameraMatrix[2][2] = 1

print(len(rows[2]))

if len(rows[2]) == 5:

print('fisheye')

self.distCoefs = np.zeros((4, 1))

self.distCoefs[0][0] = rows[2][1]

self.distCoefs[1][0] = rows[2][2]

self.distCoefs[2][0] = rows[2][3]

self.distCoefs[3][0] = rows[2][4]

scaled_K = self.cameraMatrix * 0.8 # The values of K is to scale with image dimension.

scaled_K[2][2] = 1.0

#newcameramtx = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(self.cameraMatrix, self.distCoefs, (imageWidth, imageHeight), np.eye(3), balance=0)

#map1, map2 = cv2.fisheye.initUndistortRectifyMap(self.cameraMatrix, self.distCoefs, np.eye(3), newcameramtx, (imageWidth, imageHeight), cv2.CV_32FC1)

else:

print('normal')

self.distCoefs = np.zeros((1, 5))

self.distCoefs[0][0] = rows[2][1]

self.distCoefs[0][1] = rows[2][2]

self.distCoefs[0][2] = rows[2][3]

self.distCoefs[0][3] = rows[2][4]

self.distCoefs[0][4] = rows[2][5]

#newcameramtx, roi = cv2.getOptimalNewCameraMatrix(self.cameraMatrix, self.distCoefs, (imageWidth, imageHeight), 1, (imageWidth, imageHeight))

#map1, map2 = cv2.initUndistortRectifyMap(self.cameraMatrix, self.distCoefs, None, newcameramtx, (imageWidth, imageHeight), cv2.CV_32FC1)

print('dim = %d*%d'%(imageWidth, imageHeight))

print('Kt = \n', self.cameraMatrix)

#print('newcameramtx = \n', newcameramtx)

print('Dt = \n', self.distCoefs)

self.f = [self.cameraMatrix[0][0]*(size_w/imageWidth), self.cameraMatrix[1][1]*(size_h/imageHeight)]

#self.f = [350, 350]

print('f = \n', self.f)

#print(map1,'\n',map2.T)

return

然后就可以将像素坐标转换到世界坐标了ÿ

  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值