Using OpenCV with Gazebo in Robot Operating System (ROS) — Part 2— Read and decode a QR Code present in Gazebo with pyzbar library

Dhanush B
5 min readFeb 14, 2021

We’ll be expanding on the code that we built in Part — 1 of this series. If you haven’t tried that out, make sure you go back, try, and come back here!

Link to Part — 1 of this series

Link to GitHub repo

It contains all the scripts, models and world files that are used in this tutorial series.

Launching the gazebo world

Before running the next command make sure you have run git pull and sourced the setup.bash file that’s in {your_workspace_name}/devel/ folder.

Then, to launch the gazebo world, run this command in terminal.

$ roslaunch pkg_cv_ros_tutorial_by_dhanuzch 2_world.launch

This should launch a gazebo world that has a wall with QR code on it and a camera. It should look something like this…

If you can see this, Congrats! You have set everything correctly as of now.

Alternatively, if you want to launch gazebo world and start running the script out of the box. Then run

$ roslaunch pkg_cv_ros_tutorial_by_dhanuzch 2_world_and_script.launch

If you wanna know how the code works, then continue reading…

Image preprocessing

Before jumping on to the code, you gotta know about this thing called image preprocessing. It is something that we have to do to get meaningful data out of the raw camera output. Here’s an article on ‘Image pre-processing’ that I personally found useful. We’d be using some very basic preprocessing techniques in this tutorial. Below, I’ve discussed one of many ways to preprocess images to decode QR codes.

  1. Convert the image to a grayscale image with COLOR_BGR2GRAY function that’s available in cv2
  2. Since QR Codes are generally made up of two colors, we can make use of the threshold function. With that function, we can convert grayscale image that we obtained above, to a binary image that only has two colours, black and white.
Left — Camera output window | Middle — The image after using COLOR_BGR2GRAY function | Right — After using ‘threshold’ function

Notice how clear the image is, after preprocessing. Now let’s move on to the code

The Code — Explained.

Since we are building up on the code that we discussed in Part — 1, I’ll be focusing only on the changes that were made.

This code is also available as a part of a package in my GitHub repo

pyzbar library

This library is is used to decode QR codes and barcodes, To learn more about this library, take a look at this article.

line 8imports the decode function that is available in pyzbar library.

Image preprocessing

line 29is to convert the resized_image to a grayscale image.

line 30 is to set a value for threshold. Note that threshold value depends on a lot of factors. And I’ve set it to 40. To learn about it in depth, take a look at the official guide.

line 31 converts the grayscale image to a binary image. Here, thresh,255means all pixel values above 40, will be set to 255(white).

In order Left to Right. thresh=0, thresh=40, thresh=120, thresh=255

Since the lighting conditions and the QR code is stable in this tutorial, we are taking this approach. But in real life using adaptive thresholding or other techniques might be the best bet.

Decoding

line 36 is the simplest 😛. All you have to do is call decode function with the image as an argument and the rest will be taken care by the pyzbar library. This will return decoded results.

line 38prints the decoded results.

The decoded result is as follows…

[Decoded(data="You're breathtaking!", type='QRCODE', rect=Rect(left=100, top=278, width=216, height=214), polygon=[Point(x=100, y=278), Point(x=100, y=490), Point(x=316, y=492), Point(x=315, y=278)])]

Doesn’t our output contain too many information?

To print just the decoded data. Let’s insert the following lines in our script.

qr_data = qr_result[0].data
print qr_data

Alright, this gives us the desired output. Which is… “You’re breathtaking” :) Don’t believe me? Here’s the output xD

Isn’t it slightly inconvenient to get the desired output in the terminal?

So, next we will try to print the data in Camera output window.

Drawing and writing meaningful stuff in cv window

Next, our goal is to draw a box over the detected QR Code and print the message on top of the box.

line 43 gets the position of QR code in window from qr_result

With the rectangle function available in cv2 and data obtained from line 43, line 45draws a rectangle around the QR code of colour red (0, 0, 255) and thickness 4

line 47 defines the format to print the data of QR Code

line 48 prints the data of QR code 10 pixels above the box. This is defined with (x, y-10), Font type is Hershey simplex. Colour is red (0, 0, 255) and thickness is 2. All these details will be printed in the window that displays resized_image

Yes senpai! You’re breathtaking :p

Now, try it with other QR codes. And see if the code works…

Lemme know in comments if you have any doubts or face difficulties. And also make sure to comment, what my next tutorial should be about!

That’s it for this series guys!

Bye!

--

--

Dhanush B

Hey! connect with me if you wanna talk about robotics, tech, philosophy and history.