fin.kin: Tracking of fin-like extensions of body contours

Description Usage Arguments Details Value See Also Examples

View source: R/kin.R

Description

Estimates the amplitudes of regions along a body contour that are protruding. Useful in computing paired-fin amplitudes from contour data produced from kin.simple, kin.search, or kin.free. Also computes a smoothed midline based on the body outline with the fin region removed.

Usage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
fin.kin(
  kin,
  out = "cont",
  frames = NULL,
  fin.pos = NULL,
  smooth.n = 5,
  ml.meth = "hull",
  ml.smooth = 0.9,
  red = NULL
)

Arguments

kin,

a named list from one of trackters kin functions.

out

character, specifying the contour data in 'kin'

frames

integer, the frames within 'kin' to analyze. If NULL then all frames are included.

fin.pos

numeric, a vector of length 2 indicating the start and end of the contour region that contains the fins of interest as a proportion of the body length.

smooth.n

numeric, the number of smoothing operations undertaken by coo_smooth on the contour described by 'x'. See Details.

ml.meth

character, the midline detection method. One of 'ang' for bisection using free.ml.ang or 'hull' for bisection using free.ml.hull. Delaunay triangulation using free.ml.del is not supported. See Details.

ml.smooth

numeric (0-1), the smoothing value for the midline. See Details.

red

numeric, between 0-1 the proportion of contour coordinates to sample. Will speed up fin position and midline estimations. If 'NULL', the full contour in out will be used See Details.

Details

If red is specified, the contour out is sampled with coo_interpolate from the Momocs package. The number of points sampled (n) equals red times the number of points in out

To establish the contour positions that are within fin.pos, a midline is estimated using one of two methods specified by ml.meth, "ang" for free.ml.ang or "hull" for free.ml.hull. Midline points are indexed by position along the body length by calculating the cumulative distance between midline coordinates in pixels. This midline distance is then used to estimate the position of the fin about the contour using the parameter fin.pos.

The positions of the tip of the fin appendages is estimated in two ways. The first is simply the point in each appendage that is farthest from the base of the fin. The base is estimated as a straight line between the contour coordinates that match fin.pos. The second is a little more complicated and starts with calculation the distance between each fin contours coordinates and the midpoint of the fin base. features from the features package is then use to calculate an inflection in this distance and the point of this inflection is used to estimate the fin position. Amplitudes of each method are calculated based on the orthogonal euclidean distance from the fin bases.

In addition to fin amplitude and contour extraction, this function also produces a composite contour of the body minus the fin area described by fin.pos. Fin contours are replaced by a simple linear prediction constructed from the coordinates of the first and last values covered by fin.pos, that is, the fin bases. The result is a straight line between the start and end of each fin.

From this composite body contour, a midline prediction is made based on the mean position of contour coordinates from each side of the contour sharing a the same position along body using the free.ml functions.

#' For midline smoothing, smooth_spline from the smoothr package is used to interpolate points between a reduced number of vertices using piecewise cubic polynomials. The number of vertices is calculated based on the number of midline coordinates times the value of ml.smooth.

Value

A list with the following components:

cont a data table consisting of x,y coordinates of the body contour

fin a data table describing the contour of the fins consisting of the following:

fin.pts a data table describing fin position consisting of the following:

comp a data table describing the composite contour of the body minus the fins.

midline a data table describing the estimated midline, 'x', 'y', the smoothed x and y positions, respectively

bl the body length in pixels

amp a data table describing the estimated fin amplitudes based on each method of finding the fin tip. 'amp1', the amplitude of the fin positions based on the maximum euclidean distance from the fin base and 'amp2', the distance of the fin points (based on distance inflections) from the fin base.

See Also

kin.simple, kin.search, kin.free, coo_sample, coo_smooth, smooth_spline

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
48
49
50
51
52
53
54
55
56
57
58
###plot pectoral-fin amplitudes of a swimming sunfish
## Not run: 
require(ggplot2)

#download example avi video
f <- "https://github.com/ckenaley/exampledata/blob/master/sunfish_pect.avi?raw=true"
download.file(f,"sunfish.avi")

#create directories
 ti <-paste0(tempdir(),"/images")
 dir.create(ti)

#extract images with ffmpeg operations and reduce them to 600 px wide with a filter
filt.red <- " -vf scale=600:-1 " #filter
vid.to.images2(vid.path="sunfish.avi",filt = filt.red,out.dir=ti) #extract

#number of frames
fr <- list.files(ti,full.names=TRUE)
thr.check(fr[3])

#extract contours and other data
kin <- kin.search(image.dir = ti,thr=0.9,ant.per = 0.25,save=FALSE)

#fin data by frame
fin.pos <- c(0.25,.55)
fin.dat <- fin.kin(kin=kin,fin.pos = fin.pos,smooth.n=1,ml.smooth=0.3)

p <- ggplot(dat=fin.dat$amp,aes(x=frame,y=amp2,col=side))+geom_line()+theme_classic(15)
print(p)


## plot body and fin contours of a frame

#plot body contour and fins
fr <- 8
p <- qplot(data=fin.dat$cont[frame==fr],x=x,y=y)
p <- p+geom_point(data=fin.dat$fin[frame==fr],aes(x,y),col="red",size=3)
p <- p+geom_point(data=fin.dat$fin.pts[frame==fr],aes(x,y,shape=pos))
p+xlim(c(0,kin$dim[1]))+ylim(c(0,kin$dim[2]))


#plot body contour minus fins and the body midline
p <- qplot(data=fin.dat$comp[frame==fr],x=x,y=y)
p <- p++geom_point(data=fin.dat$midline[frame==fr],aes(x,y),col="red",size=2)
p+xlim(c(0,kin$dim[1]))+ylim(c(0,kin$dim[2]))

# now the whole sequence with gg.overlay()
 gg.overlay(dat=fin.dat,
 under="cont",
 over="fin.pts",
 size=5,
 animate=TRUE,
 fps=5,
 alph=0.05)
 
unlink(ti,recursive=TRUE)

## End(Not run)

ckenaley/trackter documentation built on Feb. 11, 2022, 6:43 a.m.