mirror of
https://github.com/Jieshoudaxue/ros_senior.git
synced 2026-08-29 08:34:43 +08:00
[fix] add qr_detector
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Changelog for package qr_detector
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
1.0.0 (2017-05-01)
|
||||
------------------
|
||||
* QR detection wrapper on zbar implemented
|
||||
* Contributors: Michal Drwiega
|
||||
@@ -0,0 +1,37 @@
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
project(qr_detector)
|
||||
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
find_package(catkin REQUIRED COMPONENTS
|
||||
roscpp nodelet sensor_msgs cv_bridge image_transport)
|
||||
|
||||
catkin_package(
|
||||
INCLUDE_DIRS include
|
||||
LIBRARIES qr_detector_nodelet
|
||||
CATKIN_DEPENDS roscpp nodelet sensor_msgs cv_bridge image_transport
|
||||
)
|
||||
|
||||
find_library(ZBAR_LIBRARIES NAMES zbar)
|
||||
|
||||
include_directories(include ${catkin_INCLUDE_DIRS})
|
||||
|
||||
add_library(qr_detector_nodelet src/qr_detector_nodelet.cpp src/detector.cpp)
|
||||
target_link_libraries(qr_detector_nodelet zbar ${catkin_LIBRARIES})
|
||||
|
||||
install(TARGETS qr_detector_nodelet
|
||||
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||
)
|
||||
|
||||
install(DIRECTORY include/${PROJECT_NAME}/
|
||||
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION})
|
||||
|
||||
install(DIRECTORY launch
|
||||
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
|
||||
|
||||
install(FILES nodelets.xml
|
||||
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
|
||||
)
|
||||
@@ -0,0 +1,27 @@
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2017-, Michal Drwiega (drwiega.michal@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,11 @@
|
||||
## qr_detector
|
||||
The QR codes detector based on zbar library (http://zbar.sourceforge.net), dedicated to ROS systems.
|
||||
|
||||
Installation of zbar library on Ubuntu
|
||||
`sudo apt install libzbar-dev`
|
||||
|
||||
Subscribes:
|
||||
- **/image** (sensor_msgs/Image) - the topic with RGB images which contains QR codes.
|
||||
|
||||
Publishes:
|
||||
- **/qr_codes** (std_msgs/String) - message from each detected QR code is published as a string.
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include "zbar.h"
|
||||
|
||||
namespace qr_detector {
|
||||
|
||||
struct Tag {
|
||||
std::string message;
|
||||
std::vector<cv::Point> polygon;
|
||||
};
|
||||
|
||||
using Tags = std::vector<Tag>;
|
||||
|
||||
/**
|
||||
* Main QR codes detector class
|
||||
*/
|
||||
class Detector {
|
||||
public:
|
||||
Detector();
|
||||
~Detector() = default;
|
||||
|
||||
/**
|
||||
* Detects tags in image.
|
||||
*
|
||||
* @param[in] image - image with qr tags
|
||||
* @param[in] timeout - max time for tags detection in ms
|
||||
*/
|
||||
Tags detect(const cv::Mat& image, size_t timeout = 100);
|
||||
|
||||
protected:
|
||||
zbar::ImageScanner scanner_;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <ros/ros.h>
|
||||
#include <nodelet/nodelet.h>
|
||||
#include <image_transport/image_transport.h>
|
||||
|
||||
#include "qr_detector/detector.h"
|
||||
|
||||
namespace qr_detector {
|
||||
|
||||
class QrDetectorNodelet : public nodelet::Nodelet {
|
||||
public:
|
||||
QrDetectorNodelet();
|
||||
virtual ~QrDetectorNodelet();
|
||||
|
||||
private:
|
||||
void onInit() override;
|
||||
void connectCallback();
|
||||
void disconnectCallback();
|
||||
void imageCallback(const sensor_msgs::ImageConstPtr& image);
|
||||
|
||||
ros::NodeHandle nh_;
|
||||
image_transport::ImageTransport it_;
|
||||
image_transport::Subscriber img_subscriber_;
|
||||
ros::Publisher tags_publisher_;
|
||||
Detector detector_;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<launch>
|
||||
<node name="usb_cam" pkg="usb_cam" type="usb_cam_node" output="screen" >
|
||||
<param name="video_device" value="/dev/video0" />
|
||||
<param name="image_width" value="640" />
|
||||
<param name="image_height" value="480" />
|
||||
<param name="pixel_format" value="yuyv" />
|
||||
<param name="camera_frame_id" value="usb_cam" />
|
||||
<param name="io_method" value="mmap"/>
|
||||
</node>
|
||||
|
||||
<node pkg="nodelet"
|
||||
type="nodelet"
|
||||
name="qr_detector"
|
||||
args="standalone qr_detector/qr_detector_nodelet">
|
||||
<remap from="image" to="usb_cam/image_raw"/>
|
||||
</node>
|
||||
|
||||
<node
|
||||
pkg="rqt_image_view"
|
||||
type="rqt_image_view"
|
||||
name="rqt_image_view"
|
||||
output="screen"
|
||||
/>
|
||||
</launch>
|
||||
@@ -0,0 +1,10 @@
|
||||
<library path="lib/libqr_detector_nodelet">
|
||||
|
||||
<class name="qr_detector/qr_detector_nodelet"
|
||||
type="qr_detector::QrDetectorNodelet"
|
||||
base_class_type="nodelet::Nodelet">
|
||||
<description>
|
||||
QR detector nodelet.
|
||||
</description>
|
||||
</class>
|
||||
</library>
|
||||
@@ -0,0 +1,24 @@
|
||||
<package format="2">
|
||||
<name>qr_detector</name>
|
||||
<version>1.0.0</version>
|
||||
<description>
|
||||
QR codes detector based on zbar library (http://zbar.sourceforge.net)
|
||||
</description>
|
||||
<author email="drwiega.michal@gmail.com">Michal Drwiega (http://www.mdrwiega.com)</author>
|
||||
<maintainer email="drwiega.michal@gmail.com">Michal Drwiega</maintainer>
|
||||
<license>BSD</license>
|
||||
<url type="website">http://ros.org/wiki/qr_detector</url>
|
||||
|
||||
<buildtool_depend>catkin</buildtool_depend>
|
||||
|
||||
<depend>roscpp</depend>
|
||||
<depend>nodelet</depend>
|
||||
<depend>zbar</depend>
|
||||
<depend>sensor_msgs</depend>
|
||||
<depend>cv_bridge</depend>
|
||||
<depend>image_transport</depend>
|
||||
|
||||
<export>
|
||||
<nodelet plugin="${prefix}/nodelets.xml"/>
|
||||
</export>
|
||||
</package>
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "qr_detector/detector.h"
|
||||
|
||||
#include <cv_bridge/cv_bridge.h>
|
||||
|
||||
namespace qr_detector {
|
||||
|
||||
Detector::Detector() : scanner_()
|
||||
{
|
||||
scanner_.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1);
|
||||
}
|
||||
|
||||
Tags Detector::detect(const cv::Mat& image, size_t timeout)
|
||||
{
|
||||
cv::Mat grayImg;
|
||||
cv::cvtColor(image, grayImg, CV_BGR2GRAY);
|
||||
|
||||
const auto width = image.cols;
|
||||
const auto height = image.rows;
|
||||
|
||||
zbar::Image img(width, height, "Y800", grayImg.data, width * height);
|
||||
scanner_.scan(img);
|
||||
|
||||
Tags tags;
|
||||
for (auto s = img.symbol_begin(); s != img.symbol_end(); ++s)
|
||||
{
|
||||
Tag tag;
|
||||
tag.message = s->get_data();
|
||||
|
||||
for(int i = 0; i < s->get_location_size(); i++) {
|
||||
tag.polygon.push_back(cv::Point(s->get_location_x(i), s->get_location_y(i)));
|
||||
}
|
||||
tags.push_back(tag);
|
||||
}
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#include "qr_detector/qr_detector_nodelet.h"
|
||||
|
||||
#include "pluginlib/class_list_macros.h"
|
||||
#include <cv_bridge/cv_bridge.h>
|
||||
#include <sensor_msgs/image_encodings.h>
|
||||
#include "std_msgs/String.h"
|
||||
|
||||
PLUGINLIB_EXPORT_CLASS(qr_detector::QrDetectorNodelet, nodelet::Nodelet);
|
||||
|
||||
namespace qr_detector {
|
||||
|
||||
QrDetectorNodelet::QrDetectorNodelet()
|
||||
: it_(nh_)
|
||||
{ }
|
||||
|
||||
QrDetectorNodelet::~QrDetectorNodelet()
|
||||
{
|
||||
img_subscriber_.shutdown();
|
||||
}
|
||||
|
||||
void QrDetectorNodelet::onInit()
|
||||
{
|
||||
nh_ = getNodeHandle();
|
||||
|
||||
tags_publisher_ = nh_.advertise<std_msgs::String>("qr_codes", 10,
|
||||
std::bind(&QrDetectorNodelet::connectCallback, this),
|
||||
std::bind(&QrDetectorNodelet::disconnectCallback, this));
|
||||
|
||||
NODELET_INFO_STREAM("Initializing nodelet... [" << nh_.getNamespace() << "]");
|
||||
}
|
||||
|
||||
void QrDetectorNodelet::connectCallback()
|
||||
{
|
||||
if (!img_subscriber_ && tags_publisher_.getNumSubscribers() > 0)
|
||||
{
|
||||
NODELET_INFO("Connecting to image topic.");
|
||||
img_subscriber_ = it_.subscribe("image", 1, &QrDetectorNodelet::imageCallback, this);
|
||||
}
|
||||
}
|
||||
|
||||
void QrDetectorNodelet::disconnectCallback()
|
||||
{
|
||||
if (tags_publisher_.getNumSubscribers() == 0)
|
||||
{
|
||||
NODELET_INFO("Unsubscribing from image topic.");
|
||||
img_subscriber_.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
void QrDetectorNodelet::imageCallback(const sensor_msgs::ImageConstPtr &image)
|
||||
{
|
||||
cv_bridge::CvImageConstPtr cv_image;
|
||||
|
||||
try {
|
||||
cv_image = cv_bridge::toCvShare(image, sensor_msgs::image_encodings::BGR8);
|
||||
}
|
||||
catch (cv_bridge::Exception& e) {
|
||||
ROS_ERROR("cv_bridge exception: %s", e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
auto tags = detector_.detect(cv_image->image, 10);
|
||||
for (auto& tag : tags)
|
||||
{
|
||||
std_msgs::String msg;
|
||||
msg.data = tag.message;
|
||||
tags_publisher_.publish(msg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user