这种两点简易标定是参考《http://47.98.154.65/?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
版权声明:本文为博主原创文章,转载请附上博文链接!


少有人走的路

















