def show_means_compared(name_frame, name_scene, id_exbl, N=1000):
    """
    Plots the visualisation of impact of the second stage of the algorithm on 
    spectra, Fig.9
    parameters:
        name_frame: name of the source image (inductive scenario)
        name_scene: name of the output image
        id_exbl: id of the reference spectrum
        N: no. vectors in the 2nd stage as int or percentage string e.g. '33p'
    """

    data_frame, anno_frame = load_ds(name_frame, normalise=False)
    data_scene, anno_scene = load_ds(name_scene, normalise=False)
    blood_exbl = load_exbl(id_exbl)

    blood_frame = np.mean(data_frame[anno_frame == 1], axis=0)
    blood_scene = np.mean(data_scene[anno_scene == 1], axis=0)

    assert len(blood_exbl) == len(blood_frame)
    assert len(blood_exbl) == len(blood_scene)

    markers = ['s', 'v', '<', '>', '1', '.', 'p']

    n_blood = np.count_nonzero(anno_scene == 1)
    N_v = decode_N(N, n_blood)

    wav = get_wavelengths()

    X_data = data_scene.reshape(-1, data_scene.shape[2]).copy()
    mf = TwoStageMatchedFilter()

    mf.fit(blood_exbl, X_data, N=N_v, N_supression=0)

    plt.rcParams.update({'font.size': 14})
    plt.plot(wav,
             blood_scene,
             label="Image mean",
             marker=markers[0],
             markevery=0.3)
    plt.plot(wav,
             blood_exbl,
             label="Library",
             marker=markers[1],
             markevery=0.3)
    plt.plot(wav,
             mf.mf_2.mu_t,
             label='Second stage',
             marker=markers[2],
             markevery=0.3)

    plt.ylabel("Reflectance")
    plt.xlabel("Wavelenghts")

    plt.legend()
    plt.tight_layout()
    plt.show()
    plt.close()
def show_pca(name='F(1)'):
    """
    plots PCA visualisation of data (projection on first PC)
    Fig.2
    
    Parameters:
    ---------------------
    name: image name
    """
    plt.rcParams.update({'font.size': 14})
    data, gt = load_ds(name, normalise=False)

    data = np.delete(data, 445, 0)
    gt = np.delete(gt, 445, 0)

    X, y, _ = data2xy(data, gt)

    pca = PCA(n_components=2)
    pca.fit(X)
    X_pca = pca.transform(X)

    plt.rcParams.update({'font.size': 12})
    where = y == 0
    plt.scatter(X_pca[where, 0],
                X_pca[where, 1],
                c='grey',
                label='background',
                marker='1',
                alpha=0.5)
    where = np.logical_and(np.logical_and(y != 1, y != 8), y != 0)
    plt.scatter(X_pca[where, 0],
                X_pca[where, 1],
                c='blue',
                alpha=0.5,
                label='blood-like substances',
                marker='.')
    where = y == 8
    plt.scatter(X_pca[where, 0],
                X_pca[where, 1],
                c='orange',
                label='uncertain blood',
                marker='o',
                alpha=0.5)
    where = y == 1
    plt.scatter(X_pca[where, 0],
                X_pca[where, 1],
                c='red',
                label='blood',
                marker='x')
    plt.legend()
    plt.xlabel('First principal component')
    plt.ylabel('Second principal component')
    plt.tight_layout(pad=0)
    plt.show()
    plt.close()
def show_days(absorbance=True):
    """
    plots blood spectra sorted by days (Fig.2)

    Parameters:
    ---------------------
    absorbance: transform reflectance into (pseudo)absorbance i.e. log(1/R)
    """
    wav = get_wavelengths()

    days = ["Day 1(~1h)", "Day 1(~5h)", "Day 2", "Day 7"]
    frames = ["F(1)", "F(1s)", "F(2)", "F(7)"]
    plt.rcParams.update({'font.size': 14})
    fig, ax = plt.subplots()
    markers = ['s', 'v', '<', '>', '1', '.', 'p']

    for i_d, d in enumerate(days):
        data, anno = load_ds(frames[i_d], normalise=False)
        s = np.mean(data[anno == 1], axis=0)
        if absorbance:
            s[s == 0] += 0.0001
            s = np.log10(1.0 / s)
        plt.plot(wav,
                 s,
                 label="{}".format(d),
                 marker=markers[i_d],
                 markevery=10)
    plt.legend()
    y0, y1 = ax.get_ylim()
    plt.xlim(400, 1000)
    if absorbance:
        plt.ylim(0.2, y1)

    plt.plot([542, 542], [0, y1],
             lw=0.5,
             linestyle='--',
             alpha=0.7,
             color='black')
    plt.annotate('542', xy=(542, y1), xytext=(525, y1), fontsize=10)
    plt.plot([577, 577], [0, y1],
             lw=0.5,
             linestyle='--',
             alpha=0.7,
             color='black')
    plt.annotate('577', xy=(577, y1), xytext=(560, y1), fontsize=10)

    if absorbance:
        plt.ylabel("Log(1/R)")
    else:
        plt.ylabel("Reflectance")
    plt.xlabel("Wavelenghts")

    plt.tight_layout()
    plt.show()
    plt.close()
def experiment(name_frame,name_scene,id_exbl,N=1000,N_supression=0):
    """
    Main detection experiment, applies the TSMF 
    in `transductive', `inductive' and `ideal' settings.
    
    parameters:
        name_frame: name of the source image (inductive scenario)
        name_scene: name of the output image
        id_exbl: id of the reference spectrum
        N: no. vectors in the 2nd stage as int or percentage string e.g. '33p'
        N_supression: no. supressed vectors (extension of the algorithm, unused)
    """    
    fname = "res_scenes/{}_{}_{}_{}_{}.npz".format(name_frame,name_scene,N,N_supression,'scene')
    if isfile(fname):
        print (fname, "exists")
        return False
    
    data_frame,anno_frame = load_ds(name_frame)
    data_scene,anno_scene = load_ds(name_scene)
    
    blood_exbl = load_exbl(id_exbl)

    blood_frame = np.mean(data_frame[anno_frame==1],axis=0)
    blood_scene = np.mean(data_scene[anno_scene==1],axis=0)
    
    assert len(blood_exbl)==len(blood_frame)    
    assert len(blood_exbl)==len(blood_scene)

    names = ['scene','frame','exbl']
    
    n_blood = np.count_nonzero(anno_scene==1)
    N_v = decode_N(N, n_blood)
    for i_blood,blood in enumerate([blood_scene,blood_frame,blood_exbl]):
        X_data = data_scene.reshape(-1,data_scene.shape[2]).copy()
        mf = TwoStageMatchedFilter()
        
        mf.fit(blood, X_data, N=N_v, N_supression=N_supression)
        pred_1 = mf.predict(X_data, stage='first')
        pred_2 = mf.predict(X_data, stage='second')
        fname = "res/{}_{}_{}_{}_{}.npz".format(name_frame,name_scene,N,N_supression,names[i_blood])
        np.savez_compressed(fname,pred_1=pred_1.reshape(anno_scene.shape),pred_2=pred_2.reshape(anno_scene.shape),anno=anno_scene)
    return True
def prepare_no_blood(name_scene='F(1)', id_exbl=24, index=0):
    """
    performs the experiment from discussion: 
    number of blood pixels
    data for Fig.10
    parameters:
        name_scene: name of the output image
        id_exbl: id of the reference spectrum
        index: iteration of the experiment
    """
    data_scene, anno_scene = load_ds(name_scene)

    blood_exbl = load_exbl(id_exbl)

    X_bg = data_scene[anno_scene != 1]
    X_blood_raw = data_scene[anno_scene == 1]

    N_blood = len(X_blood_raw)

    ratio_V = RATIOS_V
    ratio_N = RATIOS_N

    res = np.zeros((len(ratio_V), len(ratio_N)))

    indices = np.arange(len(X_blood_raw))
    np.random.shuffle(indices)

    iii = 0
    for i_v, ratio_vectors in enumerate(ratio_V):
        for i_n, t_N in enumerate(ratio_N):
            iii += 1
            print(iii, ratio_vectors, t_N)
            no_vectors = int(ratio_vectors * N_blood)
            N = int(t_N * no_vectors) if t_N <= 1 else int(t_N)

            X_blood = X_blood_raw[indices]
            X_blood = X_blood[:no_vectors]

            X = np.vstack((X_bg, X_blood))
            y = np.concatenate(
                (np.zeros(len(X_bg),
                          dtype=np.int32), np.ones(len(X_blood),
                                                   dtype=np.int32)))
            blood = blood_exbl

            mf = TwoStageMatchedFilter()
            mf.fit(blood, X, N=N, N_supression=0)
            pred_2 = mf.predict(X, stage='second')
            vauc2, _, _ = comp_pr(pred_2, y)
            res[i_v, i_n] = vauc2
    np.savez_compressed('res/exp_no_blood_{}_{}'.format(name_scene, index),
                        res=res)
def show_classes(name='F(1)', absorbance=False):
    """
    plots spectra of classes in the image (Fig.1)
    
    Parameters:
    ---------------------
    name: image name
    absorbance: transform reflectance into (pseudo)absorbance i.e. log(1/R)
    """
    data, anno = load_ds(name, normalise=False)
    wav = get_wavelengths()
    plt.rcParams.update({'font.size': 14})

    plt.rcParams.update({'font.size': 12})
    labels = [
        'blood', 'ketchup', 'artificial blood', 'beetroot juice',
        'poster paint', 'tomato concentrate', 'acrylic paint'
    ]
    markers = ['s', 'v', '<', '>', '1', '.', 'p']
    cmap = plt.get_cmap("Set1")
    colors = [cmap(i / 7) for i in range(8)]

    colors[-4] = cmap(1.0)
    for c_label in range(1, 8):
        if c_label in anno:
            al = 1.0 if c_label == 1 else 0.7
            pattern = data[anno == c_label]
            s = np.median(pattern, axis=0)
            if absorbance:
                s[s == 0] += 0.0001
                s = np.log10(1.0 / s)
            plt.plot(wav,
                     s,
                     label="{} ({})".format(labels[c_label - 1], c_label),
                     color=colors[c_label - 1],
                     alpha=al,
                     marker=markers[c_label - 1],
                     markevery=10)
    plt.legend()

    if absorbance:
        plt.ylabel("Log(1/R)")
    else:
        plt.ylabel("Reflectance")
    plt.xlabel("Wavelenghts")

    plt.tight_layout(pad=0)
    plt.show()

    plt.close()
