二维码识别与定位-方法1-利用ar_track_alvar
Posted 步印
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二维码识别与定位-方法1-利用ar_track_alvar相关的知识,希望对你有一定的参考价值。
二维码识别作为一种快捷准确的技术已经应用与生活中的购物支付、物体识别及工业AGV导航等领域,在OpenCV3.4.4版本上均提供了相应的函数cv::QRCodeDetector::detectAndDecode()用于二维码的检测和解析,但是在ROS kinetic中自带的版本是OpenCV3.3.1,不能使用API,幸运地是在ROS中有一个开源功能包ar_track_alvar用于二维码相关的操作。
其安装方式为:
$ sudo apt-get install ros-melodic-ar-track-alvar
本节主要讲在ROS中如何创建二维码以及如何利用相机识别二维码来获得有用的信息。并利用两个不同的二维码来表征不同的物体,进而通过识别二维码来完成物体的定位。
1. 二维码创建
二维码的创建一般是离线进行的,是二维码识别的前提。制作好的二维码粘贴到地面、物体上后才可以实现实时定位。每一个二维码通常对应一个标签,如有的二维码代表一个网站,有的二维码代表一个坐标位置,有的二维码代表一个字符串等。
在ROS中,ar_track_alvar功能包提供了创建二维码的节点,可以根据其定义的规则,创建不同标签的二维码。例如执行如下命令,就会在终端的当前路径下,创建一个命名为MarkerData_标签.png的二维码图像。其中标签可以为整数、字符串、网址等属性。例如执行如下命令,会在终端生成一个名为MarkerData_0.png的图像,如图7.16所示。
$ rosrun ar_track_alvar createMarker 0
$ rosrun ar_track_alvar createMarker
可以看出使用-1 “string”的形式,可以创建字符串标签的二维码。在这里我们使用如下命令,创建多个不同的物体标签,包括cup、bottle、book、celephone,起二维码如图7.17所示。
$ rosrun ar_track_alvar createMarker -1 “cup”
$ rosrun ar_track_alvar createMarker -1 “bottle”
$ rosrun ar_track_alvar createMarker -1 “book”
$ rosrun ar_track_alvar createMarker -1 “celphone
做好二维码后我们就可以将其用于物体识别和定位了。
2. 二维码识别
ar_track_alvar功能包支持USB摄像头和RGB摄像头进行二维码识别,分别对应节点individualMarkersNoKinect适用于彩色摄像头,individualMarkers适用于深度相机。本节以astra mini相机为例进行二维码识别。
创建二维码识别的启动文件:
$ roscd cv_learn
<launch>
<node pkg="tf" type="static_transform_publisher" name="world_to_cam"
args="0 0 0.5 0 1.57 0 world camera_rgb_optical_frame 10" />
<arg name="marker_size" default="4.7" />
<arg name="max_new_marker_error" default="0.2" />
<arg name="max_track_error" default="0.2" />
<arg name="cam_image_topic" default="/camera/depth_registered/points" />
<arg name="cam_info_topic" default="/camera/rgb/camera_info" />
<arg name="output_frame" default="/camera_rgb_optical_frame" />
<node name="ar_track_alvar" pkg="ar_track_alvar" type="individualMarkers" respawn="false" output="screen">
<param name="marker_size" type="double" value="$(arg marker_size)" />
<param name="max_new_marker_error" type="double" value="$(arg max_new_marker_error)" />
<param name="max_track_error" type="double" value="$(arg max_track_error)" />
<param name="output_frame" type="string" value="$(arg output_frame)" />
<remap from="camera_image" to="$(arg cam_image_topic)" />
<remap from="camera_info" to="$(arg cam_info_topic)" />
</node>
<!-- rviz view /-->
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find cv_learn)/config/ar_track_astra.rviz"/>
</launch>
启动文件由三部分组成,首先设置相机坐标系与世界坐标系之间的坐标变换;其次是设置individualMarkers节点所需要的参数,主要是订阅图像数据的话题,二维码的尺寸,最大尺寸误差等参数;最后是启动可视化插件rviz用于显示tf、marker及图像。
下面启动相机与该启动文件进行测试,与之前的相机驱动程序不同,二维码的识别和定位需要相机的标定参数,又,在4.2节中已对astra mini相机进行了标定,直接使用即可,我们可以新建一个启动文件,并将标定参数加入到启动文件中,如astra_with_calibration.launch所示:
<launch>
<!-- Launch the freenect driver -->
<include file="$(find astra_launch)/launch/astra.launch">
<arg name="publish_tf" value="false" />
<!-- use device registration -->
<arg name="depth_registration" value="true" />
<arg name="rgb_processing" value="true" />
<arg name="ir_processing" value="false" />
<arg name="depth_processing" value="false" />
<arg name="depth_registered_processing" value="true" />
<arg name="disparity_processing" value="false" />
<arg name="disparity_registered_processing" value="false" />
<arg name="sw_registered_processing" value="false" />
<arg name="hw_registered_processing" value="true" />
<arg name="rgb_camera_info_url"
value="file://$(find cv_learn)/data/camera_calibration/astra_calib/rgb_calibration/astra_rgb_calibration.yaml" />
<arg name="depth_camera_info_url"
value="file://$(find cv_learn)/data/camera_calibration/astra_calib/depth_calibration/astra_depth_calibration.yaml" />
</include>
</launch>
按如下命令依次启动相机和二维码识别节点:
$ roslaunch cv_learn astra_with_calibration.launch
$ roslaunch cv_learn ar_track_astra.launch
拿起打印好的二维码,放置在摄像头前面,如图所示。可以在rviz看到已识别出了每个二维码,且包括其相对与摄像头的位置和姿态。
3 基于二维码的物体检测与识别
我们可以将二维码粘贴在物体的表面,这样当相机检测到二维码的位置和姿态时,可以间接计算出物体当前的位置和姿态通过运行如下命令:
$ rostopic echo /ar_pose_marker
如图所示,可以查看当前二维码所处的位置和姿态,变换位置后,位姿有相应的变化.
OpenCV二维码检测与定位
在如今流行扫描的年代,应用程序实现二维码扫描检测与识别已经是应用程序的标配、特别是在移动端、如果你的应用程序不能自动发现检测二维码,自动定位二维码你都不好意思跟别人打招呼,二维码识别与解析基于ZXing包即可。难点就在于如何从画面中快速而准确的找到二维码区域,寻找到二维码三个匹配模式点。
一:二维码的结构与基本原理
标准的二维码结构如下:
特别要关注的是图中三个黑色正方形区域,它们就是用来定位一个二维码的最重要的三个区域,我们二维码扫描与检测首先要做的就是要发现这三个区域,如果找到这个三个区域,我们就成功的发现一个二维码了,就可以对它定位与识别了。二维码其它各个部分的说明如下:
三个角上的正方形区域从左到右,从上到下黑白比例为1:1:3:1:1。
不管角度如何变化,这个是最显著的特征,通过这个特征我们就可以实现二维码扫描检测与定位。
二:算法各部与输出
1. 首先把输入图像转换为灰度图像(cvtColor)
2. 通过OTSU转换为二值图像(threshold)
3. 对二值图像使用轮廓发现得到轮廓(findContours)
4. 根据二维码三个区域的特征,对轮廓进行面积与比例过滤得到最终结果显示如下:
三:程序运行结果演示
上述程序运行的最终结果,左侧为原图,右侧为检测结果
四:各个步骤代码实现
#include <opencv2/opencv.hpp>
#include <math.h>
#include <iostream>
using namespace cv;
using namespace std;
bool isCorner(Mat &image);
Mat transformCorner(Mat &image, RotatedRect &rect);
int main(int argc, char** argv) {
Mat src = imread("D:/gloomyfish/qrcode_05.jpg");
if (src.empty()) {
printf("could not load image...\n");
return -1;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", src);
Mat gray, binary;
cvtColor(src, gray, COLOR_BGR2GRAY);
imwrite("D:/gloomyfish/outimage/qrcode_gray.jpg", gray);
threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
imwrite("D:/gloomyfish/outimage/qrcode_binary.jpg", binary);
// detect rectangle now
vector<vector<Point>> contours;
vector<Vec4i> hireachy;
Moments monents;
findContours(binary.clone(), contours, hireachy, RETR_LIST, CHAIN_APPROX_SIMPLE, Point());
Mat result = Mat::zeros(src.size(), CV_8UC3);
for (size_t t = 0; t < contours.size(); t++) {
double area = contourArea(contours[t]);
if (area < 100) continue;
RotatedRect rect = minAreaRect(contours[t]);
// 根据矩形特征进行几何分析
float w = rect.size.width;
float h = rect.size.height;
float rate = min(w, h) / max(w, h);
if (rate > 0.85 && w < src.cols/4 && h<src.rows/4) {
printf("angle : %.2f\n", rect.angle);
Mat qr_roi = transformCorner(src, rect);
if (isCorner(qr_roi)) {
drawContours(src, contours, static_cast<int>(t), Scalar(255, 0, 0), 2, 8);
imwrite(format("D:/gloomyfish/outimage/contour_%d.jpg", static_cast<int>(t)), qr_roi);
drawContours(result, contours, static_cast<int>(t), Scalar(255, 0, 0), 2, 8);
}
}
}
imshow("result", src);
imwrite("D:/gloomyfish/outimage/qrcode_patters.jpg", result);
waitKey(0);
return 0;
}
功崇惟志,业广惟勤!
关注【OpenCV学堂】
长按或者扫码下面二维码即可关注
+OpenCV学习群 376281510
进群暗号:OpenCV
以上是关于二维码识别与定位-方法1-利用ar_track_alvar的主要内容,如果未能解决你的问题,请参考以下文章