Package-Identification-using-Turtlebot
Robots have been used to improve efficiency in a various tasks in warehouses such as package handling, identification and organization. This project aims to simulate the use of Turtlebot in identifying packages with QR codes, in a warehouse setting.
Public Member Functions | List of all members
QReader Class Reference

Class QReader has methods to get the image and decode the QR code in the image to extract data of package ID. More...

#include <QReader.hpp>

Public Member Functions

 QReader ()
 Constructs a object. More...
 
 ~QReader ()
 Destroys the object. More...
 
void imageCb (const sensor_msgs::ImageConstPtr &msg)
 A function to get the raw image, from the camera and convert it to cv::Mat format using cv bridge. More...
 
cv::Mat processFrame ()
 
std::vector< uint8_t > decodeQR ()
 A function to get the raw image, find the QR code, unmask the QR code and decode the QR code in the image to extract data of package ID. More...
 
std::vector< uint8_t > returnBytes ()
 Function to get the extracted data array. More...
 
void setImage (cv::Mat image)
 Sets the value for the private value img. More...
 

Detailed Description

Class QReader has methods to get the image and decode the QR code in the image to extract data of package ID.

Constructor & Destructor Documentation

QReader::QReader ( )

Constructs a object.

56  : it(nh) {
57  std::string str = "unknown";
58  std::vector<uint8_t> bytes(str.begin(), str.end());
59  ROS_INFO("Inside QReader Constructor");
60  imgSub = it.subscribe("/camera/rgb/image_raw", 1, &QReader::imageCb, this);
61 }
void imageCb(const sensor_msgs::ImageConstPtr &msg)
A function to get the raw image, from the camera and convert it to cv::Mat format using cv bridge...
Definition: QReader.cpp:67
QReader::~QReader ( )

Destroys the object.

63 {}

Member Function Documentation

std::vector< uint8_t > QReader::decodeQR ( )

A function to get the raw image, find the QR code, unmask the QR code and decode the QR code in the image to extract data of package ID.

Parameters
none
Returns
Bytes containing the data in QR code in UTF-8 format
154  {
155  ros::Duration(3.0).sleep();
156  possibleCenters.clear();
157  estimatedModuleSize.clear();
158  ROS_INFO_STREAM("Decoding Image");
159  // Convert image to black and white
160  cv::cvtColor(img, img, CV_BGR2HSV);
161  inRange(img, cv::Scalar(0, 0, 200, 0), cv::Scalar(180, 255, 255, 0), img);
162  ROS_INFO_STREAM("Checking QR code existence");
163  bool found = checkQCodeExists(img);
164  std::vector<uint8_t> bytes;
165  // Check if QR code was found
166  if (found) {
167  ROS_INFO_STREAM("QR Code exists");
168  cv::Mat QR = warpToCode(img);
169  std::vector<std::vector<bool> > bitMatrix = extractBits(QR);
170 
171  unmask(bitMatrix);
172 
173  bytes = decodeArray(bitMatrix);
174  } else {
175  bytes = {0x75, 0x6E, 0x6B, 0x6E, 0x6F, 0x77, 0x6E}; // unknown
176  }
177  return bytes;
178 }
void QReader::imageCb ( const sensor_msgs::ImageConstPtr &  msg)

A function to get the raw image, from the camera and convert it to cv::Mat format using cv bridge.

