Introduction: Openscad: Tracing a Custom Line in a Photo Image V7
(my scad file was corrupted. Just uploaded a clean file, Feb 3, 2021)
For various reasons, I wanted to find a particular irregular path in a photograph. With the result to be an openscad array of the XY datapoints tracing along the line's path.
It was acceptable to require manually tracing the path in Photoshop, brushing out a mono-color line along the desired path, using a paintbrush. This manual tracing of the color line requires the line to be 4 pixels wide, and such must be the setting of the paintbrush in Photoshop. NOTE: once a line is drawn with the 4 pixel brush, *don't change the image resolution* as that will change the line width!
I generalized a bit, to a) allow multiple, possibly overlapping lines per image, by b) putting a row of color blocks along the bottom of the image, where each color block is the trace line color, blocks terminated by a white block. Trace lines cannot be white or black, but any other color is fine.
The function searches along the left margin of the image to find the start of a line trace matching the first color. It traces the line, recording the points.
Then repeat for the next color block.
Lines can cross, when sufficiently perpendicular.
Two example images show the resulting openscad lines, on top of a surface() of the image.
Here is the OpenScad console trace for the test file Line_test2.txt
Loaded design 'P:/line-tracing-v7.scad'.
Parsing design (AST generation)...
Compiling design (CSG Tree generation)...
ECHO: "find line start", 0, "XYstart", [0, 2], "ref color", [42, 240, 247], "SunitV", [0, 1]
ECHO: "color box", [42, 240, 247], "noneFound at XY?", [false, [0, 116]]
ECHO: "line for color", [42, 240, 247], "has length", 368
ECHO: "find line start", 1, "XYstart", [0, 2], "ref color", [233, 51, 51], "SunitV", [0, 1]
ECHO: "color box", [233, 51, 51], "noneFound at XY?", [false, [0, 55]]
ECHO: "line for color", [233, 51, 51], "has length", 873
ECHO: "Image with lines, y rows", 600, " x rgb cols", 600
ECHO: "Ref Colors For Line Search", [[42, 240, 247], [233, 51, 51]]
ECHO: "show line", 0, "of length", 368
ECHO: "show line", 1, "of length", 873
Compiling design (CSG Products generation)...
Geometries in cache: 5
Geometry cache size in bytes: 104192248
CGAL Polyhedrons in cache: 0
CGAL cache size in bytes: 0
Compiling design (CSG Products normalization)...
Normalized CSG tree has 3 elements
Compile and preview finished.
Total rendering time: 0 hours, 1 minutes, 0 seconds
Step 1: Converting the Image to an Openscad Array
Python script png-rcol.py takes one argument, a .png file, and converts it to an openscad array. This array has one row for each pixel row. Each pixel row is a series of 3 color intensities R, G, and B, at each pixel.
The output of png-rcol is redirected to a text file.
python3 png-rcol.py Line_test2.png > Line_test2.txt
python3 png-rcol.py SF_Topo.png > SF_Topo.txt
Step 2: Openscad Functions
The main functions of this script are invoked in the example at the end of the file.
1. include the image.txt file and fix the assignment to use the array name created by png-rcol.py. The array name is the name of the .png file, with "-" replaced by "_".
2. edit the surface() function to name the .png file.
3. function LT_ColorTraceList() searches for the row of color boxes at the lower left of the image, terminated by a white box.
4. function LT_buildTopLineList() looks for each line in turn, using the specified starting point. It returns an array of line points, one array per color line.
5. function ShowLinePoints() is for debugging, to show the results of finding the color lines.