Using OpenCV with Gazebo in Robot Operating System (ROS) — Part 2— Read and decode a QR Code present in Gazebo with pyzbar library
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.
- Convert the image to a grayscale image with
COLOR_BGR2GRAY
function that’s available in cv2 - 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.
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 8
imports the decode function that is available in pyzbar library.
Image preprocessing
line 29
is 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,255
means all pixel values above 40, will be set to 255(white).
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 38
prints 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 45
draws 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
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!