コード例 #1
0
ファイル: renderer.py プロジェクト: chrhein/dem-to-depth
def execute_pov(params):
    pov_filename, out_filename, dimensions, mode = params
    out_width, out_height = dimensions
    p_i("Generating %s" % out_filename)
    if mode == "color" or mode == "gradient":
        subprocess.call([
            "povray",
            "+W%d" % out_width,
            "+H%d" % out_height,
            "Output_File_Type=N Bits_Per_Color=16 +Q8 +UR +A",
            "-GA",
            "+I" + pov_filename,
            "+O" + out_filename,
        ])
    else:
        subprocess.call([
            "povray",
            "+W%d" % out_width,
            "+H%d" % out_height,
            "Output_File_Type=N Bits_Per_Color=16 Display=off",
            "-GA",
            "Antialias=off Quality=0 File_Gamma=1.0",
            "+I" + pov_filename,
            "+O" + out_filename,
        ])
コード例 #2
0
def vertical_stack_imshow_divider(im1, im2, title="Preview", div_thickness=3):
    try:
        _, im1_w, _ = im1.shape
    except ValueError:
        im1 = cv2.cvtColor(im1, cv2.COLOR_GRAY2BGR)
        _, im1_w, _ = im1.shape
    try:
        _, im2_w, _ = im2.shape
    except ValueError:
        im2 = cv2.cvtColor(im2, cv2.COLOR_GRAY2BGR)
        _, im2_w, _ = im2.shape
    m = min(im1_w, im2_w)
    if im1_w != im2_w:
        im1 = resizer(im1, im_width=m)
        im2 = resizer(im2, im_width=m)
    divider = np.zeros((div_thickness, m, 3), np.uint8)
    divider[:, 0:m] = (255, 255, 255)
    stack = np.vstack((im1, divider, im2))
    to_save = custom_imshow(stack, title)
    if to_save:
        path = askdirectory(title="Select Folder")
        if path:
            filename = p_in("Filename: ")
            save_image(im2, filename, path)
            p_i("File was saved")
コード例 #3
0
def structured_forest(image):
    p_i("Starting Structured Forest Edge Detection...")
    sf = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    sf = sf.astype(np.float32) / 512.0
    edge_detector = cv2.ximgproc.createStructuredEdgeDetection(
        "assets/model.yml")
    edges = edge_detector.detectEdges(sf) * 512.0
    p_i("Structured Forest Edge Detection complete!")
    return edges
コード例 #4
0
def canny_edge_detection(image, interactive_window=True, blur_factor=5):
    p_i("Starting Canny Edge Detection...")
    # automatically set lb and ub values from the median color in the image
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    v = np.median(gray)
    sigma = 0.5
    lb = int(max(0, (1.0 - sigma) * v))
    ub = int(min(100, (1.0 + sigma) * v))

    blurred = cv2.medianBlur(gray, blur_factor)
    if not interactive_window:
        p_i("Canny Edge Detection complete!")
        return cv2.Canny(blurred, lb, ub, apertureSize=5)

    p_i("Opening external window")
    n = "Canny Edge Detection"
    cv2.namedWindow(n)
    cv2.createTrackbar("Lower Bound", n, lb, 100, nothing)
    cv2.createTrackbar("Upper Bound", n, ub, 100, nothing)
    cv2.createTrackbar("Dilate Horizontal", n, 1, 20, nothing)
    cv2.createTrackbar("Dilate Vertical", n, 1, 20, nothing)
    while True:
        lb = cv2.getTrackbarPos("Lower Bound", n)
        ub = cv2.getTrackbarPos("Upper Bound", n)
        d_h = cv2.getTrackbarPos("Dilate Horizontal", n)
        d_v = cv2.getTrackbarPos("Dilate Vertical", n)
        edges = cv2.Canny(blurred, lb, ub)
        kernel = np.ones((d_v, d_h), np.uint8)
        dilated = cv2.dilate(edges, kernel, iterations=1)
        cv2.imshow(n, dilated)
        k = cv2.waitKey(1) & 0xFF
        if k == 27:  # use escape for exiting window
            cv2.destroyAllWindows()
            p_i("Canny Edge Detection complete!")
            return dilated
