# Prepare raw data (dula-fish eyes images from insta360)
# and put them into "input/"
mkdir input/
cp /path/to/your/insta360-folders/*.insp input/
# Generate panorama images to "output/"
make panorama
# You may filter out some unecessary images from "output/" by some reasons
# Put images you want to upload to Kartaview and Mapillary into "upload/"
cp -r output/ upload/
# This generate GeoJSON file for each image location
# You can read it on other softwares (like geojson.io) to make sure locations in EXIF are correct
make photos.geojson
# Check time period of images and GPX file
make stat_exif
GPX=your-gpx-file make stat_gpx
# IF you want to correct locations by time with GPX file, try command 'fix-gps':
# 1. Specify GPX file by variable 'GPX'
# 2. If GPX file contains track point which time is same to image,
# then location in image EXIF would be modified.
#
# Image would be rename with '_modified', for example:
# 2022_0807_999.jpg -> 2022_0807_999_modified.jpg
# 3. If you want to add track points by interpolation,
# set variable INTERPOLATION=true
GPX=your-gpx-file INTERPOLATION=true make fix-gps
# Now generate a new GeoJSON file and check again
make photos.geojson
# Upload images in "upload/" to Kartaview
make upload
Last active
June 1, 2023 04:25
-
-
Save typebrook/87babb88170f85607a29364712c108e0 to your computer and use it in GitHub Desktop.
Insta 360 Panorama solution with https://github.com/trek-view/fusion2sphere
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
input/ | |
output/ | |
upload/ | |
**/.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*/ | |
input/ | |
*.gpx | |
track | |
fusion2sphere | |
tmp | |
photos.geojson | |
metadata | |
install |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /bin/bash | |
# Usage: | |
# ./add-gps-into-exif test.jpg TRACKFILE | |
# | |
# TRACKFILE should contains fields "epoch", "longitude" "latitude" "elevation"(optional) in each line | |
# You can specify REMOVE_UNMATCHED=true to remove unmatched images | |
image="$1" | |
track="$2" | |
# Get Time and epoch from image | |
time=`exiftool "$image" -s -s -s -CreateDate` | |
epoch=`date +%s -d ${time:0:4}-${time:5:2}-${time:8:2}T${time:11:8}Z$TZ` | |
record="`grep ^$epoch $track | head -1`" | |
if [ -n "$record" ]; then | |
read _ lon lat ele <<<"$record" | |
echo $epoch $lon $lat | |
exiftool $image \ | |
-overwrite_original \ | |
-gpslongitude=$lon \ | |
-gpslatitude=$lat \ | |
-gpslongituderef=E \ | |
-gpslatituderef=N \ | |
&>/dev/null | |
mv $image ${image%.*}_modified.${image#*.} | |
elif [[ $REMOVE_UNMATCHED == true ]]; then | |
echo rm $image | |
rm $image | |
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FROM ubuntu:18.04 | |
RUN apt-get update && \ | |
apt-get install -y \ | |
git \ | |
make \ | |
gcc \ | |
libjpeg-dev \ | |
imagemagick \ | |
exiftool \ | |
jq \ | |
proj-bin \ | |
curl \ | |
python \ | |
python3-pip \ | |
bc | |
RUN pip3 install yq | |
COPY ./ /app | |
WORKDIR /app | |
RUN make fusion2sphere install |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /bin/bash | |
while getopts 'i:o:' arg; do | |
case $arg in | |
i) INSP=$OPTARG ;; | |
o) OUTPUT_DIR=$OPTARG ;; | |
esac | |
done | |
if [ -z $INSP ]; then | |
echo Please give Insta 360 file with '-i' option | |
exit 1 | |
elif [ -z $OUTPUT_DIR ]; then | |
echo Please give output dir with '-o' option | |
exit 1 | |
fi | |
OUTPUT_DIR=${OUTPUT_DIR%/} | |
mkdir -p $OUTPUT_DIR | |
img=`basename ${INSP%.insp}` | |
origin=/tmp/${img}_origin.jpg | |
left=/tmp/${img}_1.jpg | |
right=/tmp/${img}_2.jpg | |
output=${OUTPUT_DIR}/${img}.jpg | |
trap "rm $origin $left $right &>/dev/null" EXIT | |
convert $INSP $origin | |
convert $origin -crop 3040x3040+0+0 -rotate 90 $left | |
convert $origin -crop 3040x3040+3040+0 -rotate 270 $right | |
./fusion2sphere -b 10 -w 5800 -f $left $right -o $output photo-mode.txt | |
exiftool &>/dev/null \ | |
-overwrite_original \ | |
-UsePanoramaViewer=TRUE \ | |
-ProjectionType="equirectangular" \ | |
-tagsFromFile $origin $output \ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /bin/bash | |
set -o pipefail | |
echo $1 | |
[ -z "$1" ] && echo 'Please specify GPX file as first argument' && exit 1 | |
_get_interpolation() { | |
read epoch1 lon1 lat1 ele1 epoch2 lon2 lat2 ele2 | |
DIFF=$(( $epoch1 - $epoch2 )) | |
for (( i=1; i<=$(( $DIFF - 1 )); i++ )); do | |
echo $(( $epoch2 + $i )) | |
echo 'scale=7; ' $lon2 '+ (' $lon1 - $lon2 ') *' "$i/$DIFF" | bc -l | |
echo 'scale=7; ' $lat2 '+ (' $lat1 - $lat2 ') *' "$i/$DIFF" | bc -l | |
echo 'scale=2; ' $ele2 '+ (' $ele1 - $ele2 ') *' "$i/$DIFF" | bc -l | |
done | paste -d' ' - - - - | |
} | |
xq -r \ | |
--xml-force-list trk \ | |
--xml-force-list trkseg \ | |
--xml-force-list trkpt \ | |
'.gpx.trk[].trkseg[].trkpt[] | "\(.time) \(."@lon") \(."@lat") \(.ele)" ' \ | |
"$1" >track_info.tmp && \ | |
paste -d' ' <(cut -d' ' -f1 track_info.tmp | date +%s -f -) <(cut -d' ' -f2-4 track_info.tmp) | \ | |
while read epoch record; do | |
if [ "$INTERPOLATION" = true ] && (( $epoch - ${LAST_EPOCH:-$epoch} > 1 )); then | |
echo $epoch $record $LAST_EPOCH $LAST_RECORD | _get_interpolation | |
fi | |
echo $epoch $record | |
LAST_EPOCH=$epoch | |
LAST_RECORD=$record | |
done >track | |
rm track_info.tmp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.ONESHELL: | |
.PHONY: panorama photos.geojson metadata upload | |
SHELL := bash | |
IMAGE := street-view:1.1 | |
HUGO := klakegg/hugo:0.101.0 | |
export INPUT_DIR?=input | |
export OUTPUT_DIR?=output | |
export UPLOAD_DIR?=upload | |
stat_exif: | |
@exiftool $(INPUT_DIR)/* -s -s -s -CreateDate | \ | |
sed '/^==/d;$$d' | \ | |
sort | \ | |
sed -n -E '1s/^/Start: \t/; 1p; $$s/^/End: \t/; $$p' | |
stat_gpx: | |
@xq -r \ | |
--xml-force-list trk \ | |
--xml-force-list trkseg \ | |
--xml-force-list trkpt \ | |
'.gpx.trk[].trkseg[].trkpt[].time' $(GPX) | \ | |
date --iso-8601=seconds -f - | \ | |
sort | \ | |
sed -n -E '1s/^/Start: \t/; 1p; $$s/^/End: \t/; $$p' | |
panorama: fusion2sphere | |
count=$$(ls $(INPUT_DIR)/*insp | wc -l) | |
find -L $(INPUT_DIR) -name '*insp' | nl | \ | |
while read index insp; do | |
echo $$index/$$count | |
./insp2panorama -i $$insp -o $(OUTPUT_DIR) & | |
while [ $$(jobs -r | wc -l) -ge $$(nproc) ]; do | |
sleep 0.3 | |
done | |
done | |
repo-fusion2sphere: | |
git clone --depth=1 [email protected]:trek-view/fusion2sphere $@ | |
fusion2sphere: repo-fusion2sphere | |
make -C $^ | |
ln -sf $^/$@ ./$@ | |
photos.geojson: | |
find -L $(UPLOAD_DIR) -name '*.jpg' | \ | |
xargs exiftool -s -s -s -gpslongitude -gpslatitude -gpsaltitude -CreateDate | \ | |
sed '/^=/d; $$d; s/ m Above Sea Level//; s/deg/d/; /d/ s/ //g; s/ /_/' | \ | |
paste -d' ' - - - - | \ | |
sort -k4 | \ | |
cs2cs -f %.7f +init=epsg:4326 +to +init=epsg:4326 | \ | |
awk '{ print "[" $$1 "," $$2 "," $$3 "]" }' | \ | |
jq -s '{type: "Feature", properties: {}, geometry: {type: "LineString", coordinates: .}}' >$@ | |
export INTERPOLATION?=false | |
track: | |
./make-track-from-GPX $(GPX) | |
export TZ=+0800 | |
export REMOVE_UNMATCHED?=false | |
fix-gps: track | |
find -L $(UPLOAD_DIR) -name '*jpg' | \ | |
while read file; do | |
./add-gps-into-exif $$file $< & | |
while [ $$(jobs -r | wc -l) -ge $$(nproc) ]; do | |
sleep 0.3 | |
done | |
done | |
upload-scripts/osc_tools.py: | |
git clone --depth=1 [email protected]:typebrook/upload-scripts | |
install: upload-scripts/osc_tools.py | |
pip3 install -r upload-scripts/requirements.txt && touch $@ | |
upload: upload-scripts/osc_tools.py | |
$< upload --path $(UPLOAD_DIR) | |
metadata: | |
sequence_id=`jq -r .id $(UPLOAD_DIR)/osc_sequence_id.txt` | |
curl https://api.openstreetcam.org/2.0/sequence/$${sequence_id}/photos | \ | |
jq . >$@ | |
clean: | |
rm -rf upload-scripts fusion2sphere install track | |
docker: repo-fusion2sphere upload-scripts/osc_tools.py | |
[ -z "`docker images -q $(IMAGE)`" ] && docker build . -t $(IMAGE) | |
docker run -it --rm \ | |
--user `id -u`:`id -g` \ | |
--volume /etc/passwd:/etc/passwd:ro \ | |
--volume /etc/group:/etc/group:ro \ | |
--volume `pwd`:/app \ | |
$(IMAGE) $(COMMAND) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# left/front - 3104 x 3000 | |
IMAGE: | |
RADIUS: 1450 | |
CENTER: 1520 1520 | |
FOV: 190 | |
# right/back - 3104 x 3000 | |
IMAGE: | |
RADIUS: 1450 | |
CENTER: 1520 1520 | |
FOV: 190 | |
# recommended output width = 5760 (gives final dimensions of 5760 × 2880) | |
# 0.25 pt = 1440, 0.75 pt = 4320 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment