Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Pinard Clement
drone-depth-validation-set
Commits
a5c21661
Commit
a5c21661
authored
Sep 27, 2019
by
Clément Pinard
Browse files
add video frames extractor
parent
f7f1428c
Changes
2
Show whitespace changes
Inline
Side-by-side
edit_exif.py
0 → 100644
View file @
a5c21661
import
piexif
from
fractions
import
Fraction
def
to_deg
(
value
,
loc
):
"""convert decimal coordinates into degrees, munutes and seconds tuple
Keyword arguments: value is float gps-value, loc is direction list ["S", "N"] or ["W", "E"]
return: tuple like (25, 13, 48.343 ,'N')
"""
if
value
<
0
:
loc_value
=
loc
[
0
]
elif
value
>
0
:
loc_value
=
loc
[
1
]
else
:
loc_value
=
""
abs_value
=
abs
(
value
)
deg
=
int
(
abs_value
)
t1
=
(
abs_value
-
deg
)
*
60
min
=
int
(
t1
)
sec
=
round
((
t1
-
min
)
*
60
,
5
)
return
[
deg
,
min
,
sec
],
loc_value
def
to_dec
(
deg
,
min
,
sec
,
sign
):
result
=
deg
[
0
]
/
deg
[
1
]
result
+=
min
[
0
]
/
(
60
*
min
[
1
])
result
+=
sec
[
0
]
/
(
60
*
60
*
sec
[
1
])
return
sign
*
result
def
change_to_rational
(
number
):
"""convert a number to rantional
Keyword arguments: number
return: tuple like (1, 2), (numerator, denominator)
"""
f
=
Fraction
(
str
(
number
))
return
(
f
.
numerator
,
f
.
denominator
)
def
set_gps_location
(
file_name
,
lat
,
lng
,
altitude
):
"""Adds GPS position as EXIF metadata
Keyword arguments:
file_name -- image file
lat -- latitude (as float)
lng -- longitude (as float)
altitude -- altitude (as float)
"""
lat_deg
,
ref_lat
=
to_deg
(
lat
,
[
"S"
,
"N"
])
lng_deg
,
ref_lng
=
to_deg
(
lng
,
[
"W"
,
"E"
])
exif_lat
=
list
(
map
(
change_to_rational
,
lat_deg
))
exif_lng
=
list
(
map
(
change_to_rational
,
lng_deg
))
ref
=
1
if
altitude
<
0
else
0
gps_ifd
=
{
piexif
.
GPSIFD
.
GPSVersionID
:
(
2
,
0
,
0
,
0
),
piexif
.
GPSIFD
.
GPSAltitudeRef
:
ref
,
piexif
.
GPSIFD
.
GPSAltitude
:
change_to_rational
(
abs
(
altitude
)),
piexif
.
GPSIFD
.
GPSLatitudeRef
:
ref_lat
,
piexif
.
GPSIFD
.
GPSLatitude
:
exif_lat
,
piexif
.
GPSIFD
.
GPSLongitudeRef
:
ref_lng
,
piexif
.
GPSIFD
.
GPSLongitude
:
exif_lng
,
}
exif_dict
=
{
"GPS"
:
gps_ifd
}
exif_bytes
=
piexif
.
dump
(
exif_dict
)
piexif
.
insert
(
exif_bytes
,
file_name
)
def
get_gps_location
(
file_name
):
exif_dict
=
piexif
.
load
(
file_name
)
gps
=
exif_dict
[
'GPS'
]
if
len
(
gps
)
==
0
:
return
ref_lat
=
gps
[
piexif
.
GPSIFD
.
GPSLatitudeRef
]
ref_lng
=
gps
[
piexif
.
GPSIFD
.
GPSLongitudeRef
]
ref_alt
=
gps
[
piexif
.
GPSIFD
.
GPSAltitudeRef
]
exif_lat
=
gps
[
piexif
.
GPSIFD
.
GPSLatitude
]
exif_lng
=
gps
[
piexif
.
GPSIFD
.
GPSLongitude
]
exif_alt
=
gps
[
piexif
.
GPSIFD
.
GPSAltitude
]
lat
=
to_dec
(
*
exif_lat
,
(
1
if
ref_lat
==
b
'N'
else
-
1
))
lng
=
to_dec
(
*
exif_lng
,
(
1
if
ref_lng
==
b
'E'
else
-
1
))
alt
=
exif_alt
[
0
]
/
exif_alt
[
1
]
if
ref_alt
==
1
:
alt
*=
-
1
return
lat
,
lng
,
alt
extract_video_with_gps.py
0 → 100644
View file @
a5c21661
import
edit_exif
from
subprocess
import
Popen
,
PIPE
from
path
import
Path
from
argparse
import
ArgumentParser
,
ArgumentDefaultsHelpFormatter
import
pandas
as
pd
from
tqdm
import
tqdm
def
extract_images
(
folder_path
,
file_path
,
fps
):
print
(
"exporting to images with ffmpeg ..."
)
if
fps
is
not
None
:
fps_arg
=
[
"-vf"
,
"fps={}"
.
format
(
fps
)]
output
=
folder_path
/
"{}_fps{}"
.
format
(
file_path
.
namebase
,
fps
)
else
:
fps_arg
=
[]
ffmpeg
=
Popen
([
"ffmpeg"
,
"-y"
,
"-i"
,
str
(
file_path
),
"-qscale:v"
,
"2"
]
+
fps_arg
+
[
str
(
output
/
"{}%05d.jpg"
)],
stdout
=
PIPE
,
stderr
=
PIPE
)
ffmpeg
.
wait
()
def
extract_metadata
(
folder_path
,
file_path
,
native_wrapper
):
name
=
file_path
.
namebase
output_file
=
folder_path
/
name
/
"metadata.csv"
print
(
"extracting metadata with vmeta_extract..."
)
vmeta_extract
=
Popen
([
native_wrapper
,
"vmeta-extract"
,
str
(
file_path
),
"--csv"
,
str
(
output_file
)],
stdout
=
PIPE
,
stderr
=
PIPE
)
vmeta_extract
.
wait
()
def
add_gps_to_exif
(
folder
,
fps
):
csv_file
=
folder
/
"metadata.csv"
metadata
=
pd
.
read_csv
(
csv_file
,
sep
=
" "
)
metadata
=
metadata
.
set_index
(
"time"
)
metadata
.
index
=
pd
.
to_datetime
(
metadata
.
index
,
unit
=
"us"
)
if
fps
is
not
None
:
metadata
=
metadata
.
resample
(
"{:.3f}S"
.
format
(
1
/
fps
)).
first
()
pictures
=
sorted
(
folder
.
files
(
"*.jpg"
))
print
(
"Modifying gps EXIF for colmap..."
)
for
pic_path
,
row
in
tqdm
(
zip
(
pictures
,
metadata
.
iterrows
()),
total
=
len
(
pictures
)):
if
row
[
1
][
"location_valid"
]
==
1
:
edit_exif
.
set_gps_location
(
pic_path
,
row
[
1
][
"location_latitude"
],
row
[
1
][
"location_longitude"
],
row
[
1
][
"location_altitude"
])
def
workflow
(
folder
,
video_path
,
args
):
(
folder
/
video_path
.
namebase
).
mkdir_p
()
print
(
video_path
.
namebase
)
print
(
video_path
)
extract_images
(
folder
,
video_path
,
args
.
fps
)
extract_metadata
(
folder
,
video_path
,
args
.
nw
)
add_gps_to_exif
(
folder
/
video_path
.
namebase
,
args
.
fps
)
parser
=
ArgumentParser
(
description
=
'image extractor from parrot video'
,
formatter_class
=
ArgumentDefaultsHelpFormatter
)
parser
.
add_argument
(
'--root'
,
metavar
=
'DIR'
,
default
=
"~/Images/scan manoir/anafi/video"
,
help
=
'path to video folder root'
)
parser
.
add_argument
(
'--fps'
,
metavar
=
'F'
,
default
=
None
,
type
=
int
,
help
=
'fps'
)
parser
.
add_argument
(
'--nw'
,
default
=
''
,
help
=
"native-wrapper.sh file location"
)
if
__name__
==
'__main__'
:
args
=
parser
.
parse_args
()
root
=
Path
(
args
.
root
)
file_exts
=
[
'.mp4'
,
'.MP4'
]
if
root
.
isdir
():
folders
=
list
(
root
.
walkdirs
())
folders
.
append
(
root
)
for
folder
in
folders
:
videos
=
sum
((
folder
.
files
(
'*{}'
.
format
(
ext
))
for
ext
in
file_exts
),
[])
if
videos
:
print
(
"Generating images with gps for videos in {}"
.
format
(
str
(
folder
)))
for
video_path
in
videos
:
workflow
(
folder
,
video_path
,
args
)
elif
root
.
isfile
()
and
root
.
ext
in
file_exts
:
workflow
(
root
.
parent
,
root
,
args
)
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment