使用大恒水星相机利用OpenCV+ Zbar 解QR码在ROS下定位的实现

使用大恒水星相机利用OpenCV+ Zbar 解QR码在ROS下定位的实现

        本次的程序功能实现是在师兄原有程序的基础上,经我继续开发的。主要完成的功能是使用QR码定位,将位姿信息通过ROS中的tf变换发布出去,采用的是OpenCV和Zbar库相结合的解码方式,硬件上使用的是大恒水星工业相机,可以调节曝光时间,普通的网络摄像头相应的程序也有开发,在这里不再叙述。

        实现的过程将分为三个部分来描述。1、硬件安装;2、软件安装;3、定位过程。之所以提到硬件,是因为硬件问题也很重要,只有正确的安装硬件,才能获得图像信息,进行图像处理,为下一步定位做准备。软件上使用的是OpenCV和Zbar,因为是免费的开放软件和解码包,为后续工作的开发提供便利,且使用Zbar进行解码比较容易(相比于dmtx库)。定位方法因人而异,不过别人的一些方法可以借鉴。

1、硬件安装

使用的是大恒水星相机MER-030-120UM/UC,镜头焦距是16mm。性能参数如下:

 

        下载大恒相机的驱动程序daheng_x64_1.3.1502.1506,在Ubuntu系统中,使用的是generic.39 的内核,目前大恒相机只开发到此版本相应的内核,需要在此内核下才能安装大恒相机的驱动程序。每次使用的时候,都要安装驱动程序,命令$sudo ./INSTALL.sh,会提示安装成功,此时相机就可以用了。目前还没有很好的办法去解决这个兼容问题,我曾试过在其他版本的内核下运行同样的程序,但提示找不到相机的接口,因此无法使用,所以要使用此款工业相机,需要按照这种方式去做。连接上数据线。


例子:

zcn@zcn:~/Downloads/daheng_x64-1.3.1502.1506$ sudo ./INSTALL.sh

[sudo] password for zcn:

***********************************************************************************************

                                       SelfInstaller

 

SDK install successs!

ERROR: Module videodev is in use by uvcvideo

Driver install success!

Please restart current terminal...

***********************************************************************************************

此时,相机可以正常使用。

2、软件安装

     下载OpenCV包,官网上都有的,可自行下载,照装入软件的步骤一步步装入,这是准备工作,同样Zbar的解码包也是。可用命令$sudo apt-get install ros-hydro-zbar*来装解码包,dmtx解码包也可用同样的命令安装。目前电脑上安装的是Ubuntu12.04,OpenCV版本是2.4.9。


$sudo apt-getinstall ros-hydro-zbar*

提示:

 

3、定位过程。

         着重讲的是这部分的内容。首先是图像采集,采集之后的图像交给OpenCV来处理,利用Zbar库解出二维码的内容。在图像平面中对二维码的角度进行求解,利用二维码四个顶点的像素信息和图像平面的中心之间的关系,求出图像中心相对于二维码坐标系所在的象限,根据坐标分解求出图像中心在世界坐标系中的实际坐标信息,车体的角度可通过求二维码的偏转角度而得到。

效果如下图:


(1)拆解QR解码内容

         通过symbol->get_data()可以直接解出QR码中融入的内容,将该字符串转换为char类型,可以用srotok函数进行字符串分割。此过程需要注意字符串类型的转换,思路是:在不同的类型之间搭一座桥,两者可以进行处理了。将分割后的字符作为下面计算坐标的依据。

(2)输出QR码四个顶点

        在图像平面坐标系中,每个顶点的像素坐标是已知的,可以直接通过symbol->get_localization()来获得。由于使用Zbar进行解码,旋转矩形的四个顶点可以直接求出。比用dmtx库进行图像处理方便很多。在使用dmtx库时,是用canndy算子进行边缘检测,二值化,矩形大小匹配等处理,比较复杂。

坐标系的建立及QR顶点:

 

 使用line(imgout,Point(),Point(),Scalar())来画出四个顶点连成的矩形。

 由于opencv中没有直接画箭头的函数,因此可以调用drawArrow函数来画箭头。具体实现在网上都有例子。

(3)计算边的像素长度和夹角。

    点的像素坐标是已知的,因此三边的长度可以计算得到,可通过余弦定理来求两边的夹角。

