Victor is a registered member of Data Science Nigeria and an electrical and electronic student of Obafemi Awolowo University. A mastermind.
Trace My Pen
Welcome back folks to another episode of the tutorial on opencv. Permit me to share with you a quick story. Sometimes ago, my colleagues tried to build a device using a gyro-meter which could be used to write directly into a PC, the idea was to write on any surface and get corresponding results on the PC. Cool right, it's like writing instead of typing. Yes, they made the device, but on the day of the project defence, Dr Akintade (One of the conducting lecturers) disagreed with the idea. He claimed that the gyroscope should have a point of origin on the (x,y,z) Axis so the software back-end could take reasonable measurements and convert to traces. This eventually brings us to this quick trace project, where we detect the color of my object(Pen) And track it's movement.
The pipeline is quite easy, first is to get the frame, mask out all other color regions asides our color of interest, and lastly draw a bounding circle for the contour as well as a line between the position of where the contour was found last and where is is now.
Firstly, we import the packages needed to run the algorithm. If you've been following my previous tutorials, the only package new to you may be deque. The deque is just a form of list with super-fast edits, like fast appends, fast pops, and more. It even has an append-left feature which will be very useful in this project.
Time is another package available in python which helps us keep track of real time.
In the short code below, I defined the upper and lower boundary for the color of my object (Red pen), I actually used trial by error method to get a good span for the upper and lower color boundary, I left the tip to do this down in the bonus section.
Having defined these, I initialized points to be a deque (Think of it like a speed list) With maximum length of 64, the max length there pops out the item in the list when I append a new one. Finally I start the video stream giving it some 2 seconds to warm up.
The Big Deal
In this section, we do everything. First, I placed the whole process in a while loop since a video is nothing more than continuous moving frame of pictures.
In the next line I read off the frame from the video master, next, I separated the ret and frame. The ret is simply just a boolean regarding whether there was a return at all from the vs.Read(). Next if there is nothing in the frame, break stop the process.Another way could be if ret is false, break. In the next line, I used imutils to resize the frame. The imutils resize saves a lot of stress in preserving the aspect ratio than stressful standard opencv methods of resizing.
Following that, I decided to flip the image. I did this to obtain the mirror view of my frame which is absolutely quite cool for direct streaming from the camera.
Processing the Frame.
The frame is ready, first I blurred the frame using the popular Gaussian blur method, this helps to reduce noise in the image. Next, I converted the color from the BGR to HSV. The HSV is a color band which means hue, saturation and value. It is a color representation closer to the human vision(Our way of seeing).
In the next step, I created a mask by using the image threshold such that I save out only colors within my upper and lower boundary, which in this case is the color of my red pen. After masking out other parts of the image, I performed erosion, and dilation to further reduce high frequency noise caused by taking images to their threshold.
All Said and Done
Now that I've gotten a view of the object (My red pen), I found the contours, grabbed them using imutils. In the following if statement, I picked out the contour with the maximum area, which is definitely the contour of my object, the remaining contours I'm quite positive is just noise. Unless if you plan to track two objects of the same color. In the next line, I prepared parameters required to construct a bounding circle on the object. The first is the radius and the x,y co-ordinates, next I used cv2.Moments to obtain it's center of mass. The last if loop was written such that if the radius is reasonable enough, I draw a bounding circle around my object as well as a filled in dot at the center of the object.
Very importantly, i append-left the center of my object to the deque. Remember that my deque has a max-length of 64. I'll explain why i did this shortly.
The last and final step is to draw the traces. To do this I decided to connect all my points in order with a single line, like in a chain form. I also specified that if the value in the list is none, it should ignore and start the while loop all over. I did this so that I avoid drawing a point at (0,0) Which is (None,none) On my frame when the object is not detected.
On the other hand, if I find my object, it connects all 64 dots together and traces it out. I used a max-length of 64 to avoid my screen from getting all messed up with traces. See the effects yourself. Run the code.
This concludes the tutorial on tracing my red pen with opencv.
How on earth did i find out the HSV values for my red pen. I am no magician, i'm a programmer and i definitely do not know all things. You can look up on google for the HSV values for your color of interest and test them down here with this short code like i did(trial by error). I have put the code in a RAWNB format.
Olufemi Victor (author) from Nigeria on August 13, 2020:
Download the full code and run on your pc from my github repository.