R/ImageJ: Measuring shortest distance between points and curves
Asked Answered
E

2

5

I have some experience with R as a statistics platform, but am inexperienced in image based maths. I have a series of photographs (tiff format, px/µm is known) with holes and irregular curves. I'd like to measure the shortest distance between a hole and the closest curve for that particular hole. I'd like to do this for each hole in a photograph. The holes are not regular either, so maybe I'd need to tell the program what are holes and what are curves (ImageJ has a point and segmented line functions).

Any ideas how to do this? Which package should I use in R? Would you recommend another program for this kind of task?

Example image

Encratis answered 12/1, 2012 at 9:37 Comment(2)
Off the top of my head, I'd go with ImageJ first. I'm not an expert with that tool but it does seem to be good at finding spots and doing things with them.Grating
It might be that Bio7 could be good for this task. Any Bio7 gurus out there? The program does so much, that it's difficult to figure out what it actually does =)Encratis
E
2

EDIT: Doing this is now possible using sclero package. The package is currently available on GitHub and the procedure is described in detail in the tutorial. Just to illustrate, I use an example from the tutorial:

library(devtools)
install_github("MikkoVihtakari/sclero", dependencies = TRUE)
library(sclero)
path <- file.path(system.file("extdata", package = "sclero"), "shellspots.zip")
dat <- read.ijdata(path, scale = 0.7812, unit = "um") 
shell <- convert.ijdata(dat)
aligned <- spot.dist(shell)
plot(aligned)

enter image description here

It is also possible to add sample spot sizes using the functions provided by the sclero package. Please see Section 2.5 in the tutorial.

Encratis answered 23/4, 2012 at 14:20 Comment(0)
N
1

There's a tool for edge detection written for Image J that might help you first find the holes and the lines, and clarify them. You find it at

http://imagejdocu.tudor.lu/doku.php?id=plugin:filter:edge_detection:start

Playing around with the settings for the tresholding and the hysteresis can help in order to get the lines and holes found. It's difficult to tell whether this has much chance of working without seeing your actual photographs, but a colleague of mine had good results using this tool on FRAP images. I programmed a ImageJ tool that can calculate recoveries in FRAP analysis based on those images. You might get some ideas for yourself when looking at the code (see: http://imagejdocu.tudor.lu/doku.php?id=plugin:analysis:frap_normalization:start )

The only way I know you can work with images, is by using EBImage that's contained in the bioconductor system. The package Rimage is orphaned, so is no longer maintained.

To find the shortest distance: once you have the coordinates of the lines and holes, you can go for the shotgun approach : calculate the distances between all points and the line, and then take the minimum. An illustration about that in R :

x <- -100:100
x2 <- seq(-70,-50,length.out=length(x)/4)

a.line <- list(x = x,
               y = 4*x + 5) 

a.hole <- list(
  x = c(x2,rev(x2)),
  y = c(200 + sqrt(100-(x2+60)^2),
        rev(200 - sqrt(100-(x2+60)^2)))
  )

plot(a.line,type='l')
lines(a.hole,col='red')

calc.distance <- function(line,hole){

  mline <- matrix(unlist(line),ncol=2)
  mhole <- matrix(unlist(hole),ncol=2)

  id1 <- rep(1:nrow(mline),nrow(mhole))
  id2 <- rep(1:nrow(mhole), each=nrow(mline))

  min(
    sqrt(
      (mline[id1,1]-mhole[id2,1])^2 + 
      (mline[id1,2]-mhole[id2,2])^2
    )
  )
}

Then :

> calc.distance(a.line,a.hole)
[1] 95.51649

Which you can check mathematically by deriving the equations from the circle and the line. This goes fast enough if you don't have millions of points describing thousands of lines and holes.

Nitza answered 12/1, 2012 at 15:31 Comment(3)
Thanks for helpful answer Joris! I replaced the illustration with a real photograph. I tried your plugin, but doubt that it can separate the lines, which I have marked with red. Do you know, if it's possible to manually define the points and lines and then import them to EBImage?Encratis
@Largh : indeed, forget about finding those lines in that photograph. You can do that manually in ImageJ as well and then export the coordinates of those lines in a csv file. That file you can read with R. Same for the circles (which EdgeDetection should find easily). I can't remember from the top of my head how to do that in ImageJ, it's been a few years since I've been working with it, but there's Burge and Burgers book (which is excellent : imagingbook.com ) and they also have an ImageJ Tutorial on the side. Plus, there's plenty of information on this on the web.Nitza
Thanks again Joris. I wonder how to transfer point and segmented line information from ImageJ or EBImage to R without loosing the pixel information (or then converting pixels to µm before transfer). Bio7 could probably do this, but it's pretty complicated to use (lots of clicking).Encratis

© 2022 - 2024 — McMap. All rights reserved.