I am working on a project that involves image processing for contour extraction and I’m seeking some guidance on the best approach. I have a basic understanding of Python, but I am open to solutions in C# as well, especially if they offer increased efficiency or ease of integration.
Objective: My goal is to process bitmap images to group adjacent pixels by color, and then output the outline of each clustered pixel group as a crv/polyline along with the related color value. These dimensions of these images wil be quite large, more towards the 4k to 8k resolution, with lost of fine details. For now I assume a high contrast image using black&white, but I assume that for the code method it should not make a difference what specific colors the source img has and how many distinct colors , maybe a filter to find specif color groups might be even usefull/faster
Current Approach: using some Python code that uses libraries like Numpy, and OpenCV. To finds contours for each unique value in the image, and then export these contours as crvs. Here is the sample code https://trinket.io/python3/8bb5b78429
But this required GH2 to work, so if an equivalent and fast method exists for GH1, i’'d definetly want to hear about it. I’m am perfectly ok, to use an external plugin if that does the job.
Previous Attempts: I have tried using the Trace Bitmap node such as provided by the Bitmap Plus plugin, but found that it doesn’t achieve the level of precision I am looking for
Exploring RTree: I am also considering the use of RTree for fast calculations of distances between pixel coordinates. Specifically, the RTree Closest Point component could potentially be employed to efficiently identify and group pixels based on spatial proximity, forming a basis for further color-based clustering (k-means ?). Any insights or experiences with such an approach would be greatly appreciated.
Exploring Mesh: Maybe make a mesh by the list of colors and maybe do something smart … stillno sure what
Assuming that you know how to Cluster things (let’s forget // for the monent)
:
Using some proper Class (in order to monitor the x/y cell value) Cluster your pixels. This yields a higher order collection (Tree) or … use suitable Properties in the Class to control the collections “within” the Class.
Each pixel has a center and 4 corners (monitor these using some Property as well).
So given some Cluster (i.e. a GroupBy pixel value result) order items (in x/y), separate islands (i.e. singular contacts) and then do a doule Loop and “trace” the outlines - so to speak.
Level required: mid to advanced. I have some C# that does that but is written a million years ago and I’m not sure where it is.
Or you can start using a Matrix (and cell vals representing Colors). If you want to visualize the Matrix remember that R/C 0,0 pos is the upper left corner.
BTW: Tons of related stuff around. Like:
BTW: did a quick search - but I’m not in the practice right now: the only C# found is something that given Voxels … yields a closed Mesh from the “outer” faces … meaning that somehow this is the 3d take of your 2d puzzle (kinda).
interesting links, good to know what terms to google for. I try to make a fast and scaleable script based upon both your inputs and share the results (optimistically i am aiming for 8k res processing in < 5 sec calculation)
Another - stupid/lazy- way could be: sample your pixels (as meshes) into the Class collection then GroupBy(x=>x.Color), then OrderBy(x=>x.Center.X).ThenBy(x=>x.Center.Y) and Append’m into a Mesh (per Group). Then just use the SplitDisjointPieces Method and then the GetNakedEdges Method per island (i.e. a Polyline where edges are connected with one Face).
But this is indeed kinda flying from DC to NY via LA. In fact is so stupid that I’m tempted to write another C# that is - more or less - the art of pointless.
However … give it a spin (Mesh ops [blame floats] are fast). And your Elapsed target (5000 milliseconds) is rather generous (hideous to me if you ask). All that prior implenenting some // approach (hope dies last).
Update: finish the attached (is pointless but then what isn’t?)
OK … stupid things are like Cuban cigars: the more the better.
So I did the right (i.e. the wrong) thing. Result? 100 ms VS 7K pixels as Meshes (using an ancient i5 - I always use a crap CPU when writing code). So expect 20 ms max (using ~10+K pixels) on an 14th gen I9 … plus a thread safe // approach.