kin.LDA: Midline tracking over image sequences with ROI search using...

Description Usage Arguments Details Value See Also Examples

View source: R/exp.R

Description

Experimental and untested (in the unit-testing sense). Automatically retrieves the midline of a detected ROI in each image of a sequence through thresholding and segmentation. Chose a fish-like ROI class detected through linear discriminate analysis (LDA) of PCA on elliptical Fourier described shapes. Initial training of ROIs is user defined or with the 'fishshapes' data set loaded with trackter (see details). For each detected ROI, kin.LDA finds the y-value midpoint along the x-value array of the ROI and fits a midline according to a chosen smoothing method (loess or spline). Also outputs the midline amplitude relative to a reference line determined by an anterior section of the ROI. Supported image formats are jpeg, png, and tiff.

Usage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
kin.LDA(
  image.dir = NULL,
  frames = NULL,
  thr = 0.7,
  ant.per = 0.2,
  tips = 0.2,
  edges = FALSE,
  train.dat = NULL,
  rescale = FALSE,
  harms = 15,
  enorm = TRUE,
  retrain = 5,
  after.train = "LDA",
  ties = "fish",
  size.min = 0.05,
  show.prog = FALSE,
  smoothing = "loess",
  smooth = 0.3,
  smooth.points = 200,
  save = TRUE,
  out.dir = NULL,
  image.type = "orig",
  plot.pml = TRUE,
  flip = TRUE
)

Arguments

image.dir

character, directory containing images to analyze.

frames

numeric, vector indicating which images to process.

thr

numeric or character ('otsu') threshold to determine binary image. See Details.

ant.per

numeric; left-most percentage of ROI that establishes the horizontal reference for the midline displacement.

tips,

numeric, the proportion the the midline data to use in calculation of the head and tail position.

edges

logical, should ROIs on image edges by evaluated. See Details.

train.dat

Classified Out and Coo outlines that are produced from Momocs. See Details.

rescale

logical, should all shapes in PCA be rescaled. Performs best as 'FALSE'.

harms

numeric, the number of harmonics to use. If missing, Momocs sets 'nh.b' to 12. Will produce messages.

enorm

logical, should the EFA coefficients from efourier operations be normalized or not. See details and efourier

retrain

numeric, the number of frames on which to retrain the LDA data set. See details.

after.train

character, if set to 'size', LDA will be skipped after retrain and the ROI with a size closest to the ROI found by the LDA $>=$ will be chosen. This speeds calculations considerably. If 'LDA', the default, LDA will continue using the retraining classifications from frames $<=$ 'train'.

ties

character, how to chose ROI's in any one frame that appear fish-like. See details.

size.min

numeric, indicating the minimum size of ROIs as a proportion of the pixel field to be considered in analysis. May be useful if smaller unimportant ROIs appear in the frame. Default is 0.05.

show.prog

logical value indicating if outputted image should be displayed during analysis.

smoothing

character, the midline smoothing method, either 'loess' or 'spline'.

smooth

numeric; if smoothing is set to 'loess', 'span' parameter value for loess. If smoothing is set to 'spline' 'spar' parameter value for smooth.spline

smooth.points

numeric, number of equally spaced points along the ROI midline on which the smoothed midline is computed.

save

logical, value indicating if images should be outputted with midline and predicted midline based on the ant.per lm() overlaying original or binary images.

out.dir

character, the directory to which ouputted images should be saved. If NULL, then a subdirectory 'processed_images' in the working directory.

image.type

character; the type of image to be outputted, either 'orig' or 'bin' representing the original or binary images, respectively. Ignored if 'save==FALSE'.

plot.pml

logical, value indicating if outputted images should include the predicted midline (in blue) and the points according to ant.per used to construct the predicted midline (in green).

flip

logical, indicating if binary should be flipped.

Details

The algorithm assumes a left-right orientation, i.e., the head of the ROI is positioned left, the tail right. ffmpeg operations or even imageJ can rotate images not in this orientation. The ant.per value therefor establishes the reference line (theoretical straight midline) based on that portion of the head. The midline is calculated as the midpoints between the y extrema for each x position. If 'save=TRUE', images are saved as binary or the original with a body midline overlay and, if chosen, with the theoretical midline (based on ant.per).

Thresholding operations can be performed with an arbitrary (user-defined) numeric value or with Otsu's method ('thr="otsu"'). The latter chooses a threshold value by minimizing the combined intra-class variance. See otsu.

Before train, ROIs are chosen according to LDA of a PCA object constructed from efourier analysis. LDA is trained by a user define 'train.dat' when the frame $<=$ retrain. LDA will proceed after retrain if after.train='LDA', but the LDA will be trained by the contours classified as 'fish' and 'not.fish' found during the chosen training period.

enorm Normalization of EFA coefficients is often perilous, especially for symmetrical shapes, a conditional met for undulating, bilaterally symmetrical organisms at least some of the time and perhaps for many of the frames included in any analysis. Thus, 'enorm' by default is set to 'FALSE'. 'enorm=TRUE' may produce odd ROI choices and should be used cautiously.

train.dat This should be a Coo and Out object produced by efourier analysis of predefined shapes. A user defined dataset or the fishshapes dataset in trackter must be used for training. fishshapes includes several arbitrary shapes (circles, squares, U-shapes, etc.) as well as several fish shapes: sunfish (genus Lepomis), eel (genus Anguilla), and trout (genus Onchorhynchus) swimming over one tail-beat cycle. A user-defined dataset must have shapes classified with factors identical to the fishshapes contours, that is by shape, type, and edge. Shape levels should indicate what type of shape is described by the contour (e.g., 'circle', 'L-shape', 'trout', 'eel', etc). The type levels must describe the shape as 'fish' or 'not.fish'. The edge levels must be 'FALSE'.

edges Set by default to 'FALSE'. It is not advisable to include shapes that are on the edge of any frame and are therefore incomplete. retrain After this value, the LDA analysis will use the ROIs determined as 'fish' and 'not.fish' in the frames $>=$ retrain to discriminate fish from non-fish shapes. This speeds up analysis considerably. ties Determines how to chose ROIs if more than one fish-like ROI is found in any frame. 'fish' will result in choosing the ROI with shape types in which the best *and* second-best fish-like shape (according to posterior probabilities) match a fish-like shape in the training and/or retraining datasets.'post' will chose the best fish-like shape according the the highest posterior probability from LDA.

Value

A list with the following components:

kin.dat a data table consisting of frame-by-frame position parameters for the ROI determined by LDA analysis.

midline A data table containing, for each frame described by frames, the following:

cont A data table containing x and y positions of the contours used to calculate the data in 'kin.dat'. Contains the following:

all.classes A data table containing the following for all ROIs detected:

dim the x and y dimensions of the images analyzed

See Also

kin.simple, kin.search, efourier LDA, fishshapes.

Examples

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# produce a classic midline waveform plot of swimming 
# fish searching a image field with a two fish-like ROIs
## Not run: 
require(wesanderson)
require(ggplot2)
require(data.table)
require(dplyr)
require(EBImage)

#download example images and place in 'example' subdirectory
f <- "https://github.com/ckenaley/exampledata/blob/master/example.zip?raw=true"
download.file(f, "temp.zip")
unzip("temp.zip")
unlink("temp.zip")

#load fishshapes data
data(fishshapes)


kin <- kin.LDA(image.dir = "example",frames=1:20,thr=0.7,
              ant.per=.25,enorm=FALSE,show.prog = FALSE,retrain=2,
              train.dat = fishshapes,after.train="LDA",edges=FALSE, 
              )
ml <- kin$midline
 #x start at 0
ml <-ml[,x2:=x-x[1],by=frame]

#compute instantaneous amplitude of tail (last/rightmost point) and wave crest x position  by frame
ml2 <-ml[,.(amp.i=abs(last(wave.y))),by=frame]

ml <- merge(ml,ml2,by="frame") #merge these

pal <- wes_palette("Zissou1", 100, type = "continuous") #"Zissou" color palette
p <- ggplot(dat=ml,aes(x=x2,y=wave.y))+theme_classic(15)+scale_color_gradientn(colours = pal)
p <- p+geom_line(aes(group=frame,color=amp.i),
stat="smooth",method = "loess", size = 1.5,alpha = 0.5)
print(p)


### Make a video of processed frames

images.to.video2(image.dir="processed_images",
vid.name="trout_test",frame.rate=5,qual=100,raw=FALSE)
file.exists("trout_test_red.mp4")


## End(Not run)

trackter documentation built on April 19, 2021, 1:08 a.m.