コード例 #5
0
def holistically_nested(image):
    p_i("Starting Holistically-Nested Edge Detection...")
    net = cv2.dnn.readNetFromCaffe(
        "data/hed_model/deploy.prototxt",
        "data/hed_model/" + "hed_pretrained_bsds.caffemodel",
    )
    height, width = image.shape[:2]
    cv2.dnn_registerLayer("Crop", CropLayer)
    blob = cv2.dnn.blobFromImage(image, size=(width, height))
    net.setInput(blob)
    hed = (255 * cv2.resize(net.forward()[0, 0],
                            (width, height))).astype("uint8")
    p_i("Holistically-Nested Edge Detection complete!")
    cv2.dnn_unregisterLayer("Crop")
    return hed
コード例 #6
0
ファイル: run.py プロジェクト: chrhein/dem-to-depth
def mark_image_seen(img_data):
    p_i('Marking image as seen')
    if img_data.view_direction is None:
        return
    make_folder(f"{UPLOAD_FOLDER}dev/")
    try:
        h = open(SEEN_IMAGES_PATH, "r")
        seen_images = h.readlines()
        h.close()
        if img_data.filename in seen_images or f"{img_data.filename}\n" in seen_images:
            return
        else:
            h = open(SEEN_IMAGES_PATH, "a")
            h.write(f"{img_data.filename}\n")
            h.close()

    except FileNotFoundError:
        h = open(SEEN_IMAGES_PATH, "a")
        h.write(f"{img_data.filename}\n")
        h.close()
コード例 #7
0
def reset_image(im):
    p_i(f"Resetting image {im}")
    IMAGE_DATA = load_image_data(im)
    try:
        os.remove(IMAGE_DATA.overlay_path)
    except (AttributeError, FileNotFoundError):
        pass
    try:
        os.remove(IMAGE_DATA.ultrawide_path)
    except (AttributeError, FileNotFoundError):
        pass
    try:
        os.remove(IMAGE_DATA.warped_panorama_path)
    except (AttributeError, FileNotFoundError):
        pass
    IMAGE_DATA.view_direction = None
    IMAGE_DATA.fov_l = None
    IMAGE_DATA.fov_r = None
    IMAGE_DATA.location = None
    IMAGE_DATA.transform_matrix = None
    save_image_data(IMAGE_DATA)
コード例 #8
0
def get_3d_location(camera_location, dataset, fov):
    def get_initial_bearing(camera_location, object_location):
        c_lon = radians(camera_location.longitude)
        c_lat = radians(camera_location.latitude)
        o_lon = radians(object_location.longitude)
        o_lat = radians(object_location.latitude)

        diff_lon = o_lon - c_lon

        x = sin(diff_lon) * cos(o_lat)
        y = cos(c_lat) * sin(o_lat) - sin(c_lat) * cos(o_lat) * cos(diff_lon)

        init_bearing = degrees(atan2(x, y))
        compass_bearing = (init_bearing + 360) % 360

        return compass_bearing

    def get_3d_placement(camera_location, item, generator):
        d = generator.get_distance_between_locations(camera_location,
                                                     item.location)
        c_e = camera_location.elevation + 25
        i_e = item.location.elevation
        diff = i_e - c_e
        h = (d**2 + diff**2)**0.5
        pitch = degrees(asin(diff / h))
        yaw = get_initial_bearing(camera_location, item.location)
        return yaw, pitch, d

    generator = Distance()
    new_ds = []
    p_i(f"Field of View: {fov[0]}-{fov[1]}")
    for item in dataset:
        yaw, pitch, d = get_3d_placement(camera_location, item, generator)
        item.set_location_in_3d(Location3D(yaw=yaw, pitch=pitch, distance=d))
        p_i(f"{item.name} at {item.location_in_3d}")
        if yaw < fov[0] or yaw > fov[1]:
            new_ds.append(item)

    return new_ds
コード例 #9
0
ファイル: renderer.py プロジェクト: chrhein/dem-to-depth
def generate_viewshed(img_data):
    cropped_dem, coordinates, image_location, elevation = pickle.load(
        open(f"{img_data.folder}/vs.pkl", "rb"))
    ds_raster = rasterio.open(cropped_dem)
    p_i(f"Creating viewshed for {img_data.filename}")
    converter = LatLngToCrs(int(ds_raster.crs.to_authority()[1]))
    locxy = converter.convert(coordinates[0], coordinates[1])
    vs_created = create_viewshed(cropped_dem, (locxy.GetX(), locxy.GetY()),
                                 img_data.folder)
    if not vs_created:
        p_e(f"Failed to create viewshed for {img_data.filename}")
        return False
    load_dotenv()
    api_key = os.getenv("MAPBOX_TOKEN")
    url = f"https://api.mapbox.com/geocoding/v5/mapbox.places/{image_location.longitude},{image_location.latitude}.json?access_token={api_key}"
    headers = CaseInsensitiveDict()
    headers["Accept"] = "application/json"
    resp = requests.get(url, headers=headers).json()
    place_name = resp["features"][0]["text"]
    img_data.place_name = place_name
    img_data.place_elevation = elevation
    save_image_data(img_data)
    return True
コード例 #10
0
def tui_select(it, itt="", in_t="", e_t="", afd=False):
    formatted_text = []
    for i in range(len(it)):
        formatted_text.append("%i: %s" % (i + 1, it[i]))
    formatted_text.append("0: exit")
    p_line()
    p_i(itt)
    p_line(formatted_text)
    while True:
        try:
            mode = p_in(in_t)
            if mode == "debug" and afd:
                return mode
            mode = int(mode)
        except ValueError:
            p_e(e_t)
            continue
        if mode == 0:
            exit()
        if mode < 1 or mode > len(it):
            p_e(e_t)
            continue
        return mode
コード例 #11
0
def create_route_texture(dem_file, gpx_path, debugging=False):
    filename = gpx_path.split("/")[-1].split(".")[0]
    folder = "exports/%s/texture" % filename
    if debugging:
        im_path = "%s/%s-texture-debug.png" % (folder, filename)
    else:
        im_path = "%s/%s-texture.png" % (folder, filename)
    try:
        os.mkdir(folder)
    except FileExistsError:
        pass
    texture_bounds_path = "%s/%s-texture-bounds.pkl" % (folder, filename)
    texture_exist = os.path.isfile("%s" % im_path)
    bounds_exist = os.path.isfile("%s" % texture_bounds_path)
    if texture_exist and bounds_exist:
        with open(texture_bounds_path, "rb") as f:
            tex_bounds = pickle.load(f)
        return [im_path, tex_bounds]

    p_i(f"Creating route texture for {filename}")

    mns, minimums, maximums = read_hike_gpx(gpx_path)
    ds_raster = rasterio.open(dem_file)
    crs = int(ds_raster.crs.to_authority()[1])
    converter = LatLngToCrs(crs)
    lower_left = converter.convert(minimums[0].latitude, minimums[1].longitude)
    upper_right = converter.convert(maximums[0].latitude,
                                    maximums[1].longitude)

    bbox = (
        lower_left.GetX(),
        upper_right.GetY(),
        upper_right.GetX(),
        lower_left.GetY(),
    )

    gdal.Translate(f"{folder}/{filename}-output_crop_raster.tif",
                   dem_file,
                   projWin=bbox)

    im = cv2.imread(f"{folder}/{filename}-output_crop_raster.tif")
    h, w, _ = im.shape
    rs = 1
    if debugging:
        rs = 20

    multiplier = 100

    h = h * multiplier
    w = w * multiplier
    if not mns:
        return ["", ""]
    img = np.ones([h, w, 4], dtype=np.uint8)
    ds_raster = rasterio.open(dem_file)
    crs = int(ds_raster.crs.to_authority()[1])
    b = ds_raster.bounds
    bounds = [b.left, b.bottom, b.right, b.top]
    converter = LatLngToCrs(crs)
    locs = [
        convert_single_coordinate_pair(bounds, converter, i.latitude,
                                       i.longitude) for i in mns
    ]
    prev_lat = abs(int(((100.0 * locs[0][0]) / 100) * w))
    prev_lon = h - abs(int(100.0 - ((100.0 * locs[0][1]) / 100.0) * h))
    for i in locs:
        lat, lon = i
        x = h - abs(int(100.0 - ((100.0 * lon) / 100.0) * h))
        y = abs(int(((100.0 * lat) / 100.0) * w))
        cv2.line(img, (prev_lat, prev_lon), (y, x), (0, 0, 255, 255), 3 * rs)
        prev_lat, prev_lon = y, x
    min_lat_p = minimums[0]
    min_lon_p = minimums[1]
    max_lat_p = maximums[0]
    max_lon_p = maximums[1]
    min_x = convert_single_coordinate_pair(bounds, converter,
                                           min_lat_p.latitude,
                                           min_lat_p.longitude)
    min_y = convert_single_coordinate_pair(bounds, converter,
                                           min_lon_p.latitude,
                                           min_lon_p.longitude)
    max_x = convert_single_coordinate_pair(bounds, converter,
                                           max_lat_p.latitude,
                                           max_lat_p.longitude)
    max_y = convert_single_coordinate_pair(bounds, converter,
                                           max_lon_p.latitude,
                                           max_lon_p.longitude)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, thresh = cv2.threshold(gray, 1, 255, cv2.THRESH_BINARY)
    contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL,
                                   cv2.CHAIN_APPROX_SIMPLE)
    cnt = contours[0]
    x, y, w, h = cv2.boundingRect(cnt)
    crop = img[y:y + h, x:x + w]
    cv2.imwrite(im_path, crop)

    tex_bounds = TextureBounds(
        min_lat=min_lat_p,
        min_lon=min_lon_p,
        max_lat=max_lat_p,
        max_lon=max_lon_p,
        min_x=min_x,
        min_y=min_y,
        max_x=max_x,
        max_y=max_y,
    )

    p_i("Route texture complete")

    with open(texture_bounds_path, "wb") as f:
        pickle.dump(tex_bounds, f)

    subprocess.call(
        ["rm", "-r", f"{folder}/{filename}-output_crop_raster.tif"])

    return [im_path, tex_bounds]
