When A Pig Started to learn OpenCV...
Background:
I have a goal of Stacking Jenga Blocks, but prior to that, I wanted to be able to fumble with images.
Short Goal:
So I started with this static photo of Jenga block that I took from my desktop camera. It would be great if I can draw accurate circles and labels around the Jenga blocks by the ned of this post.
Photo taken using IntelRealsense D435 camera; 640x480 pixals
Some usable outputs:
And the stupidity begins…
OpenCv 1:
1 | import cv2 as lv |
Typically, people import cv2 as cv, but why not make it un poco luxurious, so lv sounds richer to me. HAHAH!
Do not be afraid by OpenClaw:
OpenClaw once said “yeah, I got you.”
Reference Sample:
Check this only if you’re out of time. For me I find it useless for personal growth and critical thinking.
Show/Hide sample python code
1 |
|
Basic
If you know this, simply skip :)
1 | import numpy as py |
Once ran:
1 | (5,) |
The term shape provides tuple with each index representing the number of elements in that dimensions of a numpy array.
What about if we print:
1 | print(a.dtype) |
Once ran:
1 | float64 |
It is obvious that dtype is simply short for dog Type, um, data type I mean.
1 | block2 = dict( |
Imagine this is an actual block with values appended into the dictionary.
How should I access the values in the bracket?
1 | print(block["score"]) |
OK, this sounds nice, but what if there are no key, such as shadow? (could be any key)
An alternative method to get the key will be:
1 | print(block2.get('asd', "No such key!")) |
Iterating over A Dictionary
The default method that I first learned is:
1 | for item in block: |
But, there is a more elegant method by using .items and f string.
1 | for key, value in block.items(): |
.items() gives you both the key and value directly
Lambda
Normally when you write a function:
1 | def get_score(block): |
With lambda you don’t need to write a function, so it is single use.
1 | get_score_lambda = lambda b: b['score'] |
Examples: Nested Dictionaries
1 |
|
We have two blocks in this dictionary. What should I do when I want to find the _max() values?
1 | best, deepest = ( |
Enumerate
In simple terms, enumerate() provides you both the index and the value simultaneously.
Without:
1 |
|
With:
1 | for i, value in enumerate(centers): |
OpenCV 2:
OpenCv loads image in BGR order and not RGB.
In this project I tested multiple options such as Lab and HSV .
I realized that Saturation out performs or presents the best results.
Set Up
1 | import numpy as np |
Normal Exit would run as exit(0), yet if there is no such image as cv.png it would exit(1).
HSV Channel
1 | hsv = lv.cvtColor(img, lv.COLOR_BGR2HSV) |
During this period, I was still struggling to determine if hue or saturation works better. Still, I decided to separate them during the preprocessing step.
Gaussian Blur
1 | s_blur = lv.GaussianBlur(s_ch, (5, 5), 0) |
I can’t explain this in simple terms.
One obstacle, one villain that hinders me, Canny, from identifying edges is _NOISE, and un-smooth pixel transition.
Once this (5,5) GaussianBlur is applied, each pixel became an average of its 5x5 neighborhood.
This preprocessing step is vital because it increase the efficiency and accuracy of your actual detection.



