def get_json(json_data_out, session_id, static_label, user_id, index): global bb_label_mapping, data ctx = dash.callback_context if not ctx.triggered: raise PreventUpdate else: prop_id = ctx.triggered[0]["prop_id"] if prop_id != "canvas.json_data_out": raise PreventUpdate print("static", static_label) props = parse_labels(json_data_out, bb_label_mapping, static_label) datetime = data.index[index] df = pd.DataFrame( props, columns=["end_x", "end_y", "start_x", "start_y", "__target"]) df["start_time"] = datetime df["end_time"] = datetime df["__creation_time"] = stuett.to_datetime("now", utc=True) file_id = datetime.strftime("%Y%m%d_%H%M%S") to_csv(df, session_id, file_id, user_id) raise PreventUpdate
def update_output(date, session_id, user_id): """ The callback is used to load a new image when the date has changed. Date change can be triggered by the date selector box or indirectly by the arrow buttons, which change the date selector box. Besides loading images, this callback loads the annotation from the current user session and the annotations from the folder. Arguments: date {[type]} -- [description] session_id {[type]} -- [description] Raises: PreventUpdate: [description] Returns: [type] -- [description] """ global data static_label = [] info_box = "No info" if date is not None: index = data.index.get_loc(date, method="nearest") if isinstance(index, slice): index = index.start try: key = data.iloc[index]["filename"] img = imio.imread(io.BytesIO(store[key])) except Exception as e: print(e) info_box = "Error loading the image" img = np.zeros(img_shape, dtype="uint8") img = img[::img_downsampling, ::img_downsampling, :] image_content = array_to_data_url(img) # load data from index start_and_image = ( '{"version":"2.4.3","objects":[{"type":"image","version":"2.4.3", "originX":"left","originY":"top","left":0,"top":0,"width":%d,"height":%d,"src":"%s"}' % (img.shape[1], img.shape[0], image_content)) # load local annotations if exist datetime = data.index[index] file_id = datetime.strftime("%Y%m%d_%H%M%S") try: df = read_csv(session_id, file_id, user_id) except Exception as e: print('Could not read annotation file', e) df = None # Load the annotations from the server try: global_df = stuett.read_csv_with_store(annotation_store, "annotations.csv") global_df = global_df[stuett.to_datetime(global_df["start_time"]) == datetime] df = pd.concat([global_df, df]) except Exception as e: print(e) # create the data that is passed to dash_canvas rectangles = [""] if df is not None: rects = [] for i, row in df.iterrows(): if row["__target"] in static_label_mapping: if row["__target"] not in static_label: static_label.append(row["__target"]) left = row["start_x"] top = row["start_y"] right = row["end_x"] bottom = row["end_y"] if left is None or pd.isnull(left): continue label = static_label_mapping[str(row["__target"])] if label not in bb_label_reverse_mapping: continue stroke = bb_label_reverse_mapping[label] rect = ( ',{"type":"rect","version":"2.4.3","originX":"left","transparentCorners":false,"originY":"top","left":%f,"top":%f,"right":%f,"bottom":%f,"width":0,"height":0,"fill":"transparent","stroke":"%s","strokeWidth":2}' % (left, top, right, bottom, stroke)) rects.append(rect) if rects: rectangles = rects end_objects = "]}" string = [start_and_image] string += rectangles string += [end_objects] json_data = "".join(string) return json_data, index, str(datetime), static_label raise PreventUpdate
def serve_layout(): session_id = str(uuid.uuid4()) layout = html.Div( [ html.Div([ html.Div( session_id, id="session-id", style={"display": "none"}), html.Div([], id="storage", style={"display": "none"}), html.H3("Permafrost Image Annotation"), html.Div([ html.Div( [ dcc.DatePickerSingle( id="my-date-picker-single", min_date_allowed=stuett.to_datetime( "2017-01-01"), max_date_allowed=stuett.to_datetime( "2017-12-31"), initial_visible_month=None, date="2017-01-01", display_format="Y-MM-DD", ) ], style={ "width": "50%", "display": "inline-block" }, ), html.Div( id="date_indicator", style={ "width": "50%", "display": "inline-block" }, ), html.Div( [ dcc.Input( id="userid_input", placeholder="Your ID", type="number", value="", persistence=True, ), ], style={ "width": "50%", "display": "inline-block" }, ), ]), html.Div( [ dash_canvas.DashCanvas( id="canvas", width=500, tool="select", lineWidth=2, # json_data_in=json_template, # filename=filename, hide_buttons=["pencil", "line"], ), ], style={"text-align": "center"}, ), ]), html.Div( [ dcc.Markdown("Class names for bounding boxes:"), dcc.Dropdown( id="bb_label_dropdown", options=[{ "label": bb_label_mapping[m], "value": m } for m in bb_label_mapping.keys()], value="#1f77b4", ), dcc.Markdown("Class names for per image Labels:"), dcc.Dropdown( id="static_label_dropdown", options=[{ "label": static_label_mapping[m], "value": m } for m in static_label_mapping.keys()], value=[], multi=True, ), dcc.Store(id="index", data=0), ], className="six columns", ), dcc.Markdown( """Annotate by selecting per picture labels or draw bounding boxes with the rectangle tool Note: Rotating bounding boxes will result in incorrect labels.""" ), ], style={"width": "50%"}, # Div className="row", ) return layout