import sys
import json
import pandas as P
import argparse
import re
from pyproj import Transformer
GPS_EXIFS = ['GPSLatitude', 'GPSLongitude']
GPS_RE = re.compile('[^0-9.]+')
def get_args():
parser = argparse.ArgumentParser(description='Vimana VM Command tool')
parser.add_argument('-g', '--gps',
help='Add GPS coords',
action='store_true')
parser.add_argument('--epsg', help='Convert lat long to projected coords (requires --gps)', type=int)
return parser.parse_args()
def normalize_stats(st: dict):
count = st['count']
mean = st['sum'] / count
var = st['sum_2'] / count - mean * mean
std = var ** 0.5
st.update(mean=mean, std_dev=std)
return st
def degree_to_float(deg_str):
deg_comps = GPS_RE.split(deg_str)
deg_float = float(deg_comps[0]) + float(deg_comps[1]) / 60. + float(deg_comps[2]) / 3600.
if deg_str[-1] == "S" or deg_str[-1] == "W": deg_float = -deg_float
return deg_float
def add_gps_coords(stat, proj_t: Transformer = None):
exif = json.load(open(stat['path']))
if isinstance(exif, list): exif = exif[0]
lat = degree_to_float(exif['GPSLatitude'])
lon = degree_to_float(exif['GPSLongitude'])
stat['latitude'] = lat
stat['longitude'] = lon
if proj_t is not None:
(east, north) = proj_t.transform(lat, lon)
stat['easting'] = east
stat['northing'] = north
def main():
args = get_args()
stats_json = json.load(sys.stdin)
proj_t = None
if args.gps and args.epsg:
proj_t = Transformer.from_crs(4326, args.epsg)
df = []
for im_stat in stats_json['image_stats']:
stat = normalize_stats(im_stat['stats'])
im_stat.update(**stat)
if args.gps: add_gps_coords(im_stat, proj_t=proj_t)
df.append(im_stat)
tot = normalize_stats(stats_json['cumulative'])
tot.update(path="cumulative")
df.append(tot)
df = P.DataFrame(df)
cols = 'path,width,height,min,max,mean,std_dev'.split(',')
if args.gps:
cols = cols + ['latitude', 'longitude']
if args.epsg is not None:
cols = cols + ['easting', 'northing']
df = df[cols]
df.to_csv(sys.stdout, index=False)
if __name__ == '__main__':
main()