勇哥的视觉实验: 不用标定板的简易2点标定(一)


这种两点简易标定是参考http://www.skcircle.com/?id=504来进行的。

勇哥用CAD画了一个原理图如下:


image.png

在上图中:

黄色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度。


我们来计算一下,结果如下:

image.png

由于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)用来验证上面的推论。

image.png


可以看到结果是正确的。

image.png

这里比较有意思的是怎么由(式二)推断出(式三)的。

看(式三)已经把r和cos(theta)、sin(theta)消掉了。


以上求出来的a,b,c,d的值,就可以像应用矩阵一样,用来推算其它任意一个像素的机械坐标了。


晚上勇哥用x,y,z平台实验一下,看看这种方法精度怎么样。

=================================

实验开始,首先像素取标定块两个角点。

让笔去戳这个角点,记下机械坐标。

image.png

写程序验证

* 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),求出机械坐标。

image.png

运动过去。

反正肉眼看着是很准的。


image.png

实际上这样实验的话,是没有办法得到量化数据到底有多准的。


换个方式吧。

我先随便找一个像素坐标,转为机械坐标后,定位过去,然后把笔降下来戳一个点,然后移开机构,用相机来拍像素坐标位置。

这样验证的话我们就有量化数据了。


鼠标随便指向一点(1216,1348)   

转机械坐标后,定位过去,Z轴下降来戳点。

机械移开后重新拍照,取这一点的中心,坐标为(1215,1350)

和第一步记录的点坐标相比,row相差1个像素,col相差2个像素。

这么看来,这种方法精度还不错,真是想不到哦。

image.png


实验的结果证明,这种方法在精度要求不太高的情况下,还是很方便很实用的。


--------------------- 

作者:hackpig

来源:www.skcircle.com

版权声明:本文为博主原创文章,转载请附上博文链接!


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:
本帖最后由 勇哥,很想停止 于 2020-07-22 21:53:56 编辑
  • 评论列表:
  •  wly_2023
     发布于 2023-08-16 15:29:37  回复该评论
  • 你好,我按照你的文章操作,得不到想要的效果?x和Y数值都有偏移,请问是不是要加上X和Y的偏移数值?

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年4月    »
1234567
891011121314
15161718192021
22232425262728
2930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864