Skip to content

Instantly share code, notes, and snippets.

View mlubej's full-sized avatar

Matic Lubej mlubej

  • EO Research Team @ Sinergise
  • Ljubljana, Slovenia
View GitHub Profile
@mlubej
mlubej / hillshade.py
Created April 8, 2024 13:41
Calculate hillshade from DEM
import cv2
import numpy as np
def get_hillshade(dem: np.ndarray, azimuth: float, zenith: float, resolution: int):
"""Calculates hillshade from DEM."""
# calculate gradient using open-cv
grad_x = cv2.Sobel(dem, cv2.CV_32F, 1, 0, ksize=3) / resolution / 8
grad_y = cv2.Sobel(dem, cv2.CV_32F, 0, 1, ksize=3) / resolution / 8
@mlubej
mlubej / yabai_spaces.py
Created September 16, 2022 14:07
custom functions to ignore mac native-fullscreen apps with yabai
import json
import subprocess
import sys
from typing import Dict, List
import numpy as np
def get_nth_space(index: int) -> int:
spaces = get_non_native_spaces()
@mlubej
mlubej / evalscript_mowing.js
Last active November 2, 2021 11:30
A proof-of-principle Sentinel Hub Evalscript for detecting mowing events on the pixel level
//VERSION=3
function setup() {
return {
input: ["B04", "B08", "CLP", "dataMask"],
output: {bands: 2, sampleType: SampleType.INT8},
mosaicking: "ORBIT"
}
}
import subprocess
from sentinelhub import CRS
# rescale to a lower resolution
nres = 120*10
target_crs = CRS.WGS84.epsg
def create_rgb_per_timestamp(batch_tile_name):
subprocess.run(f'gdalwarp -tr {nres} {nres} <INPUT HI-RES RED> <OUTPUT LO_RES RED>', shell=True)
# repeat for green and blue ...
import subprocess
# tasks for exporting to .tiffs
export_r = ExportToTiff(feature=(FeatureType.DATA, 'RGB'), folder='./tiffs/', band_indices=[0])
export_g = ExportToTiff(feature=(FeatureType.DATA, 'RGB'), folder='./tiffs/', band_indices=[1])
export_b = ExportToTiff(feature=(FeatureType.DATA, 'RGB'), folder='./tiffs/', band_indices=[2])
# gdal magic for spatial merge
subprocess.run(f'gdal_merge.py -n 0 -a_nodata 0 -o tiffs/r.tiff -co compress=LZW tiffs/r_patch_*.tiff && rm -rf tiffs/r_patch_*.tiff', shell=True);
subprocess.run(f'gdal_merge.py -n 0 -a_nodata 0 -o tiffs/g.tiff -co compress=LZW tiffs/g_patch_*.tiff && rm -rf tiffs/g_patch_*.tiff', shell=True);
@mlubej
mlubej / gif_maker.py
Last active January 22, 2021 21:56
gif_maker.py
import ffmpeg
# video related
stream = ffmpeg.input('<INPUT_IMAGES>', pattern_type='glob', framerate=<FPS>) # load image stream
stream = stream.filter('pad', w='ceil(iw/2)*2', h='ceil(ih/2)*2', color='white') # pad the image
split = stream.split() # split for multiple usecases
video = split[0] # define the video stream
# gif related
palette = split[1].filter('palettegen', reserve_transparent=True, stats_mode='diff') # determine time-lapse specific color pallete to reduce dithering
import ephem
import numpy as np
from datetime import datetime
def get_shadow_length(long, lat, datetime, height):
"""
Accepts longitude and latitude in the WGS84 CRS, along with the
datetime in the UTC time zone. Returns the length of a shadow of an object
with a specified height at the specified time and location.
"""
//VERSION=3
function setup() {
return {
input: ["B04", "B08", "CLM"],
output: { bands: 2 }
};
}
function evaluatePixel(sample) {
let ndvi = index(sample.B08, sample.B04);
band_names = ['B02', 'B03', 'B04', 'B08', 'B11', 'B12']
add_data = SentinelHubInputTask(
bands_feature=(FeatureType.DATA, 'BANDS'),
bands = band_names,
resolution=10,
maxcc=0.8,
time_difference=datetime.timedelta(minutes=120),
data_source=DataSource.SENTINEL2_L1C,
additional_data=[(FeatureType.MASK, 'dataMask'),
def mate(self, partner):
"""
Create offspring with a order-crossover method
:param partner: a second p1 which will participate in the mating
:return: two new offspring individuals
"""
c1, c2 = np.zeros((2, self.n_pieces), dtype=int)
start, end = np.sort(np.random.choice(range(self.n_pieces), 2, replace=False))
p1 = self.chromosome