We can use imager::cannyEdges to get the edges, and then put the coordinates in the data frame.
library('ggplot2') library('imager') plot(boats)

img <- cannyEdges(boats) plot(img)

It looks like img is a logical array with 4 dimensions.
dim(img)
I just want two dimensions, so I will drop the two dimensions.
img <- img[, , 1, 1] img[1:8, 1:8] # [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] # [1,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE # [2,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE # [3,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE # [4,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE # [5,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE # [6,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE # [7,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE # [8,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
which can convert this matrix to a coordinate list.
coords <- which(img, arr.ind = T) head(coords)
Now it can be built.
df <- data.frame(x = coords[,1], y = coords[,2]) ggplot(df, aes(x, -y)) + geom_point()