(4)AB边与像平面坐标轴的夹角。

    这里利用了r.angle,这个是QR码矩形的倾斜角度,可以用来获取AB与X轴、Y轴的夹角。此处注意判断条件的完备性。                                 

(5)O点在QR码规定的坐标系中所处的象限

       这里主要是通过AO与BA方向的夹角来进行判断O点所在的象限的。AO与BA方向的夹角可以通过AO与X轴正方向夹角、BA与X轴正方向夹角来获得,共同选取X轴正方向为角度判断依据。

      此处的问题:由于角度信息求取不准确,因此后面判断象限时有错误,说明方法有误,需要考虑完备的方案。解决思路:选取共同的一条边为依据,计算角度,两个相对角度的差即为角度差的绝对值,然后通过角度的绝对值来判断O点所在象限。此方法是师兄提供的。

注:这个象限角度的确定问题,下面讲述下我是如何解决的。先确定A点在四个象限中的位置,然后确定AO向量与X 轴正方向的夹角。使用了fastAtan()函数,需要明白它的角度范围,根据向量AO在第几象限从而确定夹角angle_AO,此处我是采用绝对值的方式加减一个角度值来实现的。调试的过程中可以调节增量,保证数值是连续的,而且要考虑边界时的情况,保证判断条件的完备性。                           

(6)象限判断后可以求出O点在世界坐标系中的坐标

规定BA方向为QR码的X轴正方向,AD方向为QR码的Y轴正方向。根据O点,分为不同的象限,将AO的像素长度分解到BA和AD方向上,每个像素在实际坐标系中所代表的距离可以通过相机的标定来获得,因此可以求出车体的x,y坐标。

(7)发布并tf变换

将得到的x,y,theta信息通过tf变换广播并发布出去,遵循ROS节点的机制,其他的节点可以订阅此信息,于是定位功能到此完成。

(8)为何选取图像平面的中心O点?

       这个问题是反复测试之后才确定的。曾选用图像的坐标原点为计算依据,利用图像坐标原点和图像中心点的关系来计算,这样会省去中间过程中象限确定及角度确定的繁琐。然而最终坐标在图像坐标原点和图像中心点转换时,还是需要考虑到车体的偏转角度也即是AB与X轴或Y轴正方向的夹角的,所以这种方式不可行。


总结:

1.角度的转换问题是一个难点,若夹角不准确,则后面的判断结果必然错误,关于象限求角度,其实是可以有不同求法的。

2.提取分割的数据时,注意字符串的数据类型,需要经过一步转换满足条件后才可以进行分割提取。

        第一次写,难免有不足之处。这只是一个实现过程,欢迎多多交流。

 

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用OpenCV大恒C SDK可以轻松地采集大恒水星相机的图像。首先,需要下载和安装相应的SDK和库,并确保与相机的连接正常。接下来,可以使用OpenCV提供的函数来打开相机,并设置相应的参数,如分辨率和帧率。然后,可以通过循环不断地从相机中读取图像帧,并使用OpenCV进行图像处理和分析。 可以使用OpenCV中的cv::VideoCapture类来打开相机连接,并设置相应的参数。例如: ``` cv::VideoCapture capture; capture.open(0); // 打开相机连接 if (!capture.isOpened()) { // 相机连接失败 return -1; } capture.set(cv::CAP_PROP_FRAME_WIDTH, 1280); // 设置图像宽度 capture.set(cv::CAP_PROP_FRAME_HEIGHT, 720); // 设置图像高度 capture.set(cv::CAP_PROP_FPS, 30); // 设置帧率 ``` 然后,可以在循环中读取相机图像,并使用OpenCV函数进行处理。例如,可以使用cv::imshow函数显示图像,使用cv::imwrite保存图像,使用cv::cvtColor将图像转换为不同的颜色空间等等。 ``` cv::Mat frame; while (capture.read(frame)) { cv::imshow("Camera", frame); // 显示图像 // 进行其他的图像处理操作 int key = cv::waitKey(1); if (key == 27) { // 按下Esc键退出循环 break; } } ``` 最后,记得在程序结束时,释放相机连接和关闭窗口: ``` capture.release(); // 释放相机连接 cv::destroyAllWindows(); // 关闭窗口 ``` 以上就是使用OpenCV大恒C SDK采集大恒水星相机图像的基本步骤。可以根据实际需求,结合OpenCV提供的丰富功能,进行图像处理、计算机视觉和图像分析等任务。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值