-------- Original Message --------
Subject: R code: Reading TPS and PLY files
Date: Fri, 13 Jan 2012 17:24:59 -0500
From: Dean Adams <[email protected]>
To: [email protected] <[email protected]>

Hi all,

Below are a few R-routines I've written that I thought folks might find
useful.

The first is a function for reading PLY files from NextEngine and David
Scanners, and getting the data into R. For other scanners, the code may
need to be adjusted somewhat, as different scanners output slightly
different PLY files.  The second is a function for reading TPS landmark
data files.  The pixel coordinates are multiplied by the scale factor if
one is included (note: an earlier post by M. Rubio provided code for
reading outline data in TPS format).

I also have a general GPA routine for performing 2D and 3D GPA using
points, curves, surfaces, or any combination. For semilandmarks, the
routine implements both sliding approaches described in the literature
(i.e., via bending energy and via Procrustes distance). I will be
cleaning this code up soon and hope to distribute it in the near future.

All the best,

Dean

--
Dr. Dean C. Adams
Associate Professor
Department of Ecology, Evolution, and Organismal Biology
Department of Statistics
Iowa State University
Ames, Iowa
50011
www.public.iastate.edu/~dcadams/
phone: 515-294-3834


###############
read.ply<-function(file){            #Dean C. Adams
  plyfile<-scan(file=file,what="char",sep="\n",strip.white=T,quiet=T)
    #header section
  xline<-unlist(strsplit(grep(c("vertex "),plyfile, value=T)," "))
  npoints<-as.numeric(xline[grep(c("vertex"),xline)+1])
  yline<-unlist(strsplit(grep(c("element face"),plyfile, value=T)," "))
  npoly<-as.numeric(yline[grep(c("face"),yline)+1])
  headerend<-grep(c("end_header"),plyfile)
    #3D points
  ncolpts<-(length(grep(c("property"),plyfile))-1)
  cols<-grep(c("property"),plyfile, value=T)      #finds x,y,z cols
from points section
  x<-grep(c(" x"),cols);y<-grep(c(" y"),cols);z<-grep(c(" z"),cols)

points<-as.matrix(as.numeric(unlist(strsplit(plyfile[(headerend+1):(headerend+npoints)],"
"))))
  dim(points)<-c(ncolpts,npoints)
  points<-t(points)
  xpts<-points[,x];ypts<-points[,y];zpts<-points[,z]
  points<-cbind(xpts,ypts,zpts)
    #polygons
  plyrest<-plyfile[(headerend+npoints+1):(headerend+npoints+npoly)]
  size1<-as.matrix(as.numeric(unlist(strsplit(plyrest[1]," "))))[1]
  sizecheck<-function(A){
size<-as.matrix(as.numeric(unlist(strsplit(A," "))))[1]}
  sizeall<-unlist(lapply(plyrest,sizecheck))
  if (min(sizeall)!=max(sizeall)) print("Polygons not saved: faces have
different number of vertices") else {

poly<-as.matrix(as.numeric(unlist(strsplit(plyfile[(headerend+npoints+1):(headerend+npoints+npoly)],"
"))))
    dim(poly)<-c((poly[1]+1),npoly) #poly[1] = #pts per face
    poly<-poly[-1,]
    ifelse(min(poly)==0,poly<-poly+1,poly<-poly)  #b/c DavidScanner
begins count @ 0,NULL
  }
return(list(coords=points,polygons=poly))
}

##########

readland.tps<-function(file){            #Dean C. Adams: inspired by M.
Rufino's code on Morphmet
  tpsfile<-scan(file=file,what="char",sep="\n",strip.white=T,quiet=T)
  lmdata<-grep("LM=",tpsfile) # landmark points
  nspecs<-length(lmdata)
  scale<-as.numeric(sub("SCALE=","",tpsfile[grep("SCALE",tpsfile)]))
  if (is.null(scale)){scale=array(1,nspecs)}          #NOTE: assumes
scale is present for all, or none
  nland<-as.numeric(sub("LM=","",tpsfile[lmdata]))
    #landmark data, scaled by scale values
  landdata<-NULL                #extract landmark coordinates, multiply
by scale factor
  for(i in 1:nspecs){
    for(j in 1:nland[1]){
    tmp<-as.numeric(unlist(strsplit(tpsfile[lmdata[i]+j]," ")))*scale[i]
    landdata<-rbind(landdata,tmp)
     }
   }
  imageID<-(sub("IMAGE=","",tpsfile[grep("IMAGE",tpsfile)]))
    imageID<-sub(".jpg","",imageID)          #note: done for .jpg
  return(list(coords=landdata,specID=imageID,nspecs=nspecs,nland=nland[1]))
}


Reply via email to