Parameters
Themessage to subcribe to get the image from the turtlebot camera.
Returns
None
67  {
68  cv_bridge::CvImagePtr cvPtr;
69  try {
70  cvPtr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
71  ROS_INFO("Inside image callback");
72  } catch (cv_bridge::Exception& e) {
73  ROS_ERROR("cv_bridge exception: %s", e.what());
74  return;
75  }
76  img = cvPtr->image;
77  img = processFrame();
78 
79  // Decode the QR code in the image
80  bytes = decodeQR();
81 }
std::vector< uint8_t > decodeQR()
A function to get the raw image, find the QR code, unmask the QR code and decode the QR code in the i...
Definition: QReader.cpp:154
cv::Mat processFrame()
Definition: QReader.cpp:83
cv::Mat QReader::processFrame ( )
83  {
84  cv::Mat temp;
85  cv::cvtColor(img, temp, CV_BGR2HSV);
86  inRange(temp, cv::Scalar(0, 0, 200, 0), cv::Scalar(180, 255, 255, 0), temp);
87 
88  std::vector<std::vector<cv::Point> > contours;
89  std::vector<cv::Vec4i> hierarchy;
90  findContours(temp, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE,
91  cv::Point(0, 0));
92  // Threshold the counters
93  std::vector<std::vector<cv::Point> > contours_poly(contours.size());
94  std::vector<cv::Rect> boundRect(contours.size());
95  cv::Mat roi(img.rows, img.cols, CV_8UC3, cv::Scalar(0, 0, 0));
96  cv::Mat dst = cv::Mat::zeros(roi.size(), CV_32FC1);
97  cv::Mat dst_norm, dst_norm_scaled;
98  cv::Mat result;
99  std::vector<cv::Point2f> src;
100  src.clear();
101 
102  // Detect corners of the QR code for appropriate warping
103  for (int i = 0; i < contours.size(); i++) {
104  if (contourArea(contours[i]) > 40000) {
105  drawContours(roi, contours, i, cv::Scalar(255, 255, 255), CV_FILLED);
106  cv::cvtColor(roi, roi, CV_BGR2GRAY);
107  cornerHarris(roi, dst, 2, 3, 0.06);
108  normalize(dst, dst_norm, 0, 255, cv::NORM_MINMAX, CV_32FC1, cv::Mat());
109  convertScaleAbs(dst_norm, dst_norm_scaled);
110  for (int x = 0; x < dst_norm.rows; x++) {
111  for (int y = 0; y < dst_norm.cols; y++) {
112  if (static_cast<int>(dst_norm.at<float>(x, y)) > 200) {
113  src.push_back(cv::Point2f(y, x));
114  }
115  }
116  }
117  }
118  }
119  ROS_INFO("Number of corner points detected: %d",
120  static_cast<int>(src.size()));
121  std::vector<cv::Point2f> srcPoints;
122  cv::Point2f topLeft, topRight, bottomRight, bottomLeft;
123 
124  if (src.size() == 4) {
125  std::sort(
126  src.begin(), src.end(),
127  [](const cv::Point2f& a, const cv::Point2f& b) { return a.x < b.x; });
128 
129  if (src.at(0).x + src.at(0).y < src.at(1).x + src.at(1).y) {
130  topLeft = src.at(0);
131  bottomLeft = src.at(1);
132  } else {
133  topLeft = src.at(1);
134  bottomLeft = src.at(0);
135  }
136  if (src.at(2).x + src.at(2).y < src.at(3).x + src.at(3).y) {
137  topRight = src.at(2);
138  bottomRight = src.at(3);
139  } else {
140  topRight = src.at(3);
141  bottomRight = src.at(2);
142  }
143  srcPoints = {topLeft, topRight, bottomLeft, bottomRight};
144 
145  std::vector<cv::Point2f> dstPoints = {
146  cv::Point2f(0.0, 0.0), cv::Point2f(199.0, 0.0), cv::Point2f(0.0, 199.0),
147  cv::Point2f(199.0, 199.0)};
148  cv::Mat transform = getPerspectiveTransform(srcPoints, dstPoints);
149  warpPerspective(img, img, transform, cv::Size(200, 200), CV_INTER_LINEAR);
150  }
151  return img;
152 }
std::vector< uint8_t > QReader::returnBytes ( )

Function to get the extracted data array.

Parameters
none
Returns
array of bytes of data stored in the QR code
65 { return bytes; }
void QReader::setImage ( cv::Mat  image)

Sets the value for the private value img.

Parameters
cv::Matto set as value of img.
Returns
none
732 { img = image; }

The documentation for this class was generated from the following files: