Synthetic Dataset Generation for Custom 3D Object Using Blender
During my thesis work I faced the problem of how purely documented is the subject of synthetically generated learning datasets for custom 3D objects, so here are my tips.
Note: Since I wrote this post, several other people tried this with (probably) more understandable and effective codes, so I recommend checking them as well:
Either way this is still a 100% usable guide, and it worked once in 2020 so it should do today. Gave fun! :)
Why would you need this?
You might work in a simulation environment where pretrained neural networks won’t work as precise as you expect or you just can’t find any public dataset for the object you want to detect. In my case this is exactly what happened, I worked with drones using ROS and Gazebo, and I wanted to use the drone camera image to detect objects with it using YOLO.
Sources
My project is heavily inspired from this post from Oles Tourko about ConvNet training data with Blender. Check out his work, it’s very very very useful.
Guide
Okay, so I had a cute 3D model of a penguin (stole it from here) and I really wanted to make my network to detect it, therefore I had to generate a huuuge amount of training data from the model, like render images. My model was compatible with Blender, so I load it in, then used Blender Python API. Here is a simple video to understand the very basics of it, but honestly it’s fairly easy to use.
Code
Aaaand here is the script I used.
Step by step
The function names and comments in code are pretty straightforward IMO, so I won’t explain it in depth. Basically the following things happens: (in a for loop)
Rotate the object (in my case this wholesome emperor penguin)
Put the default light in a random location in selected range - Honestly not even sure if its neccessary, but whatever
The third function works exactly like the previous one, just move the camera.
Direct the camera to point to the center point of penguin.
Next we render the picture! Yay!
Then the scritps just creates a txt file for each image in the right format for YOLO training.
So yes, the only tricky part (calculation of bounding box coordinates on render images) can be found here with more comments.
Extra script for adding background
If you have paid attention you may see that the generated renders have transparent background and saved in png format. I decided to do this, because I didn’t found a simple solution for adding background in blender to the renders. I created a seperate script (NOT a Blender script), that can be executed after the first one completed. (Inspired by this stackoverflow thread)
Training
And at this point I had everything to start the training. It can be easily done by following the official guide for Darknet. Good luck!