File size: 3,432 Bytes
0914710
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
"""functions using machine learning instance model(s)"""
from samgis import app_logger, MODEL_FOLDER
from samgis.io.geo_helpers import get_vectorized_raster_as_geojson
from samgis.io.raster_helpers import get_raster_terrain_rgb_like, get_rgb_prediction_image
from samgis.io.tms2geotiff import download_extent
from samgis.io.wrappers_helpers import check_source_type_is_terrain
from samgis.prediction_api.global_models import models_dict
from samgis.utilities.constants import DEFAULT_URL_TILES, SLOPE_CELLSIZE
from samgis_core.prediction_api.sam_onnx import SegmentAnythingONNX
from samgis_core.prediction_api.sam_onnx import get_raster_inference
from samgis_core.utilities.constants import MODEL_ENCODER_NAME, MODEL_DECODER_NAME, DEFAULT_INPUT_SHAPE
from samgis_core.utilities.type_hints import llist_float, dict_str_int, list_dict


def samexporter_predict(
        bbox: llist_float,
        prompt: list_dict,
        zoom: float,
        model_name_key: str = "fastsam",
        source: str = DEFAULT_URL_TILES
) -> dict_str_int:
    """
    Return predictions as a geojson from a geo-referenced image using the given input prompt.

    1. if necessary instantiate a segment anything machine learning instance model
    2. download a geo-referenced raster image delimited by the coordinates bounding box (bbox)
    3. get a prediction image from the segment anything instance model using the input prompt
    4. get a geo-referenced geojson from the prediction image

    Args:
        bbox: coordinates bounding box
        prompt: machine learning input prompt
        zoom: Level of detail
        model_name_key: machine learning model name
        source: xyz

    Returns:
        Affine transform
    """
    if models_dict[model_name_key]["instance"] is None:
        app_logger.info(f"missing instance model {model_name_key}, instantiating it now!")
        model_instance = SegmentAnythingONNX(
            encoder_model_path=MODEL_FOLDER / MODEL_ENCODER_NAME,
            decoder_model_path=MODEL_FOLDER / MODEL_DECODER_NAME
        )
        models_dict[model_name_key]["instance"] = model_instance
    app_logger.debug(f"using a {model_name_key} instance model...")
    models_instance = models_dict[model_name_key]["instance"]

    pt0, pt1 = bbox
    app_logger.info(f"tile_source: {source}: downloading geo-referenced raster with bbox {bbox}, zoom {zoom}.")
    img, transform = download_extent(w=pt1[1], s=pt1[0], e=pt0[1], n=pt0[0], zoom=zoom, source=source)
    if check_source_type_is_terrain(source):
        app_logger.info("terrain-rgb like raster: transforms it into a DEM")
        dem = get_raster_terrain_rgb_like(img, source.name)
        # set a slope cell size proportional to the image width
        slope_cellsize = int(img.shape[1] * SLOPE_CELLSIZE / DEFAULT_INPUT_SHAPE[1])
        app_logger.info(f"terrain-rgb like raster: compute slope, curvature using {slope_cellsize} as cell size.")
        img = get_rgb_prediction_image(dem, slope_cellsize)

    app_logger.info(
        f"img type {type(img)} with shape/size:{img.size}, transform type: {type(transform)}, transform:{transform}.")

    mask, n_predictions = get_raster_inference(img, prompt, models_instance, model_name_key)
    app_logger.info(f"created {n_predictions} masks, preparing conversion to geojson...")
    return {
        "n_predictions": n_predictions,
        **get_vectorized_raster_as_geojson(mask, transform)
    }