source("https://bioconductor.org/biocLite.R")
biocLite("EBImage")
library(EBImage)
fn = YOURFILE
img <- readImage(fn)
# remove outer frame
border <- 5 # 5px
dims <- dim(img)
img <- img[border:(dims[1]-border), border:(dims[2]-border),1:dims[3]]
# some despectling
img <- medianFilter(img,size=10) # blur image
# display(img) # check if blurring is fine
# get plate mask.
highpass_rect <- .02 # if images are darker, lower this
rect <- bwlabel(dilate(img>highpass_rect, makeBrush(size=3)))
rect <- rect > 0 # remove background
# display(rect) # check if plate is recognized correctly
highpass_light <- .4 # again, darker images need lower values here for the light objects
# get single light objects
img <- bwlabel(img > highpass_light)
# display(img) # # check if all lights are displayed
# get dimensions of rectangle
rect_mid <- round(dim(rect@.Data[,,1]) / 2)
x_range <- c(min(which(rect@.Data[,rect_mid[2],1])), max(which(rect@.Data[,rect_mid[2],1])))
y_range <- c(min(which(rect@.Data[rect_mid[1],,1])), max(which(rect@.Data[rect_mid[1],,1])))
# now substract border of plate
# measured from the image you provided. 'should' scale to other images as well
# x: left 69px, right: 74px, ROI: 1085
x_range[1] <- x_range[1] + round((diff(x_range)) * (74/(1085+74+69)))
x_range[2] <- x_range[2] - round((diff(x_range)) * (69/(1085+74+69)))
# y: top 17px, bottom: 12px, ROI: 722
y_range[1] <- y_range[1] + round((diff(y_range)) * (17/(722+17+12)))
y_range[2] <- y_range[2] - round((diff(y_range)) * (12/(722+17+12)))
# get pixel ranges for the 12x8 cells
# we will use this as indexes in df
x_cuts <- c(rep(NA,x_range[1]), cut(x_range[1]:x_range[2],12,dig.lab = 0,include.lowest = T,labels=F))
y_cuts <- c(rep(NA,y_range[1]), cut(y_range[1]:y_range[2],8,dig.lab = 0,include.lowest = T,labels=F))
# create 12X8 matrix
df <- matrix(rep(0,12*8),nrow=8,dimnames = list(levels(cut(y_range,8,dig.lab = 0)),
levels(cut(x_range,12,dig.lab = 0,include.lowest = T))))
# now go through lighted objects
for (i in 1:(dim(table(img))-1)) {
# img == i is light nr i
# get position of object
pos <- which(img@.Data[,,1] == i, arr.ind = T)
# add up enlighted pixels in df
for (row in 1:nrow(pos)) {
df[y_cuts[pos[row,2]], x_cuts[pos[row,1]]] <- df[y_cuts[pos[row,2]], x_cuts[pos[row,1]]] + 1
}
}
print(df)
> [143,235] (235,326] (326,417] (417,508] (508,599] (599,690] (690,781] (781,872] (872,963] (963,1.05e+03] (1.05e+03,1.14e+03] (1.14e+03,1.24e+03]
> (90,1.8e+02] 1116 0 0 0 1974 0 0 0 0 0 0 0
> (1.8e+02,2.7e+02] 0 2528 0 0 0 2528 0 0 0 0 1938 845
> (2.7e+02,3.6e+02] 0 2479 2518 2430 0 0 0 0 0 2477 2409 0
> (3.6e+02,4.5e+02] 1731 2339 0 2601 0 2775 0 0 0 0 0 0
> (4.5e+02,5.4e+02] 0 0 0 2549 0 1033 0 0 0 0 0 0
> (5.4e+02,6.3e+02] 2370 2449 2570 0 0 0 0 2555 0 0 0 0
> (6.3e+02,7.3e+02] 0 0 0 0 0 0 0 0 0 0 1836 2348
> (7.3e+02,8.2e+02] 0 1447 1760 0 0 0 0 0 0 0 2303 0