(im_ms, cloud_mask, im_labels, shoreline,image_epsg, georef,
                   settings, date, satname)
return skip_image
Shows the detected shoreline to the user for visual quality control. 
    The user can accept/reject the detected shorelines  by using keep/skip
    buttons.

    KV WRL 2018

    Arguments:
    -----------
    im_ms: np.array
        RGB + downsampled NIR and SWIR
    cloud_mask: np.array
        2D cloud mask with True where cloud pixels are
    im_labels: np.array
        3D image containing a boolean image for each class in the order (sand, swash, water)
    shoreline: np.array
        array of points with the X and Y coordinates of the shoreline
    image_epsg: int
        spatial reference system of the image from which the contours were extracted
    georef: np.array
        vector of 6 elements [Xtr, Xscale, Xshear, Ytr, Yshear, Yscale]
    date: string
        date at which the image was taken
    satname: string
        indicates the satname (L5,L7,L8 or S2)
    settings: dict with the following keys
        'inputs': dict
            input parameters (sitename, filepath, polygon, dates, sat_list)
        'output_epsg': int
            output spatial reference system as EPSG code
        'check_detection': bool
            if True, lets user manually accept/reject the mapped shorelines
        'save_figure': bool
            if True, saves a -jpg file for each mapped shoreline

    Returns:
    -----------
    skip_image: boolean
        True if the user wants to skip the image, False otherwise
Shows the detected shoreline to the user for visual quality control. 
    The user can accept/reject the detected shorelines  by using keep/skip
    buttons.