Exemple #7
0
def classification_experiment(name='d01_frame_I300', binary=False):
    """
    Implementation of the experiment in Sec.6.2
    parameters:
        name: name of the HSI image
        binary: if True, the problem is treated as binary (blood/others) for acc 
            computation. If False, this is a multi-class classification experiment
    returns:
        trained classifier
    """
    data, gt = load_ds(name, remove_uncertain_blood=True)
    X, y = get_Xy(data, gt)

    X = X[y != 0]
    y = y[y != 0]

    X = scale(X)
    if binary:
        y[y != 1] = 2
    acc = []
    prec = []
    rec = []

    for i in range(10):
        print(i, binary)
        i_train, i_test = select_subset(y, size=0.05, random_state=i)
        svm = getSVM(X[i_train], y[i_train], random_state=i)
        pred = svm.predict(X[i_test])
        acc.append(accuracy_score(y[i_test], pred))
        y2 = y.copy()
        y2[y2 != 1] = 2
        pred[pred != 1] = 2
        prec.append(precision_score(y2[i_test], pred, pos_label=1))
        rec.append(recall_score(y2[i_test], pred, pos_label=1))

    print(name)
    print("acc: {:0.2f}({:0.2f})".format(
        np.mean(acc) * 100.0,
        np.std(acc) * 100.0))
    print("prec: {:0.2f}({:0.2f})".format(
        np.mean(prec) * 100.0,
        np.std(prec) * 100.0))
    print("rec: {:0.2f}({:0.2f})".format(
        np.mean(rec) * 100.0,
        np.std(rec) * 100.0))
def show_mixtures(absorbance=True):
    """
    plots differences of blood spectra on different backgrounds (Fig.2)
    
    Parameters:
    ---------------------
    absorbance: transform reflectance into (pseudo)absorbance i.e. log(1/R)
    """
    wav = get_wavelengths()
    data, gt = load_ds('E(1)', normalise=False)

    #lower range and material
    backgrounds = [[44, 'metal'], [74, 'plastic'], [147, 'wood'],
                   [192, 'blue'], [271, 'red(t-shirt)'], [332, 'mixed'],
                   [430, 'mixed(green)'], [516, 'red(sweater)']]

    plt.rcParams.update({'font.size': 14})
    where = gt != 1
    gt[where] = 0
    markers = ['s', 'v', '<', '>', '1', '.', 'p', 'x']
    for i_b, b in enumerate(backgrounds):
        gta = gt.copy()
        gta[b[0]:, :] = 0
        if i_b != 0:
            gta[:backgrounds[i_b - 1][0]:, :] = 0
        X = data[gta == 1, :]
        print(b, X.shape)
        s = np.median(X, axis=0)
        if absorbance:
            s[s == 0] += 0.0001
            s = np.log10(1.0 / s)
        plt.plot(wav,
                 s,
                 label="{}".format(b[1]),
                 marker=markers[i_b],
                 markevery=10)
    plt.legend()

    if absorbance:
        plt.ylabel("Log(1/R)")
    else:
        plt.ylabel("Reflectance")
    plt.xlabel("Wavelenghts")
    plt.show()
    plt.close()
def show_no_blood(name_scene):
    """
    Plots visusalisation of the impact of no. pixels of detection AUC
    Fig.10
    parameters:
        name_scene: name of the output image
    """
    _, anno_scene = load_ds(name_scene)
    N_blood = np.count_nonzero(anno_scene == 1)
    markers = ['s', 'v', '<', '>', '1', '.', 'p']
    ratio_V = np.array(RATIOS_V)
    no_vectors = ratio_V * N_blood
    #ratio_N=RATIOS_N
    res = []

    for i in range(1):
        name = 'res/exp_no_blood_{}_{}.npz'.format(name_scene, i)
        rr = np.load(name)['res']
        res.append(rr)
    std = np.std(res, axis=0)
    res = np.mean(res, axis=0)

    #print (res.shape,no_vectors.shape)
    #sys.exit()

    plt.rcParams.update({'font.size': 14})
    labels = ['5%', '10%', '25%', '50%', '75%', '100%', '1000']
    for ii, i_n in enumerate([2, 3, 6]):
        plt.plot(no_vectors,
                 res[:, i_n],
                 label="N={}".format(labels[i_n]),
                 marker=markers[ii],
                 markevery=2)
    plt.xlabel('No. target pixels in the image')
    plt.ylabel('AUC(PR)')
    plt.legend()
    plt.show()
def create_gt_images():
    for im in IMAGES:
        print(im['code'])
        data, anno = load_ds(im['name_scene'], normalise=False)
        save_gt(data, anno, im['code'])