4

It's possible to identify the edges of an image like so:

enter image description here

library('ggplot2')
library('imager')

plot(boats)
img <- cannyEdges(boats)
plot(img)

But suppose instead of the 'boats' object, we want to do the same thing to an svg (giraffe as an example below), how can we find the edges of the svg image?

enter image description here

I tried the obvious:

library(magick)
giraffe <- image_read_svg("http://steveharoz.com/research/isotype/icons/giraffe.svg")

plot(giraffe)
gimg <- cannyEdges(giraffe)
# Error in if (has.col) { : argument is of length zero

Note

What I'm ultimately trying to do is automatically convert an image of svg format (like the giraffe) into a set of cartesian coordinates for scatterplotting in a geom_point(), like so:

enter image description here

library(datasauRus)
library(ggplot2)

datasaurus_dozen %>% 
  filter(dataset == "dino") %>% 
  ggplot(aes(x=x, y=y))+
  geom_point()

The ultimate goal is the get the giraffe into a geom_point() like the dinosaur above

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
stevec
  • 41,291
  • 27
  • 223
  • 311
  • 1
    In the SVG format the lines are Bézier splines defined by anchors and tangents, and since the anchors are on the drawn line by construction, taking just the anchors could be sufficient. If they are too far apart, it is easy to computer intermediate points (Casteljau method or else). – xenoid Apr 26 '20 at 08:14
  • @xenoid sounds fascinating. Are you able to show an MRE of how that can be done in R? – stevec Apr 26 '20 at 08:16
  • 2
    I don't code in R. See [this](https://www.gimp-forum.net/Thread-Paths-Basics) for a short introduction (not for initially SVG but SVG are essentially the samething). – xenoid Apr 26 '20 at 08:20
  • 1
    @xenoid very interesting. and for the OP: this seems related. https://stackoverflow.com/questions/10136289/how-to-get-coordinates-of-a-path-from-svg-file-into-r – tjebo Apr 26 '20 at 13:12

1 Answers1

2

Here is one way in ImageMagick command line. (Sorry, I do not know the R equivalent)

Create an edge image. Then create a grid mask and multiply the mask with the edge image to leave dots.

Input:

enter image description here

convert giraffe.png -alpha extract -morphology edgeout diamond:1 \
\( -size 1x1 xc:black -size 1x1 xc:white +append +write mpr:tile1 +delete \) \
\( -size 1x1 xc:black -size 1x1 xc:white -append +write mpr:tile2 +delete \) \
\( -clone 0 -tile mpr:tile1 -draw "color 0,0 reset" \) \
\( -clone 0 -tile mpr:tile2 -draw "color 0,0 reset" \) \
\( -clone 1 -clone 2 -compose multiply -composite \) \
-delete 1,2 \
-compose multiply -composite -negate giraffe_edge_dots.png


Result:

enter image description here

Adjust the size of the black parts of the mask to put more spacing.

fmw42
  • 46,825
  • 10
  • 62
  • 80