- Notifications
You must be signed in to change notification settings - Fork5
R package for working with x3p files, see also heike.github.io/x3ptools/
License
heike/x3ptools
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
The x3p file format is specified in ISO standard 25178-72:2017/AMD1:2020 (based on ISO ISO5436 – 2000) describe 3d surface measurements.This package allows reading, writing and basic modifications to the 3Dsurface measurements.
x3ptools is available from CRAN:
install.packages("x3ptools")The development version is available from Github:
# install.packages("devtools")devtools::install_github("heike/x3ptools",build_vignettes=TRUE)
The x3p file format is an xml based file format created to describedigital surface measurements. x3p has been developed by OpenFMC (OpenForensic Metrology Consortium, seehttps://www.open-fmc.org/) and hasbeen adopted as 25178-72:2017/AMD 1:2020. x3p files are a zip archive ofa directory consisting of an xml file of meta information and a matrixof numeric surface measurements.
Internally, x3p objects are stored as a list consisting of the surfacematrix (the measurements) and meta information in four records: headerinfo, feature info, general info, and matrix info:
library(x3ptools)logo<- x3p_read(system.file("csafe-logo.x3p",package="x3ptools"))names(logo)
## [1] "header.info" "surface.matrix" "feature.info" "general.info" ## [5] "matrix.info" "other.info"The four info objects specify the information for Record1 throughRecord4 in the xml file. An example for an xml file is provided with thepackage and can be accessed assystem.file("templateXML.xml", package="x3ptools").
header.info contains the information relevant to interpret locationsfor the surface matrix:
logo$header.info
## $sizeY## [1] 419## ## $sizeX## [1] 741## ## $incrementY## [1] 6.45e-07## ## $incrementX## [1] 6.45e-07matrix.info expands onheader.info and provides the link to thesurface measurements in binary format.
general.info consists of information on how the data was captured,i.e. both author and capturing device are specified here.
feature.info is informed by the header info and provides the structurefor storing the information.
While these pieces can be changed and adapted manually, it is moreconvenient to save information on the capturing device and the creatorin a separate template and bind measurements and meta informationtogether in the commandx3p_addtemplate.
x3p_read andx3p_write are the two functions allows us to read x3pfiles and write to x3p files.
logo<- x3p_read(system.file("csafe-logo.x3p",package="x3ptools"))names(logo)
## [1] "header.info" "surface.matrix" "feature.info" "general.info" ## [5] "matrix.info" "other.info"The functionx3p_image usesrgl to render a 3d object in a separatewindow. The user can then interact with the 3d surface (zoom androtate):
x3p_image(logo,size=c(741,419),zoom=0.5,useNULL=TRUE)rgl::rglwidget()
In case a file name is specified in the function call the resultingsurface is saved in a file (the extension determines the actual fileformat of the image).
x3p_image_grid lays a regularly spaced grid of lines over the surfaceof the scan. Lines are drawnspaces apart (50 microns by default in ydirection and 100 microns in x direction). Every fifth and tenth linesare colored differently to ease a visual assessment of distance.
logoplus<- x3p_add_grid(logo,spaces=50e-6,size= c(3,3,5),color=c("grey50","black","darkred"))x3p_image(logoplus,size=c(741,419),zoom=0.5,useNULL=TRUE)rgl::rglwidget()
The functionsx3p_to_df anddf_to_x3p allow casting between an x3pformat and an x-y-z data set:
logo_df<- x3p_to_df(logo)head(logo_df)
## x y value## 1 0.000e+00 0.00026961 4e-07## 2 6.450e-07 0.00026961 4e-07## 3 1.290e-06 0.00026961 4e-07## 4 1.935e-06 0.00026961 4e-07## 5 2.580e-06 0.00026961 4e-07## 6 3.225e-06 0.00026961 4e-07When converting from the x3p format to a data frame, the values from thesurface matrix are interpreted as heights (saved asvalue) on an x-ygrid. The dimension of the matrix sets the number of different x and ylevels, the information inheader.info allows us to scale the levelsto the measured quantities. Similarly, when moving from a data frame toa surface matrix, the assumption is that measurements are taken on anequi-spaced and complete grid of x-y values. The information on theresolution (i.e. the spacing between consecutive x and y locations) issaved in form of the header info, which is added to the list. Generalinfo and feature info can not be extracted from the measurements, buthave to be recorded with other means.
Once data is in a regular data frame, we can use our regular means tovisualize these raster images, e.g. usingggplot2:
library(ggplot2)library(magrittr)logo_df %>% ggplot(aes(x=x,y=y,fill=value))+ geom_tile()+ scale_fill_gradient2(midpoint=4e-7)
x3p_rotate rotates an x3p image counter-clockwise by angle in degrees,x3p_transpose transposes the surface matrix of an image and updatesthe corresponding meta information. The functionx3p_flip_y is acombination of transpose and rotation, that allows to flip the directionof the y axis to move easily from legacy ISO x3p scans to onesconforming to the most recent ISO standard.
x3p_sample allows to sub-sample an x3p object to get a lowerresolution image. Inx3p_sample we need to set a sampling factor. Asample factormX of 2 means that we only use every 2nd value of thesurface matrix,mX of 5 means, we only use every fifth value:
dim(logo$surface.matrix)
## [1] 741 419logo_sample<- x3p_sample(logo,m=5)dim(logo_sample$surface.matrix)
## [1] 149 84ParametermY can be specified separately frommX for a differentsampling rate in y direction. We can also use different offsets in x andy direction by specifyingoffsetX and/oroffsetY.
sample2<- x3p_sample(logo,m=5,offset=1)cor(as.vector(logo_sample$surface.matrix[-149,]), as.vector(sample2$surface.matrix))
## [1] 0.8639308x3p_interpolate allows, likex3p_sample, to create a new x3p file ata new resolution, as specified in the parametersresx andresy. Thenew resolution should be lower (i.e. larger values forresx andresy) than the resolution specified asIncrementX andIncrementYin the header info of the x3p file.x3p_interpolate can also be usedto interpolate missing values (set parametermaxgap according tospecifications inzoo::na.approx).
The four records of header info, feature info, general info, and matrixinfo of an x3p object contain meta information relevant to the scan.x3p_show_xml allows the user to specify a search term and thenproceeds to go through all records for a matching term. As a result anymatching elements from the meta file are shown:
logo %>% x3p_show_xml("axis")# three axes are defined
## $Axes.CX.AxisType## [1] "I"## ## $Axes.CY.AxisType## [1] "I"## ## $Axes.CZ.AxisType## [1] "A"logo %>% x3p_show_xml("creator")
## $Creator## [1] "Heike Hofmann, CSAFE"If a search term identifies a single element,x3p_modify_xml allowsthe user to update the corresponding meta information:
logo %>% x3p_modify_xml("creator","I did this")
## x3p object## Instrument: N/A ## size (width x height): 741 x 419 in pixel ## resolution: 6.4500e-07 x 6.4500e-07 ## Creator: I did this ## Comment: image rendered from the CSAFE logoA mask is used to markup regions of the surface - the mask can then beused to overlay the rendered surface with color.
Below is a 3d surface of a part of a bullet surface is shown. Someregions are marked up: the bronze colored area is an area with strongstriae (vertical lines engraved on the bullet as it moves through thebarrel of the handgun when fired), areas in dark blue show grooveengraved areas, the light blue area shows break off at the bottom of thebullet, and the pink area marks an area without striae:
Any image can serve as a mask, the commandx3p_add_mask allows to adda raster image as a mask for a x3p object:
logo<- x3p_read(system.file("csafe-logo.x3p",package="x3ptools"))color_logo<-png::readPNG(system.file("csafe-color.png",package="x3ptools"))logoplus<- x3p_add_mask(logo,mask= as.raster(color_logo))x3p_image(logoplus,size=c(741,419),zoom=0.5,multiply=30)
Some masks are more informative than others, but the only requirementfor images is that they are of the right size.
Masks are raster images. Any change to the raster manifests as a changein the surface color of the corresponding scan. We suggest using themagick package to manipulate masks.
Additionally, vertical and horizontal lines can be added in the masksusing the commandsx3p_add_vline andx3p_add_hline:
logo<- x3p_read(system.file("csafe-logo.x3p",package="x3ptools"))logoplus<- x3p_add_hline(logo,yintercept=c(13e-5,19.5e-5),color="cyan")x3p_image(logoplus,size=c(741,419)/2,zoom=0.5,multiply=30,file="man/figures/logo-lines.png")
This work was partially funded by the Center for Statistics andApplications in Forensic Evidence (CSAFE) through Cooperative Agreements70NANB15H176 and 70NANB20H019 between NIST and Iowa State University,which includes activities carried out at Carnegie Mellon University,Duke University, University of California Irvine, University ofVirginia, West Virginia University, University of Pennsylvania,Swarthmore College and University of Nebraska, Lincoln.
About
R package for working with x3p files, see also heike.github.io/x3ptools/
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors6
Uh oh!
There was an error while loading.Please reload this page.