コード例 #12
0
def plot_to_map(
    camera_pano_path,
    mountains_in_sight,
    coordinates,
    filename,
    dem_file,
    converter,
    locs=None,
    mountains=None,
    images=None,
):
    p_i("Creating Interactive Map")
    c_lat, c_lon, _, _ = coordinates
    ll, ul, ur, lr = location_handler.get_raster_bounds(dem_file)
    load_dotenv()
    MAPBOX_TOKEN = os.getenv("MAPBOX_TOKEN")
    MAPBOX_STYLE_URL = os.getenv("MAPBOX_STYLE_URL")
    m = folium.Map(
        [c_lat, c_lon],
        tiles=None,
        zoom_start=12,
        scrollWheelZoom=False,
    )
    folium.TileLayer(
        location=[c_lat, c_lon],
        tiles=MAPBOX_STYLE_URL,
        API_key=MAPBOX_TOKEN,
        attr="Christian Hein",
        name="Settings",
    ).add_to(m)

    min_ele, max_ele = 10000, 0
    for i in mountains:
        if i.location.elevation > max_ele:
            max_ele = i.location.elevation
        if i.location.elevation < min_ele:
            min_ele = i.location.elevation

    ###########################################################################
    ###########################################################################
    # All mountains in dataset

    if mountains:
        mountains_fg = folium.FeatureGroup(name="All Mountains", show=False)
        m.add_child(mountains_fg)
        [(folium.Marker(
            location=(i.location.latitude, i.location.longitude),
            popup="%s\n%im" % (
                str(i.name),
                i.location.elevation,
            ),
            icon=folium.DivIcon(html=get_glyph(
                f"am-{i.name}-{int(i.location.elevation)}", "#755239",
                i.location.elevation, min_ele, max_ele)),
            zIndexOffset=1,
        ).add_to(mountains_fg)) for i in mountains]

    ###########################################################################
    ###########################################################################
    # Mountains in sight

    if mountains_in_sight:
        mountains_in_sight_fg = folium.FeatureGroup(name="Visible Mountains",
                                                    show=True)
        m.add_child(mountains_in_sight_fg)

        [(folium.Marker(
            location=(i.location.latitude, i.location.longitude),
            popup="%s\n%im" % (
                str(i.name),
                i.location.elevation,
            ),
            icon=folium.DivIcon(html=get_glyph(
                f"vm-{i.name}-{int(i.location.elevation)}", "#426877",
                i.location.elevation, min_ele, max_ele)),
            zIndexOffset=10,
        ).add_to(mountains_in_sight_fg)) for i in mountains_in_sight]

    ###########################################################################
    ###########################################################################
    # Other images in dataset

    if images:
        images_fg = folium.FeatureGroup(name="Visible Images", show=True)
        m.add_child(images_fg)
        for im in images:
            encoded = base64.b64encode(open(im.thumbnail_path, "rb").read())

            html = f'''
            <!doctype html>
            <html>
                <head>
                    <style>
                        .redirect-button {{
                            color: #fff;
                            cursor: pointer;
                            background-color: #6c757d;
                            border-color: #6c757d;
                            display: inline-block;
                            font-weight: 400;
                            line-height: 1.5;
                            text-align: center;
                            text-decoration: none;
                            vertical-align: middle;
                            padding: .375rem .75rem;
                            border-radius: .25rem;
                            transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
                        }}

                        .redirect-button:hover {{
                            color: #fff;
                            background-color: #5c636a;
                            border-color: #545b62;
                        }}
                    </style>
                    <script type="text/javascript">
                        function redirect() {{
                            console.log("Redirecting to: ", "{im.name}");
                            window.parent.parent.postMessage("{im.name}", '*');
                        }}
                    </script>
                </head>
                <body>
                    <button class="redirect-button" onclick="redirect();">View image</button>
                    <img src="data:image/JPG;base64,{encoded.decode("UTF-8")}">
                </body>
            </html>
            '''
            iframe = folium.IFrame(html, width=450 + 20, height=150 + 20)
            popup = folium.Popup(iframe, max_width=470)

            folium.Marker(
                location=(im.location.latitude, im.location.longitude),
                popup=popup,
                icon=folium.Icon(color="orange", icon="camera"),
                zIndexOffset=12,
            ).add_to(images_fg)

    ###########################################################################
    ###########################################################################
    # Current viewpoint

    encoded = base64.b64encode(open(camera_pano_path, "rb").read())
    html = f'''
    <!doctype html>
    <html>
        <img src="data:image/JPG;base64,{encoded.decode("UTF-8")}">
    </html>
    '''
    iframe = folium.IFrame(html, width=450 + 20, height=150 + 20)
    popup = folium.Popup(iframe, max_width=450)
    folium.Marker(
        location=[c_lat, c_lon],
        popup=popup,
        icon=folium.Icon(color="green", icon="camera"),
        zIndexOffset=13,
    ).add_to(m)

    ###########################################################################
    ###########################################################################
    # Visible coordinates

    if locs:
        locs_fg = folium.FeatureGroup(name="Retrieved Coordinates", show=True)
        m.add_child(locs_fg)
        for i in locs:
            loc = converter.convert(*i)
            folium.Circle(
                location=(loc.latitude, loc.longitude),
                color="#0a6496",
                fill=True,
                fill_color="#0a6496",
                fill_opacity=1,
                radius=15,
            ).add_to(locs_fg)

    ###########################################################################
    ###########################################################################
    # Raster bounds

    raster_bounds = folium.FeatureGroup(name="Raster Bounds", show=False)
    m.add_child(raster_bounds)
    folium.PolyLine(locations=[ll, ul, ur, lr, ll],
                    color="#d63e29",
                    zIndexOffset=15).add_to(raster_bounds)

    ###########################################################################
    ###########################################################################
    # Legend

    template = """
    {% macro html(this, kwargs) %}

    <!doctype html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    <div id='maplegend' class='maplegend'
        style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8);
        border-radius:6px; padding: 10px 10px 1px; font-size:16px; font-weight:500; right: 20px; bottom: 24px;'>
        <div class='legend-scale'>
            <ul class='legend-labels'>
                <li><span style='background:#71b025;opacity:1.0;'></span>Current Viewpoint</li>
                <li><span style='background:#f69730;opacity:1.0;'></span>Images in dataset</li>
                <li><span style='background:#755239;opacity:1.0;'></span>All mountains in dataset</li>
                <li><span style='background:#426877;opacity:1.0;'></span>Mountains in sight</li>
                <li><span style='background:#d63e29;opacity:1.0;'></span>DEM bounding box</li>
            </ul>
        </div>
    </div>
    </body>
    </html>

    <style type='text/css'>
    .maplegend .legend-title {
        text-align: left;
        margin-bottom: 5px;
        font-weight: bold;
        font-size: 90%;
        }
    .maplegend .legend-scale ul {
        margin: 0;
        margin-bottom: 5px;
        padding: 0;
        float: left;
        list-style: none;
        }
    .maplegend .legend-scale ul li {
        font-size: 80%;
        list-style: none;
        margin-left: 0;
        line-height: 18px;
        margin-bottom: 2px;
        }
    .maplegend ul.legend-labels li span {
        display: block;
        float: left;
        height: 16px;
        width: 30px;
        margin-right: 5px;
        margin-left: 0;
        border: 1px solid #999;
        }
    .maplegend .legend-source {
        font-size: 80%;
        color: #777;
        clear: both;
        }
    .maplegend a {
        color: #777;
        }
    </style>
    {% endmacro %}"""

    macro = MacroElement()
    macro._template = Template(template)

    ###########################################################################
    ###########################################################################
    # Add to map
    folium.LayerControl().add_to(m)
    m.get_root().add_child(macro)
    # m.add_child(Fullscreen(position='topleft'))

    m.save(filename)