Shows the detected shoreline to the user for visual quality control . The user can accept / reject the detected shorelines by using keep / skip buttons .
def show_detection(im_ms, cloud_mask, im_labels, shoreline,image_epsg, georef,
                   settings, date, satname):
    """
    Shows the detected shoreline to the user for visual quality control. 
    The user can accept/reject the detected shorelines  by using keep/skip
    buttons.

    KV WRL 2018

    Arguments:
    -----------
    im_ms: np.array
        RGB + downsampled NIR and SWIR
    cloud_mask: np.array
        2D cloud mask with True where cloud pixels are
    im_labels: np.array
        3D image containing a boolean image for each class in the order (sand, swash, water)
    shoreline: np.array
        array of points with the X and Y coordinates of the shoreline
    image_epsg: int
        spatial reference system of the image from which the contours were extracted
    georef: np.array
        vector of 6 elements [Xtr, Xscale, Xshear, Ytr, Yshear, Yscale]
    date: string
        date at which the image was taken
    satname: string
        indicates the satname (L5,L7,L8 or S2)
    settings: dict with the following keys
        'inputs': dict
            input parameters (sitename, filepath, polygon, dates, sat_list)
        'output_epsg': int
            output spatial reference system as EPSG code
        'check_detection': bool
            if True, lets user manually accept/reject the mapped shorelines
        'save_figure': bool
            if True, saves a -jpg file for each mapped shoreline

    Returns:
    -----------
    skip_image: boolean
        True if the user wants to skip the image, False otherwise

    """

    sitename = settings['inputs']['sitename']
    filepath_data = settings['inputs']['filepath']
    # subfolder where the .jpg file is stored if the user accepts the shoreline detection
    filepath = os.path.join(filepath_data, sitename, 'jpg_files', 'detection')

    im_RGB = SDS_preprocess.rescale_image_intensity(im_ms[:,:,[2,1,0]], cloud_mask, 99.9)

    # compute classified image
    im_class = np.copy(im_RGB)
    cmap = cm.get_cmap('tab20c')
    colorpalette = cmap(np.arange(0,13,1))
    colours = np.zeros((3,4))
    colours[0,:] = colorpalette[5]
    colours[1,:] = np.array([204/255,1,1,1])
    colours[2,:] = np.array([0,91/255,1,1])
    for k in range(0,im_labels.shape[2]):
        im_class[im_labels[:,:,k],0] = colours[k,0]
        im_class[im_labels[:,:,k],1] = colours[k,1]
        im_class[im_labels[:,:,k],2] = colours[k,2]

    # compute MNDWI grayscale image
    im_mwi = SDS_tools.nd_index(im_ms[:,:,4], im_ms[:,:,1], cloud_mask)

    # transform world coordinates of shoreline into pixel coordinates
    # use try/except in case there are no coordinates to be transformed (shoreline = [])
    try:
        sl_pix = SDS_tools.convert_world2pix(SDS_tools.convert_epsg(shoreline,
                                                                    settings['output_epsg'],
                                                                    image_epsg)[:,[0,1]], georef)
    except:
        # if try fails, just add nan into the shoreline vector so the next parts can still run
        sl_pix = np.array([[np.nan, np.nan],[np.nan, np.nan]])

    if plt.get_fignums():
            # get open figure if it exists
            fig = plt.gcf()
            ax1 = fig.axes[0]
            ax2 = fig.axes[1]
            ax3 = fig.axes[2]
    else:
        # else create a new figure
        fig = plt.figure()
        fig.set_size_inches([18, 9])
        mng = plt.get_current_fig_manager()
        mng.window.showMaximized()

        # according to the image shape, decide whether it is better to have the images
        # in vertical subplots or horizontal subplots
        if im_RGB.shape[1] > 2.5*im_RGB.shape[0]:
            # vertical subplots
            gs = gridspec.GridSpec(3, 1)
            gs.update(bottom=0.03, top=0.97, left=0.03, right=0.97)
            ax1 = fig.add_subplot(gs[0,0])
            ax2 = fig.add_subplot(gs[1,0], sharex=ax1, sharey=ax1)
            ax3 = fig.add_subplot(gs[2,0], sharex=ax1, sharey=ax1)
        else:
            # horizontal subplots
            gs = gridspec.GridSpec(1, 3)
            gs.update(bottom=0.05, top=0.95, left=0.05, right=0.95)
            ax1 = fig.add_subplot(gs[0,0])
            ax2 = fig.add_subplot(gs[0,1], sharex=ax1, sharey=ax1)
            ax3 = fig.add_subplot(gs[0,2], sharex=ax1, sharey=ax1)

    # change the color of nans to either black (0.0) or white (1.0) or somewhere in between
    nan_color = 1.0
    im_RGB = np.where(np.isnan(im_RGB), nan_color, im_RGB)
    im_class = np.where(np.isnan(im_class), 1.0, im_class)

    # create image 1 (RGB)
    ax1.imshow(im_RGB)
    ax1.plot(sl_pix[:,0], sl_pix[:,1], 'k.', markersize=3)
    ax1.axis('off')
    ax1.set_title(sitename, fontweight='bold', fontsize=16)

    # create image 2 (classification)
    ax2.imshow(im_class)
    ax2.plot(sl_pix[:,0], sl_pix[:,1], 'k.', markersize=3)
    ax2.axis('off')
    orange_patch = mpatches.Patch(color=colours[0,:], label='sand')
    white_patch = mpatches.Patch(color=colours[1,:], label='whitewater')
    blue_patch = mpatches.Patch(color=colours[2,:], label='water')
    black_line = mlines.Line2D([],[],color='k',linestyle='-', label='shoreline')
    ax2.legend(handles=[orange_patch,white_patch,blue_patch, black_line],
               bbox_to_anchor=(1, 0.5), fontsize=10)
    ax2.set_title(date, fontweight='bold', fontsize=16)

    # create image 3 (MNDWI)
    ax3.imshow(im_mwi, cmap='bwr')
    ax3.plot(sl_pix[:,0], sl_pix[:,1], 'k.', markersize=3)
    ax3.axis('off')
    ax3.set_title(satname, fontweight='bold', fontsize=16)

    # additional options
    #    ax1.set_anchor('W')
    #    ax2.set_anchor('W')
    #    cb = plt.colorbar()
    #    cb.ax.tick_params(labelsize=10)
    #    cb.set_label('MNDWI values')
    #    ax3.set_anchor('W')

    # if check_detection is True, let user manually accept/reject the images
    skip_image = False
    if settings['check_detection']:

        # set a key event to accept/reject the detections (see https://stackoverflow.com/a/15033071)
        # this variable needs to be immuatable so we can access it after the keypress event
        key_event = {}
        def press(event):
            # store what key was pressed in the dictionary
            key_event['pressed'] = event.key
        # let the user press a key, right arrow to keep the image, left arrow to skip it
        # to break the loop the user can press 'escape'
        while True:
            btn_keep = plt.text(1.1, 0.9, 'keep ⇨', size=12, ha="right", va="top",
                                transform=ax1.transAxes,
                                bbox=dict(boxstyle="square", ec='k',fc='w'))
            btn_skip = plt.text(-0.1, 0.9, '⇦ skip', size=12, ha="left", va="top",
                                transform=ax1.transAxes,
                                bbox=dict(boxstyle="square", ec='k',fc='w'))
            btn_esc = plt.text(0.5, 0, '<esc> to quit', size=12, ha="center", va="top",
                                transform=ax1.transAxes,
                                bbox=dict(boxstyle="square", ec='k',fc='w'))
            plt.draw()
            fig.canvas.mpl_connect('key_press_event', press)
            plt.waitforbuttonpress()
            # after button is pressed, remove the buttons
            btn_skip.remove()
            btn_keep.remove()
            btn_esc.remove()

            # keep/skip image according to the pressed key, 'escape' to break the loop
            if key_event.get('pressed') == 'right':
                skip_image = False
                break
            elif key_event.get('pressed') == 'left':
                skip_image = True
                break
            elif key_event.get('pressed') == 'escape':
                plt.close()
                raise StopIteration('User cancelled checking shoreline detection')
            else:
                plt.waitforbuttonpress()

    # if save_figure is True, save a .jpg under /jpg_files/detection
    if settings['save_figure'] and not skip_image:
        fig.savefig(os.path.join(filepath, date + '_' + satname + '.jpg'), dpi=150)

    # don't close the figure window, but remove all axes and settings, ready for next plot
    for ax in fig.axes:
        ax.clear()

    return skip_image
