93 lines
3.2 KiB
Python
93 lines
3.2 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
# \file Triskele.py
|
|
# \brief TODO
|
|
# \author Florent Guiotte <florent.guiotte@gmail.com>
|
|
# \version 0.1
|
|
# \date 22 mars 2018
|
|
#
|
|
# TODO details
|
|
|
|
import os
|
|
import subprocess
|
|
from pathlib import Path
|
|
import numpy as np
|
|
from .CreaTIFF import read, write
|
|
|
|
class Triskele:
|
|
def __init__(self, raster, dtype=np.uint8, cache_dir='/tmp', verbose=True):
|
|
|
|
self.verbose = verbose
|
|
self.triskele_bin = Path(os.path.dirname(os.path.realpath(__file__))\
|
|
+ '/../../build/out/apGenerator')
|
|
self.cache_dir = Path(cache_dir)
|
|
|
|
if not self.triskele_bin.exists():
|
|
raise EnvironmentError ('TRISKELE bin not found: {}'.format(self.triskele_bin))
|
|
|
|
if not self.cache_dir.exists():
|
|
raise EnvironmentError ('Cache directory not found: {}'.format(self.cache_dir))
|
|
|
|
self.infile = self.cache_dir.joinpath('infile.tif')
|
|
self.outfile = self.cache_dir.joinpath('outfile.tif')
|
|
|
|
self.areafile = self.cache_dir.joinpath('areafile.txt')
|
|
self.sdfile = self.cache_dir.joinpath('sdfile.txt')
|
|
self.moifile = self.cache_dir.joinpath('moifile.txt')
|
|
|
|
self._write_infile(raster, dtype)
|
|
|
|
def filter(self, tree='max-tree', area=None, standard_deviation=None, moment_of_inertia=None, feature='weight'):
|
|
self._setup(tree, area, standard_deviation, moment_of_inertia, feature)
|
|
self._run()
|
|
return self._read_outfile()
|
|
|
|
def _read_outfile(self):
|
|
return read(self.outfile)
|
|
|
|
def _write_infile(self, rasters, dtype):
|
|
## Expand if rasters is 2D
|
|
if len(rasters.shape) < 3:
|
|
rasters = np.expand_dims(rasters, 2)
|
|
|
|
## Scale to new dtype
|
|
rep = np.iinfo(dtype)
|
|
|
|
rasters = rasters.astype(np.float64)
|
|
|
|
## Channel independant scale
|
|
for i in range(rasters.shape[2]):
|
|
rasters[:,:,i] -= rasters[:,:,i].min() - rep.min
|
|
rasters[:,:,i] *= (rep.max - rep.min) / (rasters[:,:,i].max() - rasters[:,:,i].min())
|
|
|
|
rasters = rasters.astype(dtype)
|
|
write(self.infile, rasters)
|
|
|
|
def _setup(self, tree, area, standard_deviation, moment_of_inertia, feature):
|
|
self.process = [self.triskele_bin,
|
|
'-i', '{}'.format(self.infile),
|
|
'-o', '{}'.format(self.outfile),
|
|
'--{}'.format(tree),
|
|
'--f-{}'.format(feature)]
|
|
|
|
if area is not None:
|
|
np.savetxt(self.areafile, area, fmt='%d')
|
|
self.process.extend(['--area', '{}'.format(self.areafile)])
|
|
|
|
if standard_deviation is not None:
|
|
np.savetxt(self.sdfile, standard_deviation, fmt='%f')
|
|
self.process.extend(['--standard-deviation', '{}'.format(self.sdfile)])
|
|
|
|
if moment_of_inertia is not None:
|
|
np.savetxt(self.moifile, moment_of_inertia, fmt='%f')
|
|
self.process.extend(['--moment-of-inertia', '{}'.format(self.moifile)])
|
|
|
|
def _run(self):
|
|
|
|
tryskele = subprocess.Popen(self.process, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
tryskele.wait()
|
|
|
|
if self.verbose:
|
|
print('STDOUT:\n' + tryskele.stdout.read().decode() + \
|
|
'\nSTDERR:\n' + tryskele.stderr.read().decode())
|