コード例 #13
0
ファイル: renderer.py プロジェクト: chrhein/dem-to-depth
def mountain_lookup(img_data, gpx_file, plot=False):
    p_i(f"Beginning mountain lookup for {img_data.filename}")

    viewshed = f'{img_data.folder}/viewshed.tif'
    ds_viewshed = rasterio.open(viewshed)
    if not ds_viewshed:
        return False

    render_settings_path = "render_settings.json"
    with open(render_settings_path) as json_file:
        data = load(json_file)
        dem_file = data["dem_path"]
        json_file.close()

    cropped_dem, coordinates, _, _ = pickle.load(
        open(f"{img_data.folder}/vs.pkl", "rb"))

    ds_raster = rasterio.open(cropped_dem)
    crs = int(ds_raster.crs.to_authority()[1])
    lat, lon = coordinates[0], coordinates[1]

    converter = LatLngToCrs(crs)
    camera_height = convert_coordinates(ds_raster, converter, lat, lon, True)
    camera_location = Location(lat, lon, camera_height)

    viewshed = f'{img_data.folder}/viewshed.tif'
    ds_viewshed = rasterio.open(viewshed)
    """ visible_hikes = {}
    for hike in get_hikes():
        waypoints_in_sight = find_visible_items_in_ds(
            ds_viewshed, hike.waypoints
        )
        waypoints_3d = get_3d_location(
            camera_location,
            waypoints_in_sight,
        )
        visible_hikes[hike.name] = waypoints_3d """

    fov = [img_data.fov_l, img_data.fov_r]

    images = read_image_locations(img_data.filename, "src/static/images",
                                  ds_raster, converter)
    images_in_sight = find_visible_items_in_ds(ds_viewshed, images)
    images_3d = get_3d_location(camera_location, images_in_sight, fov)

    mountains = read_mountain_gpx(gpx_file, converter)
    mountains_in_sight = find_visible_items_in_ds(ds_viewshed, mountains)
    mountains_3d = get_3d_location(camera_location, mountains_in_sight, fov)

    if plot:
        plotly_path = f"{img_data.folder}/{img_data.filename}-3d.json"
        if not os.path.exists(plotly_path):
            plot_3d(ds_raster, plotly_path)

        plot_filename = f"{img_data.folder}/{img_data.filename}-{gpx_file.split('/')[-1].split('.')[0]}.html"
        plot_to_map(
            img_data.thumbnail_path,
            mountains_3d,
            coordinates,
            plot_filename,
            dem_file,
            CrsToLatLng(crs),
            mountains=mountains,
            images=images,
        )

    return mountains_3d, images_3d, {}