CreativeInquiry/PEmbroider

could we add skeleton tracing ?

stephanschulz opened this issue · 7 comments

I am adding exchange I had with Golan here to better add to this idea.

I said:
i understand that where ever white meets black a line will be stitched. is there a way to say those two lines are very close and should be considered as just one?
for example this snake would ideally be defined by single stitch lines.
here are original BW image and P5 output image. when you zoom in you see the double lines i’m talking about.
snake_bw (1)
snake_bw

Then Golan kindly replied with this input:

Hi Stephan! For a design like this I might recommend a different process for getting single lines (instead of double lines) for the scales of the snake. Specifically, you could take an image of the [black gaps between the] scales, invert it (so they become white lines) and then "skeletonize" those white lines using a Processing library like @lingdong’s "https://github.com/LingDong-/skeleton-tracing" tool, which will produce vector lines.

Then I said:

thanks for the tip.
this works very well. i used the OF example provided in Lingdong’s repo.

Screen Shot 2020-08-04 at 9 13 31 PM

I added to Lingdong's open frameworks example the option to export an SVG of an image.
https://gist.github.com/stephanschulz/70df823c91f93c64335f0ee84ec12b75

I am now wondering if this might be something we should actually build in to the P5 library?
It is very nice to be able to just draw single lines instead of having to get a double or fill for those white lines in the image.

Hi @stephanschulz, (cc @LingDong- )
Thanks for bringing this issue forward from the Slack.

I consider skeleton tracing to be outside the scope of the PEmbroider project. PEmbroider is intended to be a lightweight bridge between Processing's drawing commands, and embroidery file output. It is not really intended to be a tool just to load pre-made SVGs for embroidery (there are better free tools for that purpose). And since there exists a Processing-compatible code library for tracing skeletons, anyone who needs this functionality is free to add it to their own project, just as they can with all of the other great functionality in the Processing library ecosystem. What we can do, based on your suggestion, and I think it's a very good idea, is to make a well-documented example program that uses it.

Best
Golan

You are right. Let's not make it too bloated.
I was not aware of this processing implementation. I should have know that Lingdong is thorough :)

Screen Shot 2020-08-05 at 10 21 47 PM

@stephanschulz @golanlevin

Example added: examples/PEmbroider_trace_skeleton e2cb3ca

import traceskeleton.*;
import processing.embroider.*;
PEmbroiderGraphics E;

void setup() {
  size (1200,700);

  E = new PEmbroiderGraphics(this);
  
  PImage img = loadImage("blobfish.png");
  
  boolean[] im = new boolean[img.width*img.height];
  img.loadPixels();
  for (int i = 0; i < im.length; i++){
    im[i] = (img.pixels[i]>>16&0xFF)>128;
  }
  ArrayList<ArrayList<int[]>>  c;

  int W = img.width;
  int H = img.height;

  TraceSkeleton.thinningZS(im,W,H);
  c = TraceSkeleton.traceSkeleton(im,W,H,0,0,W,H,10,999,null);

  for (int i = 0; i < c.size(); i++){
    E.beginShape();
    for (int j = 0; j < c.get(i).size(); j++){
      E.vertex(c.get(i).get(j)[0],c.get(i).get(j)[1]);
    }
    E.endShape();
  }
  E.optimize();
  
  tint(255,50);
  image(img,0,0);
  tint(255);
  E.visualize(false,true,true);
}

Perfect, good solution.