def show_detection ( im_ms , cloud_mask , im_labels , shoreline , image_epsg , georef , settings , date , satname ) : sitename = settings [ 'inputs' ] [ 'sitename' ] filepath_data = settings [ 'inputs' ] [ 'filepath' ] # subfolder where the .jpg file is stored if the user accepts the shoreline detection filepath = os . path . join ( filepath_data , sitename , 'jpg_files' , 'detection' ) im_RGB = SDS_preprocess . rescale_image_intensity ( im_ms [ : , : , [ 2 , 1 , 0 ] ] , cloud_mask , 99.9 ) # compute classified image im_class = np . copy ( im_RGB ) cmap = cm . get_cmap ( 'tab20c' ) colorpalette = cmap ( np . arange ( 0 , 13 , 1 ) ) colours = np . zeros ( ( 3 , 4 ) ) colours [ 0 , : ] = colorpalette [ 5 ] colours [ 1 , : ] = np . array ( [ 204 / 255 , 1 , 1 , 1 ] ) colours [ 2 , : ] = np . array ( [ 0 , 91 / 255 , 1 , 1 ] ) for k in range ( 0 , im_labels . shape [ 2 ] ) : im_class [ im_labels [ : , : , k ] , 0 ] = colours [ k , 0 ] im_class [ im_labels [ : , : , k ] , 1 ] = colours [ k , 1 ] im_class [ im_labels [ : , : , k ] , 2 ] = colours [ k , 2 ] # compute MNDWI grayscale image im_mwi = SDS_tools . nd_index ( im_ms [ : , : , 4 ] , im_ms [ : , : , 1 ] , cloud_mask ) # transform world coordinates of shoreline into pixel coordinates # use try/except in case there are no coordinates to be transformed (shoreline = []) try : sl_pix = SDS_tools . convert_world2pix ( SDS_tools . convert_epsg ( shoreline , settings [ 'output_epsg' ] , image_epsg ) [ : , [ 0 , 1 ] ] , georef ) except : # if try fails, just add nan into the shoreline vector so the next parts can still run sl_pix = np . array ( [ [ np . nan , np . nan ] , [ np . nan , np . nan ] ] ) if plt . get_fignums ( ) : # get open figure if it exists fig = plt . gcf ( ) ax1 = fig . axes [ 0 ] ax2 = fig . axes [ 1 ] ax3 = fig . axes [ 2 ] else : # else create a new figure fig = plt . figure ( ) fig . set_size_inches ( [ 18 , 9 ] ) mng = plt . get_current_fig_manager ( ) mng . window . showMaximized ( ) # according to the image shape, decide whether it is better to have the images # in vertical subplots or horizontal subplots if im_RGB . shape [ 1 ] > 2.5 * im_RGB . shape [ 0 ] : # vertical subplots gs = gridspec . GridSpec ( 3 , 1 ) gs . update ( bottom = 0.03 , top = 0.97 , left = 0.03 , right = 0.97 ) ax1 = fig . add_subplot ( gs [ 0 , 0 ] ) ax2 = fig . add_subplot ( gs [ 1 , 0 ] , sharex = ax1 , sharey = ax1 ) ax3 = fig . add_subplot ( gs [ 2 , 0 ] , sharex = ax1 , sharey = ax1 ) else : # horizontal subplots gs = gridspec . GridSpec ( 1 , 3 ) gs . update ( bottom = 0.05 , top = 0.95 , left = 0.05 , right = 0.95 ) ax1 = fig . add_subplot ( gs [ 0 , 0 ] ) ax2 = fig . add_subplot ( gs [ 0 , 1 ] , sharex = ax1 , sharey = ax1 ) ax3 = fig . add_subplot ( gs [ 0 , 2 ] , sharex = ax1 , sharey = ax1 ) # change the color of nans to either black (0.0) or white (1.0) or somewhere in between nan_color = 1.0 im_RGB = np . where ( np . isnan ( im_RGB ) , nan_color , im_RGB ) im_class = np . where ( np . isnan ( im_class ) , 1.0 , im_class ) # create image 1 (RGB) ax1 . imshow ( im_RGB ) ax1 . plot ( sl_pix [ : , 0 ] , sl_pix [ : , 1 ] , 'k.' , markersize = 3 ) ax1 . axis ( 'off' ) ax1 . set_title ( sitename , fontweight = 'bold' , fontsize = 16 ) # create image 2 (classification) ax2 . imshow ( im_class ) ax2 . plot ( sl_pix [ : , 0 ] , sl_pix [ : , 1 ] , 'k.' , markersize = 3 ) ax2 . axis ( 'off' ) orange_patch = mpatches . Patch ( color = colours [ 0 , : ] , label = 'sand' ) white_patch = mpatches . Patch ( color = colours [ 1 , : ] , label = 'whitewater' ) blue_patch = mpatches . Patch ( color = colours [ 2 , : ] , label = 'water' ) black_line = mlines . Line2D ( [ ] , [ ] , color = 'k' , linestyle = '-' , label = 'shoreline' ) ax2 . legend ( handles = [ orange_patch , white_patch , blue_patch , black_line ] , bbox_to_anchor = ( 1 , 0.5 ) , fontsize = 10 ) ax2 . set_title ( date , fontweight = 'bold' , fontsize = 16 ) # create image 3 (MNDWI) ax3 . imshow ( im_mwi , cmap = 'bwr' ) ax3 . plot ( sl_pix [ : , 0 ] , sl_pix [ : , 1 ] , 'k.' , markersize = 3 ) ax3 . axis ( 'off' ) ax3 . set_title ( satname , fontweight = 'bold' , fontsize = 16 ) # additional options #    ax1.set_anchor('W') #    ax2.set_anchor('W') #    cb = plt.colorbar() #    cb.ax.tick_params(labelsize=10) #    cb.set_label('MNDWI values') #    ax3.set_anchor('W') # if check_detection is True, let user manually accept/reject the images skip_image = False if settings [ 'check_detection' ] : # set a key event to accept/reject the detections (see https://stackoverflow.com/a/15033071) # this variable needs to be immuatable so we can access it after the keypress event key_event = { } def press ( event ) : # store what key was pressed in the dictionary key_event [ 'pressed' ] = event . key # let the user press a key, right arrow to keep the image, left arrow to skip it # to break the loop the user can press 'escape' while True : btn_keep = plt . text ( 1.1 , 0.9 , 'keep ⇨',  s ze=1 2 ,  h =" r ight",  v =" t op", transform = ax1 . transAxes , bbox = dict ( boxstyle = "square" , ec = 'k' , fc = 'w' ) ) btn_skip = plt . text ( - 0.1 , 0.9 , '⇦ skip',  s ze=1 2 ,  h =" l eft",  v =" t op", transform = ax1 . transAxes , bbox = dict ( boxstyle = "square" , ec = 'k' , fc = 'w' ) ) btn_esc = plt . text ( 0.5 , 0 , '<esc> to quit' , size = 12 , ha = "center" , va = "top" , transform = ax1 . transAxes , bbox = dict ( boxstyle = "square" , ec = 'k' , fc = 'w' ) ) plt . draw ( ) fig . canvas . mpl_connect ( 'key_press_event' , press ) plt . waitforbuttonpress ( ) # after button is pressed, remove the buttons btn_skip . remove ( ) btn_keep . remove ( ) btn_esc . remove ( ) # keep/skip image according to the pressed key, 'escape' to break the loop if key_event . get ( 'pressed' ) == 'right' : skip_image = False break elif key_event . get ( 'pressed' ) == 'left' : skip_image = True break elif key_event . get ( 'pressed' ) == 'escape' : plt . close ( ) raise StopIteration ( 'User cancelled checking shoreline detection' ) else : plt . waitforbuttonpress ( ) # if save_figure is True, save a .jpg under /jpg_files/detection if settings [ 'save_figure' ] and not skip_image : fig . savefig ( os . path . join ( filepath , date + '_' + satname + '.jpg' ) , dpi = 150 ) # don't close the figure window, but remove all axes and settings, ready for next plot for ax in fig . axes : ax . clear ( ) return skip_image