这种两点简易标定是参考《http://www.skcircle.com/?id=504》来进行的。
勇哥用CAD画了一个原理图如下:
在上图中:
黄色x'oy'坐标系是相机坐标系。
白色xoy坐标系是机械坐标系。
30度为两个坐标系之间的夹角,(x0,y0)为图像坐标原点到机械坐标原点的距离,图上距离为(30,30)。
P点在相机坐标系中是(20,20),在机械人坐标系中是(57.26,37.55)。
P点由相机坐标系转为机械坐标系的计算公式如下:
(式一)
x = x' * r * cos(theta) - y' * r * sin(theta) + x0; y = x' * r * sin(theta) + y' * r * cos(theta) + y0;
其中r是毫米像素比、(mm/pixel)就是一个毫米有几个像素。(x', y')在上图中就是P点(20,20)。
theta就是30度。
我们来计算一下,结果如下:
由于CAD的捕捉有一点点误差,这个结果跟公式算出来的有小小的差别。
简化抽象公式,假设:
a = r * cos(theta);
b = r * sin(theta);
c = x0;
d = y0;
得到:
(式二)
x = x' * a - y' * b + c;
y = x' * b + y' * a + d;
很显然,要解出这个方程,需要两组对应关系,就是两组对应的坐标点。设两组坐标点,如下:
第一组:图像坐标点:(xImage1,yImage1) 对应的机械坐标点:(xMachine1,yMachine1)
第二组:图像坐标点:(xImage2,yImage2) 对应的机械坐标点:(xMachine2,yMachine2)
则可以解出a ,b, c, d。如下:
(式三)
a = ((xMachine1 - xMachine2)*(xImage1- xImage2) + (yMachine1 - yMachine2)*(yImage1 - yImage2))
/ ((xImage1 - xImage2)*(xImage1 - xImage2) + (yImage1 - yImage2)*(yImage1 - yImage2));
b = ((yMachine1 - yMachine2)*(xImage1 - xImage2) - (xMachine1 - xMachine2)*(yImage1 - yImage2))
/ ((xImage1 - xImage2)*(xImage1 - xImage2) + (yImage1 - yImage2)*(yImage1 - yImage2));
c = xMachine1 - a*xImage1 + b*yImage1;
d = yMachine1 - b*xImage1 - a*yImage1;
所以,就得出了图像上任意一点的像素坐标转成机械手坐标的关系。
勇哥增加了一个点p2(64.07, 39.44)用来验证上面的推论。
可以看到结果是正确的。
这里比较有意思的是怎么由(式二)推断出(式三)的。
看(式三)已经把r和cos(theta)、sin(theta)消掉了。
以上求出来的a,b,c,d的值,就可以像应用矩阵一样,用来推算其它任意一个像素的机械坐标了。
晚上勇哥用x,y,z平台实验一下,看看这种方法精度怎么样。
=================================
实验开始,首先像素取标定块两个角点。
让笔去戳这个角点,记下机械坐标。
写程序验证
* Image Acquisition 01: Code generated by Image Acquisition 01 open_framegrabber ('GigEVision2', 0, 0, 0, 0, 0, 0, 'progressive', -1, 'default', -1, 'false', 'default', '94aab8005ad8_Microvision_MVEM500M', 0, -1, AcqHandle) grab_image (Image, AcqHandle) * Image Acquisition 01: Do something * x y *pt1 723,1769 *pt2 1684,805 *m1 62.302,-15.007 *m2 -57.2,-135.01 xMachine1:=19.198 yMachine1:=39.2 xMachine2:=137.597 yMachine2:=159.399 xImage1:=791 yImage1:=1685 xImage2:=1751 yImage2:=725 a:=((xMachine1-xMachine2)*(xImage1-xImage2)+(yMachine1-yMachine2)*(yImage1-yImage2))/\ ((xImage1-xImage2)*(xImage1-xImage2)+(yImage1-yImage2)*(yImage1-yImage2)) b:= ((yMachine1 - yMachine2)*(xImage1 - xImage2) - (xMachine1 - xMachine2)*(yImage1 - yImage2)) \ / ((xImage1 - xImage2)*(xImage1 - xImage2) + (yImage1 - yImage2)*(yImage1 - yImage2)) c:= xMachine1 - a*xImage1 + b*yImage1 d:= yMachine1 - b*xImage1 - a*yImage1 *x = x' * a - y' * b + c; *y = x' * b + y' * a + d; *这里代入像素坐标即可换算出机械坐标 x:=1085*a-1361*b+c y:=1085*b+1361*a+d stop() close_framegrabber (AcqHandle)
上面的程序中,勇哥选择如图所示的那个点,像素坐标为(1085,1361),求出机械坐标。
运动过去。
反正肉眼看着是很准的。
实际上这样实验的话,是没有办法得到量化数据到底有多准的。
换个方式吧。
我先随便找一个像素坐标,转为机械坐标后,定位过去,然后把笔降下来戳一个点,然后移开机构,用相机来拍像素坐标位置。
这样验证的话我们就有量化数据了。
鼠标随便指向一点(1216,1348)
转机械坐标后,定位过去,Z轴下降来戳点。
机械移开后重新拍照,取这一点的中心,坐标为(1215,1350)
和第一步记录的点坐标相比,row相差1个像素,col相差2个像素。
这么看来,这种方法精度还不错,真是想不到哦。
实验的结果证明,这种方法在精度要求不太高的情况下,还是很方便很实用的。
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!

