二维码识别与定位-方法2-利用opencv扩展库aruco

  二维码识别作为一种快捷准确的技术已经应用与生活中的购物支付、物体识别及工业AGV导航等领域,典型的二维码识别开源库有arcuo,alvar以及OpenCV中的二维码检测API如QRCodeDetector,在本节中我们将使用aruco库来进行二维码的识别,该库已集成在opencv的contrib集中。
本节主要讲在ROS中如何创建二维码以及如何利用相机识别二维码来获得有用的信息。并利用两个不同的二维码来表征不同的物体,进而通过识别二维码来完成物体的定位。

1.二维码创建

  二维码的创建一般是离线进行的,是二维码识别的前提。制作好的二维码粘贴到地面、物体上后才可以实现实时定位。每一个二维码通常对应一个标签,如有的二维码代表一个网站,有的二维码代表一个坐标位置,有的二维码代表一个字符串等。
  在aruco模块包含了一些预定义的字典,如下表所示,每个字典实际上是常用的一些二维码集合,这些字典涵盖了一系列的字典大小和Marker尺寸,marker可以有不同的规格.根据每个marker我们还可以生成不同像素大小的图像.

表 Aruco字典列表
序号 字典 字典 字典 字典
DICT_4x4_50 DICT_4x4_100 DICT_4x4_250 DICT_4x4_1000
DICT_5x5_50 DICT_5x5_100 DICT_5x5_250 DICT_5x5_1000
DICT_6x6_50 DICT_6x6_100 DICT_6x6_250 DICT_6x6_1000
DICT_7x7_50 DICT_7x7_100 DICT_7x7_250 DICT_7x7_1000

  在本节中我们选择字典DICT_6x6_250,其marker大小为6x6bits,字典的大小为250,即该字典中有250个大小为6*6bit的二维码.下面我们编写节点来使用该字典中的某一个二维码来生成二维码图像.

  执行如下命令,会在终端生成一个名为marker_6X6_250_31.jpg的图像,它是aruco预定义的字典DICT_6X6_250中第31个二维码,其像素大小为500*500,即宽高都为500pixels.如图所示。

$ gedit generate_marker.py

其内容如下:

import numpy as np
import cv2  
import cv2.aruco as aruco
import math
aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_250)  
marker_id = 31
marker_img = aruco.drawMarker(aruco_dict, marker_id,500)
pic_name = "marker_6X6_250_" + str(marker_id) + ".jpg"
cv2.imwrite(pic_name,marker_img)

其图像如下:
二维码识别与定位-方法2-利用opencv扩展库aruco_第1张图片

图 marker_6X6_250_31图像

下面对上述代码的关键内容进行解析,aruco.Dictionary_get(aruco.DICT_6X6_250) 表示获取字典DICT_6X6_250;marker_id = 31,表示我们要生成的二维码在字典中的编号是31;aruco.drawMarker表示绘制该二维码,大小为500*500.

2. 二维码识别

得到了上述的二维码之后,我们就可以使用aruco来编写识别二维码的程序了.执行如下命令来创建二维码识别程序:

$ gedit marker_detect.py

你可在目录/cv_learn目录下看到文件qrcode_detect_demo.py.下面仅对其主要代码进行解释:

rospy.init_node('qcode_detect', anonymous=True)
detection_pub = rospy.Publisher("qcode_detect_result", Twist, queue_size=1)  # 发布图像话题名称上述代码声明了本节点的名称”qcode_detect”,且本节点检测到的物体结果信息将通过话题”qcode_detect_result”进行发布.
corners, ids, rejectedImgPoints = aruco.detectMarkers(image=gray, dictionary=aruco_dict, parameters=parameters, cameraMatrix=camera_matrix,distCoeff=camera_distortion)# 该代码用于检测图像中的二维码,其输入为经过灰度化处理的图像,要检测对象归属的二维码字典以及相机的内参。输出为检测到的二维码的四个角点的像素坐标,已检测的二维码在字典中的id编号。
ret = aruco.estimatePoseSingleMarkers(corners, marer_size, camera_matrix, camera_distortion)#该代码使用aruco中的estimatePoseSingleMarkers函数,其输入为检测到的二维码角点信息以及二维码实际打印后的尺寸(mm)。其输出为二维码在相机坐标系下的位置和姿态。此过程实际是通过PNP解算得到的。
result = Twist()
result.linear.x = tvec[0]
result.linear.y = tvec[1]
result.linear.z = tvec[2]
result.angular.x = r
result.angular.y = p
result.angular.z = y
detection_pub.publish(result)#用于发布检测到的结果,其类型采用的是Twist,包括二维码在相机坐标系x,y,z下的直角坐标,以及绕x,y,z轴的欧拉角。

将打印好的二维码放在相机视野下,然后执行如下命令启动二维码识别节点:

$ python marker_detect.py

  其检测结果如下,可以看到二维码区域已经被框选出来,且坐标轴也已标注出,其中红色表示x轴,绿色表示y轴,蓝色表示z轴。

二维码识别与定位-方法2-利用opencv扩展库aruco_第2张图片

图 二维码检测结果
  特别地,我们可以将二维码粘贴在物体的表面,这样当相机检测到二维码的位置和姿态时,可以间接计算出物体当前的位置和姿态,以此来达到物体检测的物体. 

你可能感兴趣的:(计算机视觉,opencv,python,二维码检测,物体检测与定位)