怎样进行机器人手眼标定?
一、标定原理
机器人手眼标定分为eye in hand与eye to hand两种。介绍之前进行变量定义说明: {b}: base基坐标系 {g}: gripper夹具坐标系 {t}: target标定板坐标系 {c}: camera相机坐标系 1、眼在手上(eye in hand)
眼在手上,相机固定在机器人上。
图1. eye in hand示意图
由以上两公式得:
经变换得:
可得:
求解 即标定 。 2、眼在手外(eye to hand)
眼在在手外,相机固定在机器人外。
图2. eye to hand示意图
由以上两公式可得:
经变换得:
可得
求解 即标定 。 二 、标定步骤将标定板固定至机械臂末端; 在位置1采集标定板图像,并记录机械臂在位置1下的位置与姿态; 在位置2采集标定板图像,并记录机械臂在位置2下的位置与姿态; 移动机械臂更换不同位置,采集25-40张图像,并记录机械臂在每个位置下的位姿; 相机标定,获取25-40组Tt_c; 位姿读取,获取25-40组Tb_g; 根据5,6调用标定接口,获取Tc_b。 三、标定代码import os import cv2 import xlrd2 from math import * import numpy as np class Calibration: def __init__(self): self.K = np.array([[2.54565632e+03, 0.00000000e+00, 9.68119560e+02], [0.00000000e+00, 2.54565632e+03, 5.31897821e+02], [0.00000000e+00, 0.00000000e+00, 1.00000000e+00]], dtype=np.float64) self.distortion = np.array([[-0.2557898, 0.81056366, 0.0, 0.0, -8.39153683]]) self.target_x_number = 12 self.target_y_number = 8 self.target_cell_size = 40 def angle2rotation(self, x, y, z): Rx = np.array([[1, 0, 0], [0, cos(x), -sin(x)], [0, sin(x), cos(x)]]) Ry = np.array([[cos(y), 0, sin(y)], [0, 1, 0], [-sin(y), 0, cos(y)]]) Rz = np.array([[cos(z), -sin(z), 0], [sin(z), cos(z), 0], [0, 0, 1]]) R = Rz @ Ry @ Rx return R def gripper2base(self, x, y, z, tx, ty, tz): thetaX = x / 180 * pi thetaY = y / 180 * pi thetaZ = z / 180 * pi R_gripper2base = self.angle2rotation(thetaX, thetaY, thetaZ) T_gripper2base = np.array([[tx], [ty], [tz]]) Matrix_gripper2base = np.column_stack([R_gripper2base, T_gripper2base]) Matrix_gripper2base = np.row_stack((Matrix_gripper2base, np.array([0, 0, 0, 1]))) R_gripper2base = Matrix_gripper2base[:3, :3] T_gripper2base = Matrix_gripper2base[:3, 3].reshape((3, 1)) return R_gripper2base, T_gripper2base def target2camera(self, img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, corners = cv2.findChessboardCorners(gray, (self.target_x_number, self.target_y_number), None) corner_points = np.zeros((2, corners.shape[0]), dtype=np.float64) for i in range(corners.shape[0]): corner_points[:, i] = corners[i, 0, :] object_points = np.zeros((3, self.target_x_number * self.target_y_number), dtype=np.float64) count = 0 for i in range(self.target_y_number): for j in range(self.target_x_number): object_points[:2, count] = np.array( [(self.target_x_number - j - 1) * self.target_cell_size, (self.target_y_number - i - 1) * self.target_cell_size]) count += 1 retval, rvec, tvec = cv2.solvePnP(object_points.T, corner_points.T, self.K, distCoeffs=distortion) Matrix_target2camera = np.column_stack(((cv2.Rodrigues(rvec))[0], tvec)) Matrix_target2camera = np.row_stack((Matrix_target2camera, np.array([0, 0, 0, 1]))) R_target2camera = Matrix_target2camera[:3, :3] T_target2camera = Matrix_target2camera[:3, 3].reshape((3, 1)) return R_target2camera, T_target2camera def process(self, img_path, pose_path): image_list = [] for root, dirs, files in os.walk(img_path): if files: for file in files: image_name = os.path.join(root, file) image_list.append(image_name) R_target2camera_list = [] T_target2camera_list = [] for img_path in image_list: img = cv2.imread(img_path) R_target2camera, T_target2camera = self.target2camera(img) R_target2camera_list.append(R_target2camera) T_target2camera_list.append(T_target2camera) R_gripper2base_list = [] T_gripper2base_list = [] data = xlrd2.open_workbook(pose_path) table = data.sheets()[0] for row in range(table.nrows): x = table.cell_value(row, 0) y = table.cell_value(row, 1) z = table.cell_value(row, 2) tx = table.cell_value(row, 3) ty = table.cell_value(row, 4) tz = table.cell_value(row, 5) R_gripper2base, T_gripper2base = self.gripper2base(x, y, z, tx, ty, tz) R_gripper2base_list.append(R_gripper2base) T_gripper2base_list.append(T_gripper2base) R_camera2base, T_camera2base = cv2.calibrateHandEye(R_gripper2base_list, T_gripper2base_list, R_target2camera_list, T_target2camera_list) return R_camera2base, T_camera2base, R_gripper2base_list, T_gripper2base_list, R_target2camera_list, T_target2camera_list def check_result(self, R_cb, T_cb, R_gb, T_gb, R_tc, T_tc): for i in range(len(R_gb)): RT_gripper2base = np.column_stack((R_gb[i], T_gb[i])) RT_gripper2base = np.row_stack((RT_gripper2base, np.array([0, 0, 0, 1]))) RT_base2gripper = np.linalg.inv(RT_gripper2base) print(RT_base2gripper) RT_camera_to_base = np.column_stack((R_cb, T_cb)) RT_camera_to_base = np.row_stack((RT_camera_to_base, np.array([0, 0, 0, 1]))) print(RT_camera_to_base) RT_target_to_camera = np.column_stack((R_tc[i], T_tc[i])) RT_target_to_camera = np.row_stack((RT_target_to_camera, np.array([0, 0, 0, 1]))) RT_camera2target = np.linalg.inv(RT_target_to_camera) print(RT_camera2target) RT_target_to_gripper = RT_base2gripper @ RT_camera_to_base @ RT_camera2target print("第{}次验证结果为:".format(i)) print(RT_target_to_gripper) print("") if __name__ == "__main__": image_path = r"Dcodeimg" pose_path = r"Dcodepose.xlsx" calibrator = Calibration() R_cb, T_cb, R_gb, T_gb, R_tc, T_tc = calibrator.process(image_path, pose_path) calibrator.check_result(R_cb, T_cb, R_gb, T_gb, R_tc, T_tc)
智驱力-科技驱动生产力
男子夜晚打车回家,遇到一个怪人,着装吓人天下之大,无奇不有一男子在夜晚正准备打车回家,谁知竟在一个桐树下发现了一个怪异的人,这个真是吓坏他了,连忙拿起手机进行拍照,各位请看下图这位女子着装的路人实在是吓人啊,两个眉毛宛如
一定要明白为什么会寒心重复的力量不单单在于正向回馈,一旦形成反向效应,杀伤力惊人。我一直追求正向回馈,人嘛,总是要向前看的,而重复是正向回馈最大化,且带有强大的复利效应。只是今天在看书的时候我突然了解到
等我老了等我老了,希望身边好友还在,时常小聚,吹吹牛皮,烫壶老酒等我老了,希望身边老铁还在,一声令号,空空技能,笑骂举报等我老了,希望身边良人还在,身老头白,磕磕绊绊,一生挚爱等我老了,
从现在起,你一定要逼自己做到的5件事头条号向暖的小窝长期有偿征稿,稿酬30100元,有意向投稿的朋友可以私信888查看具体要求,期待来稿微风嗨,小窝的家人们好,我是向暖,一个热爱成长和分享的斜杠撰稿人。最近闲来无事翻
看书,静心我在岛屿读书他不准备忏悔,也不是为了挑衅,这就是他真实的想法。老范坐边上,后来她写道说实话,他的坦率让我绝望。一个过于主动甚至积极坦白自己内心阴暗面的人,往往会让原本想去挖掘他内心
第四封信现在就去做,只要肯积极行动,你就会越来越接近成功亲爱的约翰聪明人说的话总能让我记得很牢。有位聪明人说得好教育涵盖了许多方面,但是他本身不教你任何一面。这位聪明人向我们展示了一条真理如果你不采取行动,世界上最实用最美丽最可行的哲学
自带停机坪的酒店!劳斯莱斯接送,在云端开启上帝视角WELCOMETOAIRPORTS拥有停机坪的奢华酒店合集在云端开启上帝视角之前我们已经盘点过一波可以乘直升机入住的酒店今天,我们再来盘一盘那些自带直升机停机坪的酒店!海棠湾红树林
随州解放路颜值爆表湖北日报客户端讯(通讯员曾融胡迪)解放路是随州最繁荣的商贸中心,见证着随州历史的变迁,也凝聚着随州人挥之不去的记忆。以上图片来源网络解放路商圈人流熙熙攘攘大十字街买百货,小十字街吃
王者荣耀小偶像进阶之路!女团风格皮肤大盘点王者荣耀被很多女玩家笑称为王者暖暖,不因为别的,就是因为这款游戏里面好看的皮肤实在是太多,风格也包罗万象,无论你是哪一款,总能找到自己爱的那一类。其中,女孩子们最喜欢的风格就少不了
中年女人冬天不试试毛衣呢子裙,都不知道原来这么显气质女人到了中年之后,穿衣打扮就开始逐渐有了难度,随着年龄增长身材和气质,都会发生一定程度上的变化,皱纹都不断出现身材的逐渐发福,都是导致气质降低的原因,但是我们却可以通过正确的服装组
日本战败后,2万日军带着1万女人躲进长白山,至今却了无音讯当年抗日战争胜利后,2万多名日军无法接受自己的失败,带着1万多名妇女躲进了长白山。可70多年过去了,这3万多人却从未出现过,甚至事后出动飞机也没有搜查到有大规模人类的行踪,可种种资