extracting_metadata.Rmd
The first step in the MAMMals workflow is to extract the metadata of all multimedia files. For example, files can be organized into separate subfolders in the root directory:
#> /Volumes/mydisk/MAMMals
#> ├── export_data
#> ├── export_media
#> ├── flightlogs
#> ├── photoid
#> ├── photoid.csv
#> ├── photoid.txt
#> └── videos
A good practice is to set the input and output folder paths to the folders of raw and processed multimedia data. For example, we can set the folder path a priori for our photo-identification data, drone video files and flight logs as:
photo_folderpath = '/Volumes/mydisk/MAMMals/photoid'
video_folderpath = '/Volumes/mydisk/MAMMals/videos'
flight_folderpath = '/Volumes/mydisk/MAMMals/flightlogs'
Is is also convenient to create new folders to store the outputs:
if(isFALSE(dir.exists('/Volumes/AMSM/20210202_test/export_media')))
dir.create('/Volumes/mydisk/MAMMals/export_media')
#> Warning in dir.create("/Volumes/mydisk/MAMMals/export_media"): '/Volumes/mydisk/
#> MAMMals/export_media' já existe
if(isFALSE(dir.exists('/Volumes/mydisk/MAMMals/export_data')))
dir.create('/Volumes/mydisk/MAMMals/export_data')
export_file_folder <- '/Volumes/mydisk/MAMMals/export_media'
export_data_folder <- '/Volumes/mydisk/MAMMals/export_data'
To extract the metadata of all images in the subfolder photoid, use the function getPhotoMetadata()
. Use the argument extension to set the image file extensions to look for in the photo_folderpath
and set the timezone accordingly to where the photos were taken.
photos_metadata <- MAMMals::getPhotoMetadata(
ROOTfolderpath = photo_folderpath,
extension = '.jpg',
ignore = NULL,
timezone = "America/Sao_Paulo",
export = NULL,
data_photoid = NULL
)
The metadata of all .jpg images in the photo_folderpath
will be stored in the data frame photos_metadata
:
str(photos_metadata)
#> Classes 'photo-id' and 'data.frame': 19 obs. of 21 variables:
#> $ camera.photo_path : chr "/Volumes/mydisk/MAMMals/photoid" "/Volumes/mydisk/MAMMals/photoid" "/Volumes/mydisk/MAMMals/photoid" "/Volumes/mydisk/MAMMals/photoid" ...
#> $ camera.photo_filename : chr "6Q1A0177.JPG" "6Q1A0178.JPG" "6Q1A0179.JPG" "6Q1A0180.JPG" ...
#> $ camera.PHOTOID : logi NA NA NA NA NA NA ...
#> $ camera.photo_filename_exif: chr "6Q1A0177.JPG" "6Q1A0178.JPG" "6Q1A0179.JPG" "6Q1A0180.JPG" ...
#> $ camera.datetime_GPS_UTC : chr "2019-05-22 15:05:14" "2019-05-22 15:05:14" "2019-05-22 15:05:29" "2019-05-22 15:05:59" ...
#> $ camera.datetime_local : chr "2019-05-22 12:05:15" "2019-05-22 12:05:15" "2019-05-22 12:05:30" "2019-05-22 12:06:01" ...
#> $ camera.CreateDate : chr "2019-05-22 12:05:15" "2019-05-22 12:05:15" "2019-05-22 12:05:30" "2019-05-22 12:06:01" ...
#> $ camera.TimeZone : chr "-03:00" "-03:00" "-03:00" "-03:00" ...
#> $ camera.TimeZoneCity : chr "Sao Paulo" "Sao Paulo" "Sao Paulo" "Sao Paulo" ...
#> $ camera.DaylightSavings : chr "Off" "Off" "Off" "Off" ...
#> $ camera.CanonModelID : chr "EOS 7D Mark II" "EOS 7D Mark II" "EOS 7D Mark II" "EOS 7D Mark II" ...
#> $ camera.GPSLatitudeRef : chr "South" "South" "South" "South" ...
#> $ camera.GPSLongitudeRef : chr "West" "West" "West" "West" ...
#> $ camera.GPSMapDatum : chr "WGS-84" "WGS-84" "WGS-84" "WGS-84" ...
#> $ camera.GPSAltitude : chr "3.9 m Above Sea Level" "3.9 m Above Sea Level" "3.5 m Above Sea Level" "1.1 m Below Sea Level" ...
#> $ camera.direction.angle : chr "226" "226" "167" "241" ...
#> $ camera.direction.angle.ref: chr "Magnetic North" "Magnetic North" "Magnetic North" "Magnetic North" ...
#> $ camera.GPSLatitude : chr "28 deg 29' 44.91\" S" "28 deg 29' 44.91\" S" "28 deg 29' 44.87\" S" "28 deg 29' 44.77\" S" ...
#> $ camera.GPSLongitude : chr "48 deg 45' 35.74\" W" "48 deg 45' 35.74\" W" "48 deg 45' 35.69\" W" "48 deg 45' 35.74\" W" ...
#> $ camera.latitude : num -28.5 -28.5 -28.5 -28.5 -28.5 ...
#> $ camera.longitude : num -48.8 -48.8 -48.8 -48.8 -48.8 ...
If photo-identification data is available, it can be assigned directly into the data.frame photos_metadata
. To do that, select only the columns with image file name and the respective ID for each photo. Images with no individual ID can be ignored in the getPhotoMetadata()
passing a character vector to the argument ignore.
# read photo id data
photoid <- utils::read.csv(file = "/Volumes/mydisk/MAMMals/photoid.csv")
head(photoid)
#> camera.photo_path camera.photo_filename camera.PHOTOID
#> 1 F:/fotoidrone_test/photoid 6Q1A0177.JPG L_24
#> 2 F:/fotoidrone_test/photoid 6Q1A0178.JPG L_24
#> 3 F:/fotoidrone_test/photoid 6Q1A0179.JPG L_24
#> 4 F:/fotoidrone_test/photoid 6Q1A0180.JPG L_26
#> 5 F:/fotoidrone_test/photoid 6Q1A0181.JPG L_26
#> 6 F:/fotoidrone_test/photoid 6Q1A0182.JPG L_26
#> camera.photo_filename_exif camera.datetime_GPS_UTC camera.datetime_local
#> 1 6Q1A0177.JPG 2019-05-22 15:05:14 2019-05-22 12:05:15
#> 2 6Q1A0178.JPG 2019-05-22 15:05:14 2019-05-22 12:05:15
#> 3 6Q1A0179.JPG 2019-05-22 15:05:29 2019-05-22 12:05:30
#> 4 6Q1A0180.JPG 2019-05-22 15:05:59 2019-05-22 12:06:01
#> 5 6Q1A0181.JPG 2019-05-22 15:06:14 2019-05-22 12:06:29
#> 6 6Q1A0182.JPG 2019-05-22 15:06:14 2019-05-22 12:06:29
#> camera.CreateDate camera.TimeZone camera.TimeZoneCity
#> 1 2019-05-22 12:05:15 -03:00 Sao Paulo
#> 2 2019-05-22 12:05:15 -03:00 Sao Paulo
#> 3 2019-05-22 12:05:30 -03:00 Sao Paulo
#> 4 2019-05-22 12:06:01 -03:00 Sao Paulo
#> 5 2019-05-22 12:06:29 -03:00 Sao Paulo
#> 6 2019-05-22 12:06:29 -03:00 Sao Paulo
#> camera.DaylightSavings camera.CanonModelID camera.GPSLatitudeRef
#> 1 Off EOS 7D Mark II South
#> 2 Off EOS 7D Mark II South
#> 3 Off EOS 7D Mark II South
#> 4 Off EOS 7D Mark II South
#> 5 Off EOS 7D Mark II South
#> 6 Off EOS 7D Mark II South
#> camera.GPSLongitudeRef camera.GPSMapDatum camera.GPSAltitude
#> 1 West WGS-84 3.9 m Above Sea Level
#> 2 West WGS-84 3.9 m Above Sea Level
#> 3 West WGS-84 3.5 m Above Sea Level
#> 4 West WGS-84 1.1 m Below Sea Level
#> 5 West WGS-84 3.6 m Below Sea Level
#> 6 West WGS-84 3.6 m Below Sea Level
#> camera.direction.angle camera.direction.angle.ref
#> 1 226 Magnetic North
#> 2 226 Magnetic North
#> 3 167 Magnetic North
#> 4 241 Magnetic North
#> 5 247 Magnetic North
#> 6 246 Magnetic North
#> camera.GPSLatitude camera.GPSLongitude camera.latitude
#> 1 28 deg 29' 44.91\\ S,48 deg 45' 35.74\\ W -28.49581 -48.75993
#> 2 28 deg 29' 44.91\\ S,48 deg 45' 35.74\\ W -28.49581 -48.75993
#> 3 28 deg 29' 44.87\\ S,48 deg 45' 35.69\\ W -28.49580 -48.75991
#> 4 28 deg 29' 44.77\\ S,48 deg 45' 35.74\\ W -28.49577 -48.75993
#> 5 28 deg 29' 44.77\\ S,48 deg 45' 35.72\\ W -28.49577 -48.75992
#> 6 28 deg 29' 44.77\\ S,48 deg 45' 35.72\\ W -28.49577 -48.75992
#> camera.longitude
#> 1 NA
#> 2 NA
#> 3 NA
#> 4 NA
#> 5 NA
#> 6 NA
# check photos with no individual identification
ignore.photos <- photoid[is.na(photoid$camera.PHOTOID), 'camera.photo_filename']
# extract metadata, ignore photos with no ID, export .csv file and assign photoid to data_photoid
photos_metadata <- MAMMals::getPhotoMetadata(
ROOTfolderpath = photo_folderpath,
extension = '.jpg',
ignore = ignore.photos,
timezone = "America/Sao_Paulo",
export = paste0(export_data_folder, "/photoid_metadata.csv"),
data_photoid = photoid[, c("camera.photo_filename","camera.PHOTOID")]
)
# check data
head(photos_metadata)
#> camera.photo_path camera.photo_filename camera.PHOTOID
#> 1 /Volumes/mydisk/MAMMals/photoid 6Q1A0177.JPG L_24
#> 2 /Volumes/mydisk/MAMMals/photoid 6Q1A0178.JPG L_24
#> 3 /Volumes/mydisk/MAMMals/photoid 6Q1A0179.JPG L_24
#> 4 /Volumes/mydisk/MAMMals/photoid 6Q1A0180.JPG L_26
#> 5 /Volumes/mydisk/MAMMals/photoid 6Q1A0181.JPG L_26
#> 6 /Volumes/mydisk/MAMMals/photoid 6Q1A0182.JPG L_26
#> camera.photo_filename_exif camera.datetime_GPS_UTC camera.datetime_local
#> 1 6Q1A0177.JPG 2019-05-22 15:05:14 2019-05-22 12:05:15
#> 2 6Q1A0178.JPG 2019-05-22 15:05:14 2019-05-22 12:05:15
#> 3 6Q1A0179.JPG 2019-05-22 15:05:29 2019-05-22 12:05:30
#> 4 6Q1A0180.JPG 2019-05-22 15:05:59 2019-05-22 12:06:01
#> 5 6Q1A0181.JPG 2019-05-22 15:06:14 2019-05-22 12:06:29
#> 6 6Q1A0182.JPG 2019-05-22 15:06:14 2019-05-22 12:06:29
#> camera.CreateDate camera.TimeZone camera.TimeZoneCity
#> 1 2019-05-22 12:05:15 -03:00 Sao Paulo
#> 2 2019-05-22 12:05:15 -03:00 Sao Paulo
#> 3 2019-05-22 12:05:30 -03:00 Sao Paulo
#> 4 2019-05-22 12:06:01 -03:00 Sao Paulo
#> 5 2019-05-22 12:06:29 -03:00 Sao Paulo
#> 6 2019-05-22 12:06:29 -03:00 Sao Paulo
#> camera.DaylightSavings camera.CanonModelID camera.GPSLatitudeRef
#> 1 Off EOS 7D Mark II South
#> 2 Off EOS 7D Mark II South
#> 3 Off EOS 7D Mark II South
#> 4 Off EOS 7D Mark II South
#> 5 Off EOS 7D Mark II South
#> 6 Off EOS 7D Mark II South
#> camera.GPSLongitudeRef camera.GPSMapDatum camera.GPSAltitude
#> 1 West WGS-84 3.9 m Above Sea Level
#> 2 West WGS-84 3.9 m Above Sea Level
#> 3 West WGS-84 3.5 m Above Sea Level
#> 4 West WGS-84 1.1 m Below Sea Level
#> 5 West WGS-84 3.6 m Below Sea Level
#> 6 West WGS-84 3.6 m Below Sea Level
#> camera.direction.angle camera.direction.angle.ref camera.GPSLatitude
#> 1 226 Magnetic North 28 deg 29' 44.91" S
#> 2 226 Magnetic North 28 deg 29' 44.91" S
#> 3 167 Magnetic North 28 deg 29' 44.87" S
#> 4 241 Magnetic North 28 deg 29' 44.77" S
#> 5 247 Magnetic North 28 deg 29' 44.77" S
#> 6 246 Magnetic North 28 deg 29' 44.77" S
#> camera.GPSLongitude camera.latitude camera.longitude
#> 1 48 deg 45' 35.74" W -28.49581 -48.75993
#> 2 48 deg 45' 35.74" W -28.49581 -48.75993
#> 3 48 deg 45' 35.69" W -28.49580 -48.75991
#> 4 48 deg 45' 35.74" W -28.49577 -48.75993
#> 5 48 deg 45' 35.72" W -28.49577 -48.75992
#> 6 48 deg 45' 35.72" W -28.49577 -48.75992
To extract the metadata of videos and audios, use the getVideoMetadata()
in the video_folderpath
or the getAudioMetadata()
in the audio_folderpath
. For example, use the getVideoMetadata()
to read the metadata of drone video files. If video subtitles (.SRT files) are available, use the argument include_srt_datetime to include the time from the subtitles.
videos_metadata <- MAMMals::getVideoMetadata(
ROOTfolderpath = video_folderpath,
extension = '.mp4',
include_srt_datetime = FALSE,
ignore = NULL,
timezone = "America/Sao_Paulo",
export = paste0(export_data_folder, "/video_metadata.csv")
)
# check data
head(videos_metadata)
#> video.folder video.filename
#> 1 /Volumes/mydisk/MAMMals/videos DJI_0042.MP4
#> 2 /Volumes/mydisk/MAMMals/videos DJI_0044.MP4
#> 3 /Volumes/mydisk/MAMMals/videos DJI_0045.MP4
#> video.path video.local_start_datetime
#> 1 /Volumes/mydisk/MAMMals/videos/DJI_0042.MP4 2019-05-22 11:59:05
#> 2 /Volumes/mydisk/MAMMals/videos/DJI_0044.MP4 2019-05-22 12:20:43
#> 3 /Volumes/mydisk/MAMMals/videos/DJI_0045.MP4 2019-05-22 12:58:50
#> video.duration video.local_end_datetime
#> 1 00:15:43.72 2019-05-22 12:14:48
#> 2 00:20:28.24 2019-05-22 12:41:11
#> 3 00:21:00.03 2019-05-22 13:19:50