While repairing a portable Cassette Tape Player, I needed a way to estimate the length of the rubber belts that were now deformed. Both of them.
Table of Contents
- How do you measure belts with kinks and bends ?
- OpenCV contour detection
- OpenCV Contour length
How do you measure belts with kinks and bends ?
It seems impossible to measure belts without overstretching the rubber to flatten the kinks and bends. Would there be a way to measure their length without stretching them ? Then deduce the diameter of a circle having the same circumference ? It would not avoid trial and error when picking the right belt, it would just be a starting point searching for a suitable replacement.
This article is meant for programmers 🙂
I got the idea to use software to measure the length while ensuring the photos are square with the gradations of cutting map. I know how many pixels correspond to the gradations. If an algorithm could identify the contour then measure its length in pixels, I could have a very good approximation to start with. And because there are many pixels, this should be close enough to reality.
OpenCV contour detection
I started off using OpenCV 4.6.0 for Java and this sample code: https://docs.opencv.org/3.4/df/d0d/tutorial_find_contours.html
First hurdle was on this line …
Imgproc.drawContours(drawing, contours, i, color, 2, Core.LINE_8, hierarchy, 0, new Point());
… since the compiler was throwing this error:
cannot find symbol
symbol: variable LINE_8
location: class Core
A bit of searching online and line definitions were moved from Core class to Imgproc class. The new way is
For the first run, I started of with the original high-res images cropped to only show the 10cm x 10cm center part. And with high-res images, the application seemed to have hanged. I then straightened the images and cropped them with RawTherapee and resized them to about 800x800px with IrfanView:
The images are around 800×800 pixels – which means about 80px / cm (or 8px / mm).
OpenCV sample code did not read my mind though, results were surprising and disappointing at the same time, EVERYTHING was a contour:
After some trial and error, I realized that unless I am able to extract a black and white image of the belt, OpenCV algorithm will pick on every little imperfection and call it a contour.
I tried few selection types in Gimp, but the easiest one to pick the belt only and not anything else was to use ‘Fuzzy Select’ with ‘Select by’ = ‘LCh Chroma’ with Threshold 30. Once the belt is selected, Ctrl-I to invert selection and hit Delete to remove the mat:
Now, OpenCV correctly identifies two contours:
OpenCV Contour length
After some more reading, the OpenCV way to determine the contour perimeter is to use Imgproc.arcLength:
MatOfPoint2f c2f = new MatOfPoint2f(contours.get(i).toArray());
double perimeter = Imgproc.arcLength(c2f, true);
Thus, with two continuous contours detected and outputting the length of both outside and inside contours:
I didn’t have all possible belt lengths to try, and among the choices I had – the belt that fitted properly is 5.5cm diameter. Thus, with all the approximation errors and the original belt being rather loose, I find the contour detection to be a very good result as a starting point.