diff --git a/qr_detector/CHANGELOG.rst b/qr_detector/CHANGELOG.rst deleted file mode 100644 index 3f771e6..0000000 --- a/qr_detector/CHANGELOG.rst +++ /dev/null @@ -1,8 +0,0 @@ -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Changelog for package qr_detector -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -1.0.0 (2017-05-01) ------------------- -* QR detection wrapper on zbar implemented -* Contributors: Michal Drwiega diff --git a/qr_detector/CMakeLists.txt b/qr_detector/CMakeLists.txt deleted file mode 100644 index e520dec..0000000 --- a/qr_detector/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -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} -) diff --git a/qr_detector/LICENSE b/qr_detector/LICENSE deleted file mode 100644 index 206ff2f..0000000 --- a/qr_detector/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ - * 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. diff --git a/qr_detector/README.md b/qr_detector/README.md deleted file mode 100644 index cf9705e..0000000 --- a/qr_detector/README.md +++ /dev/null @@ -1,11 +0,0 @@ -## 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. \ No newline at end of file diff --git a/qr_detector/include/qr_detector/detector.h b/qr_detector/include/qr_detector/detector.h deleted file mode 100644 index a44084e..0000000 --- a/qr_detector/include/qr_detector/detector.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include -#include -#include "zbar.h" - -namespace qr_detector { - -struct Tag { - std::string message; - std::vector polygon; -}; - -using Tags = std::vector; - -/** - * 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_; -}; - -} diff --git a/qr_detector/include/qr_detector/qr_detector_nodelet.h b/qr_detector/include/qr_detector/qr_detector_nodelet.h deleted file mode 100644 index 0fb37e8..0000000 --- a/qr_detector/include/qr_detector/qr_detector_nodelet.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include -#include -#include - -#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_; -}; - -} diff --git a/qr_detector/package.xml b/qr_detector/package.xml deleted file mode 100644 index 764b08f..0000000 --- a/qr_detector/package.xml +++ /dev/null @@ -1,24 +0,0 @@ - - qr_detector - 1.0.0 - - QR codes detector based on zbar library (http://zbar.sourceforge.net) - - Michal Drwiega (http://www.mdrwiega.com) - Michal Drwiega - BSD - http://ros.org/wiki/qr_detector - - catkin - - roscpp - nodelet - zbar - sensor_msgs - cv_bridge - image_transport - - - - - \ No newline at end of file diff --git a/qr_detector/src/detector.cpp b/qr_detector/src/detector.cpp deleted file mode 100644 index 9a233e5..0000000 --- a/qr_detector/src/detector.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "qr_detector/detector.h" - -#include - -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; -} - -} diff --git a/qr_detector/src/qr_detector_nodelet.cpp b/qr_detector/src/qr_detector_nodelet.cpp deleted file mode 100644 index 97eafd8..0000000 --- a/qr_detector/src/qr_detector_nodelet.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "qr_detector/qr_detector_nodelet.h" - -#include "pluginlib/class_list_macros.h" -#include -#include -#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("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); - } -} - -} diff --git a/robot_vision/CMakeLists.txt b/robot_vision/CMakeLists.txt index 506885a..a364407 100644 --- a/robot_vision/CMakeLists.txt +++ b/robot_vision/CMakeLists.txt @@ -3,6 +3,7 @@ project(robot_vision) ## Compile as C++11, supported in ROS Kinetic and newer # add_compile_options(-std=c++11) +set(CMAKE_CXX_FLAGS "-std=c++11 -Wall ${CMAKE_CXX_FLAGS}") ## Find catkin macros and libraries ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) @@ -11,6 +12,9 @@ find_package(catkin REQUIRED COMPONENTS cv_bridge image_transport roscpp + nodelet + cv_bridge + image_transport rospy sensor_msgs std_msgs @@ -108,10 +112,9 @@ generate_messages( ## CATKIN_DEPENDS: catkin_packages dependent projects also need ## DEPENDS: system dependencies of this project that dependent projects also need catkin_package( -# INCLUDE_DIRS include -# LIBRARIES robot_vision -# CATKIN_DEPENDS cv_bridge image_transport roscpp rospy sensor_msgs std_msgs -# DEPENDS system_lib + INCLUDE_DIRS include + LIBRARIES qr_detector_nodelet + CATKIN_DEPENDS roscpp nodelet sensor_msgs cv_bridge image_transport ) ########### @@ -120,8 +123,10 @@ catkin_package( ## Specify additional locations of header files ## Your package locations should be listed before other locations +find_library(ZBAR_LIBRARIES NAMES zbar) + include_directories( -# include + include ${catkin_INCLUDE_DIRS} ) @@ -129,6 +134,8 @@ include_directories( # add_library(${PROJECT_NAME} # src/${PROJECT_NAME}/robot_vision.cpp # ) +add_library(qr_detector_nodelet src/qr_detector_nodelet.cpp) + ## Add cmake target dependencies of the library ## as an example, code may need to be generated before libraries @@ -154,6 +161,7 @@ include_directories( # target_link_libraries(${PROJECT_NAME}_node # ${catkin_LIBRARIES} # ) +target_link_libraries(qr_detector_nodelet zbar ${catkin_LIBRARIES}) ############# ## Install ## diff --git a/robot_vision/doc/qr_code.pdf b/robot_vision/doc/qr_code.pdf new file mode 100644 index 0000000..9030e18 Binary files /dev/null and b/robot_vision/doc/qr_code.pdf differ diff --git a/robot_vision/include/qr_detector/qr_detector_nodelet.h b/robot_vision/include/qr_detector/qr_detector_nodelet.h new file mode 100644 index 0000000..5f859ea --- /dev/null +++ b/robot_vision/include/qr_detector/qr_detector_nodelet.h @@ -0,0 +1,81 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace qr_detector { + +struct QrTag { + std::string qr_msg; + std::vector square_apex_vector; +}; + +using QrTags = std::vector; + +class QrDetector { +public: + QrDetector() { + scanner_.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1); + } + + QrTags detect(const cv::Mat& image) { + cv::Mat gray_img; + cv::cvtColor(image, gray_img, CV_BGR2GRAY); + + const uint64_t width = image.cols; + const uint64_t height = image.rows; + zbar::Image img(width, height, "Y800", gray_img.data, width*height); + scanner_.scan(img); + + QrTags tags; + for (auto s = img.symbol_begin(); s != img.symbol_end(); ++s) { + QrTag tag; + tag.qr_msg = s->get_data(); + for (int i = 0; i < s->get_location_size(); i++) { + tag.square_apex_vector.push_back(cv::Point(s->get_location_x(i), s->get_location_y(i))); + } + + tags.push_back(tag); + } + + return tags; + } + +private: + zbar::ImageScanner scanner_; +}; + +class QrDetectorNodelet : public nodelet::Nodelet { +public: + QrDetectorNodelet(); + virtual ~QrDetectorNodelet(); + + void onInit() override; + +private: + void DownstreamConnectCb(); + void DownstreamDisconnectCb(); + void ImageCb(const sensor_msgs::ImageConstPtr& image); + +private: + ros::NodeHandle nh_; + image_transport::ImageTransport it_; + image_transport::Subscriber img_sub_; + ros::Publisher qr_pub_; + QrDetector detector_; +}; + +} + + + + + + + diff --git a/qr_detector/launch/detector.launch b/robot_vision/launch/qr_detector.launch similarity index 88% rename from qr_detector/launch/detector.launch rename to robot_vision/launch/qr_detector.launch index 775d5de..9fb0d7d 100644 --- a/qr_detector/launch/detector.launch +++ b/robot_vision/launch/qr_detector.launch @@ -11,7 +11,8 @@ + output="screen" + args="standalone robot_vision/qr_detector_nodelet"> diff --git a/qr_detector/nodelets.xml b/robot_vision/nodelets.xml similarity index 82% rename from qr_detector/nodelets.xml rename to robot_vision/nodelets.xml index c0932d7..2bfebfd 100644 --- a/qr_detector/nodelets.xml +++ b/robot_vision/nodelets.xml @@ -1,6 +1,6 @@ - diff --git a/robot_vision/package.xml b/robot_vision/package.xml index 2905437..4114001 100644 --- a/robot_vision/package.xml +++ b/robot_vision/package.xml @@ -52,26 +52,32 @@ cv_bridge image_transport roscpp + nodelet + zbar + image_transport rospy sensor_msgs std_msgs cv_bridge image_transport roscpp + nodelet + zbar + image_transport rospy sensor_msgs std_msgs cv_bridge image_transport roscpp + nodelet + zbar + image_transport rospy sensor_msgs std_msgs - - - - + diff --git a/robot_vision/src/qr_detector_nodelet.cpp b/robot_vision/src/qr_detector_nodelet.cpp new file mode 100644 index 0000000..c417b66 --- /dev/null +++ b/robot_vision/src/qr_detector_nodelet.cpp @@ -0,0 +1,62 @@ +#include "qr_detector/qr_detector_nodelet.h" + +#include +#include +#include +#include + +PLUGINLIB_EXPORT_CLASS(qr_detector::QrDetectorNodelet, nodelet::Nodelet); + +namespace qr_detector { + +QrDetectorNodelet::QrDetectorNodelet() : it_(nh_) { + ROS_INFO("QrDetectorNodelet Constructor"); +} + +QrDetectorNodelet::~QrDetectorNodelet() { + img_sub_.shutdown(); + ROS_INFO("QrDetectorNodelet Destructor"); +} + +void QrDetectorNodelet::onInit() { + nh_ = getNodeHandle(); + qr_pub_ = nh_.advertise("/qr_codes", 10, + std::bind(&QrDetectorNodelet::DownstreamConnectCb, this), + std::bind(&QrDetectorNodelet::DownstreamDisconnectCb, this)); + ROS_INFO("init qr detector nodelet, nodehand name %s", nh_.getNamespace().c_str()); +} + +void QrDetectorNodelet::DownstreamConnectCb() { + if (!img_sub_ && qr_pub_.getNumSubscribers() > 0) { + img_sub_ = it_.subscribe("image", 1, &QrDetectorNodelet::ImageCb, this); + ROS_INFO("subscribe image topic from usb_cam"); + } +} + +void QrDetectorNodelet::DownstreamDisconnectCb() { + if (qr_pub_.getNumSubscribers() == 0) { + img_sub_.shutdown(); + ROS_INFO("unsubscibe image topic"); + } +} + +void QrDetectorNodelet::ImageCb(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; + } + + QrTags qr_tags = detector_.detect(cv_image->image); + for (auto& qr_tag : qr_tags) { + std_msgs::String msg; + msg.data = qr_tag.qr_msg; + + qr_pub_.publish(msg); + } +} + +} \ No newline at end of file