Esempio n. 1
0
def generate_bg(img_name):
    # img_name = '../data/data_sep2019/EXP1/09192019 Graphene/6 graphene-1.tiff'

    image = Image.open(img_name)
    im_rgb = np.array(image).astype('float')
    im_gray = np.array(image.convert(
        'L', (0.2989, 0.5870, 0.1140, 0))).astype('float')
    imH, imW = im_gray.shape
    # im_hsv = color.rgb2hsv(im_rgb)
    # im_hsv[:,:,2] = im_hsv[:,:,2]/255.0
    bg_rgb = []
    [C, R] = np.meshgrid(np.arange(0, imW), np.arange(0, imH))
    Y = np.reshape(R, [-1]) / (imH - 1) - 0.5
    X = np.reshape(C, [-1]) / (imW - 1) - 0.5
    A = np.stack([
        np.ones([imH * imW]),
        X * X,
        Y * Y,
        X * Y,
        X,
        Y,
    ], axis=1)
    for c in range(3):
        brob_rlm_model = robustfit.RLM()
        brob_rlm_model.fit(A, np.reshape(im_rgb[:, :, c], [-1]))
        pred_map = np.reshape(brob_rlm_model.predict(A), [imH, imW])
        bg_rgb.append(pred_map)
    bg_rgb = np.stack(bg_rgb, axis=2).astype(np.uint8)
    bg_hsv = color.rgb2hsv(bg_rgb)
    # bg_hsv[:,:,2] = bg_hsv[:,:,2]/255.0

    # bg_rgb: [0, 255]. bg_hs [0, 1.0], v [0, 255]
    return bg_rgb, bg_hsv
Esempio n. 2
0
def perform_robustfit_multichannel(im_hsv, im_gray, im_thre=10, size_thre=10):
    # im_hsv = im_hsv.astype('float')
    # im_gray = im_gray.astype('float')
    im_ghs = np.concatenate([np.expand_dims(im_gray, 2), im_hsv[:, :, :2]],
                            axis=2)
    imH, imW, _ = im_ghs.shape
    [C, R] = np.meshgrid(np.arange(0, imW), np.arange(0, imH))
    Y = np.reshape(R, [-1]) / (imH - 1) - 0.5
    X = np.reshape(C, [-1]) / (imW - 1) - 0.5
    A = np.stack([
        np.ones([imH * imW]),
        X * X,
        Y * Y,
        X * Y,
        X,
        Y,
    ], axis=1)
    res_map = np.zeros([imH, imW])
    for c in range(3):
        im_c = im_ghs[:, :, c]
        brob_rlm_model = robustfit.RLM()
        brob_rlm_model.fit(A, np.reshape(im_c, [-1]))
        if c == 0:
            w = 1
            ref_s = brob_rlm_model.sigma
        else:
            w = ref_s / brob_rlm_model.sigma
        res_map = res_map + w * np.abs(
            np.reshape(brob_rlm_model.resid, [imH, imW]))
    outlier_map = res_map > im_thre
    outlier_map = outlier_map.astype(np.uint8)

    # connected component detection
    nCC, image_labelmap, _, flake_centroids = cv2.connectedComponentsWithStats(
        outlier_map)
    # flake_centroid: [m, 2] array, indicates row, column of the centroid
    flake_centroids = np.flip(flake_centroids, 1)
    flake_centroids = flake_centroids[1:].astype('int')

    _, flake_sizes = np.unique(image_labelmap, return_counts=True)
    # remove the background size
    flake_sizes = flake_sizes[1:]
    if size_thre > 0:
        # remove small connect component
        large_flakes = flake_sizes > size_thre
        large_flake_idxs = np.nonzero(large_flakes)[0]
        new_image_labels = np.zeros([imH, imW])
        cnt = 0
        for idx in large_flake_idxs:
            cnt += 1
            new_image_labels[image_labelmap == idx + 1] = cnt
        image_labelmap = new_image_labels
        num_flakes = large_flakes.sum()
        flake_centroids = flake_centroids[large_flake_idxs]
        flake_sizes = flake_sizes[large_flake_idxs]
    else:
        num_flakes = nCC - 1

    return res_map, image_labelmap, flake_centroids, flake_sizes, num_flakes
Esempio n. 3
0
def perform_robustfit(im_gray, im_thre=3, size_thre=0):
    # im_gray = im_gray.astype('float')
    imH, imW = im_gray.shape
    [C, R] = np.meshgrid(np.arange(0, imW), np.arange(0, imH))
    Y = np.reshape(R, [-1]) / (imH - 1) - 0.5
    X = np.reshape(C, [-1]) / (imW - 1) - 0.5
    A = np.stack([
        np.ones([imH * imW]),
        X * X,
        Y * Y,
        X * Y,
        X,
        Y,
    ], axis=1)
    # res_map = np.zeros([imH, imW])

    brob_rlm_model = robustfit.RLM()
    brob_rlm_model.fit(A, np.reshape(im_gray, [-1]))
    print(brob_rlm_model.sigma)
    res_map = np.abs(np.reshape(brob_rlm_model.resid, [imH, imW]))
    outlier_map = res_map > im_thre * brob_rlm_model.sigma
    outlier_map = outlier_map.astype(np.uint8)

    # connected component detection
    nCC, image_labelmap, _, flake_centroids = cv2.connectedComponentsWithStats(
        outlier_map)
    # flake_centroid: [m, 2] array, indicates row, column of the centroid
    flake_centroids = np.flip(flake_centroids, 1)
    flake_centroids = flake_centroids[1:].astype('int')

    _, flake_sizes = np.unique(image_labelmap, return_counts=True)
    # remove the background size
    flake_sizes = flake_sizes[1:]
    if size_thre > 0:
        # remove small connect component
        large_flakes = flake_sizes > size_thre
        large_flake_idxs = np.nonzero(large_flakes)[0]
        new_image_labels = np.zeros([imH, imW])
        cnt = 0
        for idx in large_flake_idxs:
            cnt += 1
            new_image_labels[image_labelmap == idx + 1] = cnt
        image_labelmap = new_image_labels
        num_flakes = large_flakes.sum()
        flake_centroids = flake_centroids[large_flake_idxs + 1]
        flake_sizes = flake_sizes[large_flake_idxs + 1]
    else:
        num_flakes = nCC - 1

    return res_map, image_labelmap, flake_centroids, flake_sizes, num_flakes
def process_one_image(img_name, save_name, fig_save_name, bg_name=None):
    print('process %s' % (img_name))

    image = Image.open(img_name)
    im_rgb = np.array(image).astype('float')
    im_gray = np.array(image.convert(
        'L', (0.2989, 0.5870, 0.1140, 0))).astype('float')
    imH, imW = im_gray.shape
    # to have same result as matlab
    im_hsv = color.rgb2hsv(im_rgb)
    im_hsv[:, :, 2] = im_hsv[:, :, 2] / 255.0

    if bg_name is not None:
        bg_image = Image.open(bg_name)
        bg_rgb = np.array(bg_image).astype('float')
        bg_gray = np.array(bg_image.convert(
            'L', (0.2989, 0.5870, 0.1140, 0))).astype('float')
        # to have same result as matlab
        bg_hsv = color.rgb2hsv(bg_rgb)
        bg_hsv[:, :, 2] = bg_hsv[:, :, 2] / 255.0
    else:
        # estimate bg image
        bg_rgb = []
        [C, R] = np.meshgrid(np.arange(0, imW), np.arange(0, imH))
        Y = np.reshape(R, [-1]) / (imH - 1) - 0.5
        X = np.reshape(C, [-1]) / (imW - 1) - 0.5
        A = np.stack([
            np.ones([imH * imW]),
            X * X,
            Y * Y,
            X * Y,
            X,
            Y,
        ],
                     axis=1)
        for c in range(3):
            brob_rlm_model = robustfit.RLM()
            brob_rlm_model.fit(A, np.reshape(im_rgb[:, :, c], [-1]))
            pred_map = np.reshape(brob_rlm_model.predict(A), [imH, imW])
            bg_rgb.append(pred_map)
        bg_rgb = np.stack(bg_rgb, axis=2).astype('float')
        bg_hsv = color.rgb2hsv(bg_rgb)
        bg_hsv[:, :, 2] = bg_hsv[:, :, 2] / 255.0
        bg_gray = color.rgb2gray(bg_rgb)

    res_map, image_labelmap, flake_centroids, flake_sizes, num_flakes = utils.perform_robustfit_multichannel_v2(
        im_hsv, im_gray, hyperparams['im_thre'], hyperparams['size_thre'])

    if num_flakes != len(flake_sizes):
        print(len(flake_sizes), num_flakes, img_name)
        return

    # get contrast color features
    contrast_gray = im_gray - bg_gray
    contrast_hsv = im_hsv - bg_hsv
    contrast_rgb = im_rgb - bg_rgb

    flakes = []

    kernel = np.ones((5, 5), np.uint8)

    im_tosave = im_rgb.astype(np.uint8)

    # get features for each flake
    for i in range(num_flakes):
        f_mask_r, f_mask_c = np.nonzero(image_labelmap == i + 1)
        f_mask_r_min = min(f_mask_r)
        f_mask_r_max = max(f_mask_r)
        f_mask_height = f_mask_r_max - f_mask_r_min
        f_mask_c_min = min(f_mask_c)
        f_mask_c_max = max(f_mask_c)
        f_mask_width = f_mask_c_max - f_mask_c_min
        flake_exact_bbox = [
            f_mask_r_min, f_mask_r_max + 1, f_mask_c_min, f_mask_c_max + 1
        ]
        flake_large_bbox = [
            max(0, f_mask_r_min - int(0.1 * f_mask_height)),
            min(imH, f_mask_r_max + int(0.1 * f_mask_height)),
            max(0, f_mask_c_min - int(0.1 * f_mask_width)),
            min(imW, f_mask_c_max + int(0.1 * f_mask_width))
        ]

        bwmap = (image_labelmap == i + 1).astype(np.uint8)
        _, flake_contours, _ = cv2.findContours(bwmap, cv2.RETR_EXTERNAL,
                                                cv2.CHAIN_APPROX_NONE)
        im_tosave = cv2.drawContours(im_tosave, flake_contours[0], -1,
                                     (255, 0, 0), 2)

        flake_contours = np.squeeze(flake_contours[0], 1)
        # row, column
        flake_contours = np.flip(flake_contours, 1)

        # compute convex hull of the contours
        flake_convexhull = cv2.convexHull(flake_contours)

        # shape fea
        flake_shape_len_area_ratio = flake_contours.shape[0] / (bwmap.sum() +
                                                                0.0)
        contours_center_dis = cdist(np.expand_dims(flake_centroids[i], 0),
                                    flake_contours)
        flake_shape_contour_hist = np.histogram(contours_center_dis,
                                                bins=15)[0]
        flake_shape_contour_hist = flake_shape_contour_hist / flake_shape_contour_hist.sum(
        )
        flake_shape_fracdim = utils.fractal_dimension(bwmap)

        inner_bwmap = cv2.erode(bwmap, kernel, iterations=1)

        # color fea
        flake_color_fea = [im_gray[bwmap>0].mean(),
                         im_hsv[bwmap>0, 2].mean()] + \
                         [im_gray[bwmap>0].mean(), im_gray[bwmap>0].std()] + \
                         list(im_hsv[bwmap>0].mean(0)) + list(im_hsv[bwmap>0].std(0)) + \
                         list(im_rgb[bwmap>0].mean(0)) + list(im_rgb[bwmap>0].std(0))
        # flake_color_entropy = entropy(im_gray[bwmap>0].astype('uint8'), disk(5))
        flake_color_entropy = cv2.calcHist(
            [im_gray[bwmap > 0].astype('uint8')], [0], None, [256], [0, 256])
        flake_color_entropy = entropy(flake_color_entropy, base=2)
        flake_inner_color_fea = [0] * 16
        flake_inner_color_entropy = 0
        flake_inner_contrast_color_fea = [0] * 16
        if inner_bwmap.sum() > 0:
            flake_inner_color_fea = [im_gray[inner_bwmap>0].mean(),
                         im_hsv[inner_bwmap>0, 2].mean()] + \
                         [im_gray[inner_bwmap>0].mean(), im_gray[inner_bwmap>0].std()] + \
                         list(im_hsv[inner_bwmap>0].mean(0)) + list(im_hsv[inner_bwmap>0].std(0)) + \
                         list(im_rgb[inner_bwmap>0].mean(0)) + list(im_rgb[inner_bwmap>0].std(0))

            # flake_inner_color_entropy = entropy(im_gray[inner_bwmap>0].astype('uint8'), disk(5))
            flake_inner_color_entropy = cv2.calcHist(
                [im_gray[inner_bwmap > 0].astype('uint8')], [0], None, [256],
                [0, 256])
            flake_inner_color_entropy = entropy(flake_inner_color_entropy,
                                                base=2)

            flake_inner_contrast_color_entropy = cv2.calcHist(
                [contrast_gray[inner_bwmap > 0].astype('uint8')], [0], None,
                [256], [0, 256])
            flake_inner_contrast_color_entropy = entropy(
                flake_inner_contrast_color_entropy, base=2)
            flake_inner_contrast_color_fea = [contrast_gray[inner_bwmap>0].mean(),
                         contrast_hsv[inner_bwmap>0, 2].mean()] + \
                         [contrast_gray[inner_bwmap>0].std()] + \
                         list(contrast_hsv[inner_bwmap>0].mean(0)) + list(contrast_hsv[inner_bwmap>0].std(0)) + \
                         list(contrast_rgb[inner_bwmap>0].mean(0)) + list(contrast_rgb[inner_bwmap>0].std(0)) + list(flake_inner_contrast_color_entropy)
        # get contrast color features
        flake_contrast_color_entropy = cv2.calcHist(
            [contrast_gray[bwmap > 0].astype('uint8')], [0], None, [256],
            [0, 256])
        flake_contrast_color_entropy = entropy(flake_contrast_color_entropy,
                                               base=2)
        # gray, h, gray std, hsv mean, hsv std, rgb mean, rgb std, gray entropy
        flake_contrast_color_fea = [contrast_gray[bwmap>0].mean(),
                         contrast_hsv[bwmap>0, 2].mean()] + \
                         [contrast_gray[bwmap>0].std()] + \
                         list(contrast_hsv[bwmap>0].mean(0)) + list(contrast_hsv[bwmap>0].std(0)) + \
                         list(contrast_rgb[bwmap>0].mean(0)) + list(contrast_rgb[bwmap>0].std(0)) + [flake_contrast_color_entropy]

        flake_bg_color_fea = [bg_gray[bwmap>0].mean()] + \
                         [bg_gray[bwmap>0].std()] + \
                         list(bg_hsv[bwmap>0].mean(0)) + list(bg_hsv[bwmap>0].std(0)) + \
                         list(bg_rgb[bwmap>0].mean(0)) + list(bg_rgb[bwmap>0].std(0))

        flake_i = dict()
        flake_i['img_name'] = img_name
        flake_i['flake_id'] = i + 1
        flake_i['flake_size'] = flake_sizes[i]
        flake_i['flake_exact_bbox'] = flake_exact_bbox
        flake_i['flake_large_bbox'] = flake_large_bbox
        flake_i['flake_contour_loc'] = flake_contours.astype('int16')
        flake_i['flake_convexcontour_loc'] = flake_convexhull.astype('int16')
        flake_i['flake_center'] = flake_centroids[i]
        # flake_i['flake_img'] = im_rgb[flake_large_bbox[0]: flake_large_bbox[1], flake_large_bbox[2]:flake_large_bbox[3], :].astype(np.uint8)
        flake_i['flake_shape_fea'] = np.array([flake_shape_len_area_ratio] +
                                              list(flake_shape_contour_hist) +
                                              [flake_shape_fracdim])
        flake_i['flake_color_fea'] = np.array(flake_color_fea +
                                              [flake_color_entropy] +
                                              flake_inner_color_fea +
                                              [flake_inner_color_entropy])
        flake_i['flake_contrast_color_fea'] = np.array(
            flake_contrast_color_fea)
        flake_i['flake_innercontrast_color_fea'] = np.array(
            flake_inner_contrast_color_fea)
        flake_i['flake_bg_color_fea'] = np.array(flake_bg_color_fea)

        flake_i['flake_shape_fea_names'] = [
            'len_area_ratio'
        ] + ['contour_hist'] * 15 + ['fracdim']
        flake_i['flake_color_fea_names'] = [
            'gray_avg', 'v_avg', 'gray_avg', 'gray_std', 'h_avg', 's_avg',
            'v_avg', 'h_std', 's_std', 'v_std', 'r_avg', 'g_avg', 'b_avg',
            'r_std', 'g_std', 'b_std', 'gray_entropy', 'inner_gray_avg',
            'inner_v_avg', 'inner_gray_avg', 'inner_gray_std', 'inner_h_avg',
            'inner_s_avg', 'inner_v_avg', 'inner_h_std', 'inner_s_std',
            'inner_v_std', 'inner_r_avg', 'inner_g_avg', 'inner_b_avg',
            'inner_r_std', 'inner_g_std', 'inner_b_std', 'inner_gray_entropy'
        ]
        flake_i['flake_contrast_color_fea_names'] = [
            'contrast_gray_avg',
            'contrast_v_avg',
            'contrast_gray_avg',
            'contrast_gray_std',
            'contrast_h_avg',
            'contrast_s_avg',
            'contrast_v_avg',
            'contrast_h_std',
            'contrast_s_std',
            'contrast_v_std',
            'contrast_r_avg',
            'contrast_g_avg',
            'contrast_b_avg',
            'contrast_r_std',
            'contrast_g_std',
            'contrast_b_std',
            'contrast_gray_entropy',
        ]
        flake_i['flake_bg_color_fea_names'] = [
            'bg_gray_avg', 'bg_gray_std', 'bg_h_avg', 'bg_s_avg', 'bg_v_avg',
            'bg_h_std', 'bg_s_std', 'bg_v_std', 'bg_r_avg', 'bg_g_avg',
            'bg_b_avg', 'bg_r_std', 'bg_g_std', 'bg_b_std'
        ]

        # subsegment the flake
        if flake_i['flake_size'] > 100:
            n_clusters = hyperparams['n_clusters']
            flake_rgb = im_rgb[bwmap > 0]
            flake_gray = im_gray[bwmap > 0]
            flake_hsv = im_hsv[bwmap > 0]

            flake_contrast_rgb = im_rgb[bwmap > 0] - bg_rgb[bwmap > 0]
            flake_contrast_gray = im_gray[bwmap > 0] - bg_gray[bwmap > 0]
            flake_contrast_hsv = im_hsv[bwmap > 0] - bg_hsv[bwmap > 0]

            pixel_features = np.concatenate(
                [flake_rgb, flake_hsv,
                 np.expand_dims(flake_gray, 1)], 1)
            pixel_features = StandardScaler().fit_transform(pixel_features)
            cluster_rslt = KMeans(n_clusters=n_clusters,
                                  random_state=0,
                                  n_jobs=-1).fit(pixel_features)
            assignment = cluster_rslt.labels_
            # # get the overlayed image
            # n_pixel = pixel_features.shape[0]
            # overlay = np.zeros([n_pixel, 3], dtype=np.uint8)
            # overlay[assignment==0] = (255,0,0)
            # overlay[assignment==1] = (0,255,0)
            # overlay[assignment==2] = (0,0,255)
            # ori_bgr = im_bgr_tosave[bwmap>0]
            # overlay_bgr = cv2.addWeighted(np.expand_dims(ori_bgr,0), 0.75, np.expand_dims(overlay,0), 0.25, 0)
            # im_bgr_tosave[bwmap>0] = overlay_bgr[0,:,:]
            all_subsegment_features = []
            all_subsegment_keys = []
            for ci in range(n_clusters):
                subseg_gray = flake_gray[assignment == ci]
                subseg_contrast_gray = flake_contrast_gray[assignment == ci]
                # print(len(subseg_gray))
                subseg_hsv = flake_hsv[assignment == ci]
                subseg_rgb = flake_rgb[assignment == ci]
                subseg_contrast_hsv = flake_contrast_hsv[assignment == ci]
                subseg_contrast_rgb = flake_contrast_rgb[assignment == ci]

                sub_flake_color_entropy = cv2.calcHist(
                    [subseg_gray.astype('uint8')], [0], None, [256], [0, 256])
                sub_flake_color_entropy = entropy(sub_flake_color_entropy,
                                                  base=2)[0]
                sub_flake_contrast_color_entropy = cv2.calcHist(
                    [subseg_contrast_gray.astype('uint8')], [0], None, [256],
                    [0, 256])
                sub_flake_contrast_color_entropy = entropy(
                    sub_flake_contrast_color_entropy, base=2)[0]

                sub_flake_color_fea = [subseg_gray.mean(),
                         subseg_hsv[:, 2].mean()] + \
                         [subseg_hsv.std()] + \
                         list(subseg_hsv.mean(0)) + list(subseg_hsv.std(0)) + \
                         list(subseg_rgb.mean(0)) + list(subseg_rgb.std(0)) + [sub_flake_color_entropy] + \
                         [subseg_contrast_gray.mean(),
                         subseg_contrast_hsv[:, 2].mean()] + \
                         [subseg_contrast_gray.std()] + \
                         list(subseg_contrast_hsv.mean(0)) + list(subseg_contrast_hsv.std(0)) + \
                         list(subseg_contrast_rgb.mean(0)) + list(subseg_contrast_rgb.std(0)) + [sub_flake_contrast_color_entropy]
                all_subsegment_features.append(sub_flake_color_fea)
                all_subsegment_keys.append(sub_flake_color_fea[0])
            # sort based on gray values
            subsegment_features = []
            key_ids = np.argsort(all_subsegment_keys)
            for key_id in key_ids:
                subsegment_features.extend(all_subsegment_features[key_id])

            subsegment_features = np.array(subsegment_features)
            subsegment_features[np.isnan(
                subsegment_features
            )] = 0  # some flake can only be clustered into one cluster.
            if subsegment_features.shape[0] != 32 * n_clusters:
                print('wrong', save_name, i, subsegment_features.shape)
            assert subsegment_features.shape[0] == 32 * n_clusters
            flake_i['subsegment_features_%d' %
                    (n_clusters)] = subsegment_features
            flake_i['subsegment_assignment_%d' % (n_clusters)] = assignment
        flakes.append(flake_i)

    # save mat and images
    to_save = dict()
    to_save['bg_rgb'] = bg_rgb
    to_save['res_map'] = res_map
    to_save['image_labelmap'] = image_labelmap
    to_save['flakes'] = flakes

    pickle.dump(to_save, open(save_name + '.p', 'wb'))
    cv2.imwrite(fig_save_name + '.png', np.flip(im_tosave, 2))
def load_one_image(args_color, flake_path, fname, data_path, size_thre):
    tmp_flake = pickle.load(open(os.path.join(flake_path, fname), 'rb'))
    image_labelmap = tmp_flake['image_labelmap']
    tmp_flake = tmp_flake['flakes']

    flakes = []
    feats = []
    if len(tmp_flake) > 0:
        image = Image.open(os.path.join(data_path, fname[:-2] + 'tiff'))
        im_rgb = np.array(image).astype('float')
        im_hsv = color.rgb2hsv(im_rgb)
        im_hsv[:, :, 2] = im_hsv[:, :, 2] / 255.0
        im_gray = color.rgb2gray(im_rgb)
        imH, imW, _ = im_rgb.shape

        # background fitting
        if args_color == 'contrast' or args_color == 'both' or 'bg' in args_color:
            bg_rgb = []
            [C, R] = np.meshgrid(np.arange(0, imW), np.arange(0, imH))
            Y = np.reshape(R, [-1]) / (imH - 1) - 0.5
            X = np.reshape(C, [-1]) / (imW - 1) - 0.5
            A = np.stack([
                np.ones([imH * imW]),
                X * X,
                Y * Y,
                X * Y,
                X,
                Y,
            ],
                         axis=1)
            for c in range(3):
                brob_rlm_model = robustfit.RLM()
                brob_rlm_model.fit(A, np.reshape(im_rgb[:, :, c], [-1]))
                pred_map = np.reshape(brob_rlm_model.predict(A), [imH, imW])
                bg_rgb.append(pred_map)
            bg_rgb = np.stack(bg_rgb, axis=2).astype('float')
            bg_hsv = color.rgb2hsv(bg_rgb)
            bg_hsv[:, :, 2] = bg_hsv[:, :, 2] / 255.0
            bg_gray = color.rgb2gray(bg_rgb)

        for i in range(len(tmp_flake)):
            if tmp_flake[i]['flake_size'] > size_thre:
                # names.append(fname+'-'+str(tmp_flake[i]['flake_id']))
                f_mask_r_min, f_mask_r_max, f_mask_c_min, f_mask_c_max = tmp_flake[
                    i]['flake_exact_bbox']
                f_mask_height = f_mask_r_max - f_mask_r_min
                f_mask_width = f_mask_c_max - f_mask_c_min
                flake_large_bbox = [
                    max(0, f_mask_r_min - int(0.5 * f_mask_height)),
                    min(imH, f_mask_r_max + int(0.5 * f_mask_height)),
                    max(0, f_mask_c_min - int(0.5 * f_mask_width)),
                    min(imW, f_mask_c_max + int(0.5 * f_mask_width))
                ]
                tmp_flake[i]['flake_large_bbox'] = flake_large_bbox
                tmp_flake[i]['flake_img'] = im_rgb[
                    flake_large_bbox[0]:flake_large_bbox[1],
                    flake_large_bbox[2]:flake_large_bbox[3], :].astype(
                        np.uint8)

                flakes.append(tmp_flake[i])

                tmp_fea_ori = tmp_flake[i]['flake_color_fea']
                bwmap = (image_labelmap == i + 1).astype(np.uint8)

                if 'ori' in args_color:
                    tmp_color_fea = list(tmp_fea_ori)
                elif 'contrast' in args_color or 'both' in args_color:
                    # color fea
                    assert bwmap.sum() == tmp_flake[i]['flake_size']
                    contrast_gray = im_gray - bg_gray
                    contrast_hsv = im_hsv - bg_hsv
                    contrast_rgb = im_rgb - bg_rgb
                    flake_color_entropy = cv2.calcHist(
                        [contrast_gray[bwmap > 0].astype('uint8')], [0], None,
                        [256], [0, 256])
                    flake_color_entropy = entropy(flake_color_entropy, base=2)
                    # gray, h, gray std, hsv mean, hsv std, rgb mean, rgb std, gray entropy
                    tmp_fea_contrast = [contrast_gray[bwmap>0].mean(),
                                     contrast_hsv[bwmap>0, 2].mean()] + \
                                     [contrast_gray[bwmap>0].std()] + \
                                     list(contrast_hsv[bwmap>0].mean(0)) + list(contrast_hsv[bwmap>0].std(0)) + \
                                     list(contrast_rgb[bwmap>0].mean(0)) + list(contrast_rgb[bwmap>0].std(0)) + [flake_color_entropy]

                    if 'contrast' in args_color:
                        tmp_color_fea = list(tmp_fea_contrast)
                    elif 'both' in args_color:
                        tmp_color_fea = list(tmp_fea_ori) + list(
                            tmp_fea_contrast)
                else:
                    raise NotImplementedError

                if 'bg' in args_color:
                    tmp_bg_fea = [bg_gray[bwmap>0].mean()] + \
                         [bg_gray[bwmap>0].std()] + \
                         list(bg_hsv[bwmap>0].mean(0)) + list(bg_hsv[bwmap>0].std(0)) + \
                         list(bg_rgb[bwmap>0].mean(0)) + list(bg_rgb[bwmap>0].std(0))

                    tmp_color_fea = list(tmp_color_fea) + list(tmp_bg_fea)

                if 'shape' in args_color:
                    tmp_shape_fea = tmp_flake[i]['flake_shape_fea']
                    len_area_ratio = tmp_shape_fea[0]
                    fracdim = tmp_shape_fea[-1]
                    tmp_color_fea = list(tmp_color_fea) + [
                        len_area_ratio, fracdim
                    ]

                feats.append(tmp_color_fea)

    return flakes, feats
def process_one_image_step1(img_name, save_name, fig_save_name):
    image = Image.open(img_name)
    im_rgb = np.array(image).astype('float')
    im_gray = np.array(image.convert(
        'L', (0.2989, 0.5870, 0.1140, 0))).astype('float')
    imH, imW = im_gray.shape
    # im_hsv = np.array(image.convert('HSV')).astype('float')
    # to have same result as matlab
    im_hsv = color.rgb2hsv(im_rgb)
    im_hsv[:, :, 2] = im_hsv[:, :, 2] / 255.0
    im_ghs = np.concatenate([np.expand_dims(im_gray, 2), im_hsv[:, :, :2]],
                            axis=2)

    if os.path.exists(save_name + '.p'):
        rslt = pickle.load(open(save_name + '.p', 'rb'))
        bg_ghs = rslt['bg_ghs']
        bg_rgb = rslt['bg_rgb']
        # return bg_ghs, bg_rgb
        return bg_ghs, bg_rgb, im_ghs, im_rgb
    print('process %s' % (img_name))

    # res_map, image_labelmap, flake_centroids, flake_sizes, num_flakes = utils.perform_robustfit_multichannel(im_hsv, im_gray, hyperparams['im_thre'], hyperparams['size_thre'])
    all_res_map, all_image_labelmap, all_flake_centroids, all_flake_sizes, all_num_flakes, bg_ghs = utils.perform_robustfit_multichannel_v4(
        im_hsv, im_gray, hyperparams['ori_im_thre_pairs'],
        hyperparams['size_thre'])

    # if num_flakes != len(flake_sizes):
    #     print(len(flake_sizes), num_flakes, img_name)
    #     return

    # get bg
    bg_rgb = []
    [C, R] = np.meshgrid(np.arange(0, imW), np.arange(0, imH))
    Y = np.reshape(R, [-1]) / (imH - 1) - 0.5
    X = np.reshape(C, [-1]) / (imW - 1) - 0.5
    A = np.stack([
        np.ones([imH * imW]),
        X * X,
        Y * Y,
        X * Y,
        X,
        Y,
    ], axis=1)
    for c in range(3):
        brob_rlm_model = robustfit.RLM()
        brob_rlm_model.fit(A, np.reshape(im_rgb[:, :, c], [-1]))
        pred_map = np.reshape(brob_rlm_model.predict(A), [imH, imW])
        bg_rgb.append(pred_map)
    bg_rgb = np.stack(bg_rgb, axis=2).astype('float')
    bg_hsv = color.rgb2hsv(bg_rgb)
    bg_hsv[:, :, 2] = bg_hsv[:, :, 2] / 255.0
    bg_gray = color.rgb2gray(bg_rgb)
    # # get contrast color features
    # contrast_gray = im_gray - bg_gray
    # contrast_hsv = im_hsv - bg_hsv
    # contrast_rgb = im_rgb - bg_rgb

    # flakes = []

    # kernel = np.ones((5,5),np.uint8)

    cv2.imwrite(fig_save_name + '_ori_bg.png',
                np.flip(bg_rgb.astype(np.uint8), 2))

    all_im_tosave = []
    for pi, thre_pair in enumerate(hyperparams['ori_im_thre_pairs']):
        im_tosave = im_rgb.astype(np.uint8)

        # get features for each flake
        for i in range(all_num_flakes[pi]):
            bwmap = (all_image_labelmap[pi] == i + 1).astype(np.uint8)
            _, flake_contours, _ = cv2.findContours(bwmap, cv2.RETR_EXTERNAL,
                                                    cv2.CHAIN_APPROX_NONE)
            im_tosave = cv2.drawContours(im_tosave, flake_contours[0], -1,
                                         (255, 0, 0), 2)
        all_im_tosave.append(im_tosave)

        cv2.imwrite(
            fig_save_name + '_ori_thre-' + str(thre_pair[0]) + '-' +
            str(thre_pair[1]) + '.png', np.flip(im_tosave, 2))

    # save mat and images
    to_save = dict()
    to_save['bg_rgb'] = bg_rgb
    to_save['bg_ghs'] = bg_ghs
    to_save['all_res_map'] = all_res_map
    to_save['all_image_labelmap'] = all_image_labelmap
    to_save['all_im_tosave'] = all_im_tosave
    # to_save['flakes'] = flakes

    pickle.dump(to_save, open(save_name + '.p', 'wb'))

    return bg_ghs, bg_rgb, im_ghs, im_rgb
Esempio n. 7
0
def perform_robustfit_multichannel_v4(im_hsv,
                                      im_gray,
                                      thre_pairs,
                                      size_thre=10):
    # im_hsv = im_hsv.astype('float')
    # im_gray = im_gray.astype('float')
    im_ghs = np.concatenate([np.expand_dims(im_gray, 2), im_hsv[:, :, :2]],
                            axis=2)
    imH, imW, _ = im_ghs.shape
    [C, R] = np.meshgrid(np.arange(0, imW), np.arange(0, imH))
    Y = np.reshape(R, [-1]) / (imH - 1) - 0.5
    X = np.reshape(C, [-1]) / (imW - 1) - 0.5
    A = np.stack([
        np.ones([imH * imW]),
        X * X,
        Y * Y,
        X * Y,
        X,
        Y,
    ], axis=1)
    res_map = np.zeros([imH, imW])
    bg_ghs = []
    im_thres = []
    for c in range(3):
        im_c = im_ghs[:, :, c]
        brob_rlm_model = robustfit.RLM()
        brob_rlm_model.fit(A, np.reshape(im_c, [-1]))
        pred_map = np.reshape(brob_rlm_model.predict(A), [imH, imW])
        bg_ghs.append(pred_map)
        if c == 0:
            w = 1
            ref_s = brob_rlm_model.sigma
            im_thre = brob_rlm_model.sigma
            im_thres.append(im_thre)
        else:
            w = ref_s / brob_rlm_model.sigma
            im_thre = w * brob_rlm_model.sigma
            im_thres.append(im_thre)
        res_map = res_map + w * np.abs(
            np.reshape(brob_rlm_model.resid, [imH, imW]))
        # print(im_thre, brob_rlm_model.sigma)
    bg_ghs = np.stack(bg_ghs, axis=2).astype('float')

    all_res_map = []
    all_image_labelmap = []
    all_flake_centroids = []
    all_flake_sizes = []
    all_num_flakes = []
    for thre_pair in thre_pairs:
        im_thre = np.sum(im_thres) * thre_pair[0]
        # true_fg_map = res_map>im_thre
        bg_map = res_map <= im_thre
        # recompute threshold based on background regions
        # bg_sigma = np.std(res_map[bg_map])
        bg_sigma = get_sigma(res_map[bg_map])
        outlier_map = res_map > bg_sigma * thre_pair[1]
        outlier_map = outlier_map.astype(np.uint8)

        # connected component detection
        nCC, image_labelmap, _, flake_centroids = cv2.connectedComponentsWithStats(
            outlier_map)
        # flake_centroid: [m, 2] array, indicates row, column of the centroid
        flake_centroids = np.flip(flake_centroids, 1)
        flake_centroids = flake_centroids[1:].astype('int')

        _, flake_sizes = np.unique(image_labelmap, return_counts=True)
        # remove the background size
        flake_sizes = flake_sizes[1:]
        if size_thre > 0:
            # remove small connect component
            large_flakes = flake_sizes > size_thre
            large_flake_idxs = np.nonzero(large_flakes)[0]
            new_image_labels = np.zeros([imH, imW])
            cnt = 0
            for idx in large_flake_idxs:
                cnt += 1
                new_image_labels[image_labelmap == idx + 1] = cnt
            image_labelmap = new_image_labels
            num_flakes = large_flakes.sum()
            flake_centroids = flake_centroids[large_flake_idxs]
            flake_sizes = flake_sizes[large_flake_idxs]
        else:
            num_flakes = nCC - 1

        all_res_map.append(res_map)
        all_image_labelmap.append(image_labelmap)
        all_flake_centroids.append(flake_centroids)
        all_flake_sizes.append(flake_sizes)
        all_num_flakes.append(num_flakes)
        # print(num_flakes)
    return all_res_map, all_image_labelmap, all_flake_centroids, all_flake_sizes, all_num_flakes, bg_ghs
def load_one_image_v2(data_path,
                      result_path,
                      fname,
                      exp_name,
                      subexp_name,
                      all_labeled_flake_name_ids,
                      output_img_size=256):
    # fname = labeled_flake_name_ids.rsplit('-', 1)[0]
    # flake_id = int(labeled_flake_name_ids.rsplit('-', 1)[1])

    flake_info = pickle.load(
        open(os.path.join(result_path, exp_name, subexp_name, fname), 'rb'))
    img_name = fname.split('.')[0] + '.tiff'
    image = Image.open(os.path.join(data_path, exp_name, subexp_name,
                                    img_name))

    im_rgb = np.array(image).astype('float')
    im_hsv = color.rgb2hsv(im_rgb)
    im_hsv[:, :, 2] = im_hsv[:, :, 2] / 255.0
    im_gray = color.rgb2gray(im_rgb)
    imH, imW = im_gray.shape

    # get bg image
    bg_rgb = []
    [C, R] = np.meshgrid(np.arange(0, imW), np.arange(0, imH))
    Y = np.reshape(R, [-1]) / (imH - 1) - 0.5
    X = np.reshape(C, [-1]) / (imW - 1) - 0.5
    A = np.stack([
        np.ones([imH * imW]),
        X * X,
        Y * Y,
        X * Y,
        X,
        Y,
    ], axis=1)
    for c in range(3):
        brob_rlm_model = robustfit.RLM()
        brob_rlm_model.fit(A, np.reshape(im_rgb[:, :, c], [-1]))
        pred_map = np.reshape(brob_rlm_model.predict(A), [imH, imW])
        bg_rgb.append(pred_map)
    bg_rgb = np.stack(bg_rgb, axis=2).astype('float')
    bg_hsv = color.rgb2hsv(bg_rgb)
    bg_hsv[:, :, 2] = bg_hsv[:, :, 2] / 255.0
    bg_gray = color.rgb2gray(bg_rgb)

    # build a list of flakes
    image_labelmap = flake_info['image_labelmap']
    flakes = flake_info['flakes']

    # print(labeled_flake_name_ids, flake_id, len(flakes))

    flake = flakes[flake_id]

    flake_centroids = flake['flake_center'].astype('int')
    flake_large_bbox = [
        max(0, flake_centroids[0] - output_img_size // 2),
        min(imH, flake_centroids[0] + output_img_size // 2),
        max(0, flake_centroids[1] - output_img_size // 2),
        min(imW, flake_centroids[1] + output_img_size // 2)
    ]

    f_img = np.zeros([output_img_size, output_img_size, 3], dtype=np.uint8)
    r_min = output_img_size // 2 - (flake_centroids[0] - flake_large_bbox[0])
    r_max = r_min + (flake_large_bbox[1] - flake_large_bbox[0])
    c_min = output_img_size // 2 - (flake_centroids[1] - flake_large_bbox[2])
    c_max = c_min + (flake_large_bbox[3] - flake_large_bbox[2])
    # print(r_min, r_max, c_min, c_max)
    f_img[r_min:r_max,
          c_min:c_max, :] = im_rgb[flake_large_bbox[0]:flake_large_bbox[1],
                                   flake_large_bbox[2]:flake_large_bbox[3], :]
    f_img = f_img.astype(np.uint8)

    # get contour image
    im_tosave_withcontour = im_rgb.astype(np.uint8)
    contour_color = (255, 255, 255)
    contours = flakes[flake_id]['flake_contour_loc']
    contours = np.expand_dims(np.flip(contours), 1).astype(np.int32)
    im_tosave_withcontour = cv2.drawContours(im_tosave_withcontour, contours,
                                             -1, contour_color, 2)
    f_img_withcontour = np.zeros([output_img_size, output_img_size, 3],
                                 dtype=np.uint8)
    f_img_withcontour[r_min:r_max, c_min:c_max, :] = im_tosave_withcontour[
        flake_large_bbox[0]:flake_large_bbox[1],
        flake_large_bbox[2]:flake_large_bbox[3], :]
    # stick withcontour and without contour together
    black_strip = np.zeros(
        [output_img_size, int(output_img_size * 0.03), 3], dtype=np.int)
    f_img_withcontour = np.concatenate([f_img_withcontour, black_strip, f_img],
                                       1)

    # get bg image
    f_bg_img = np.zeros([output_img_size, output_img_size, 3], dtype=np.uint8)
    f_bg_img[r_min:r_max, c_min:c_max, :] = bg_rgb[
        flake_large_bbox[0]:flake_large_bbox[1],
        flake_large_bbox[2]:flake_large_bbox[3], :]
    f_bg_img = f_bg_img.astype(np.uint8)

    # get mask
    mask = (image_labelmap == flake['flake_id']).astype(np.uint8)
    mask[mask == 1] = 255
    f_mask = np.zeros([output_img_size, output_img_size], dtype=np.uint8)
    f_mask[r_min:r_max,
           c_min:c_max] = mask[flake_large_bbox[0]:flake_large_bbox[1],
                               flake_large_bbox[2]:flake_large_bbox[3]]
    f_contrast = np.zeros([output_img_size, output_img_size, 3],
                          dtype=np.uint8)
    f_contrast[r_min:r_max, c_min:c_max, 0] = np.abs(im_gray[flake_large_bbox[0]: flake_large_bbox[1], flake_large_bbox[2]:flake_large_bbox[3]] - \
                                                    bg_gray[flake_large_bbox[0]: flake_large_bbox[1], flake_large_bbox[2]:flake_large_bbox[3]])
    f_contrast[r_min:r_max, c_min:c_max, 1] = np.abs(im_hsv[flake_large_bbox[0]: flake_large_bbox[1], flake_large_bbox[2]:flake_large_bbox[3], 0] - \
                                                    bg_hsv[flake_large_bbox[0]: flake_large_bbox[1], flake_large_bbox[2]:flake_large_bbox[3], 0])
    f_contrast = f_contrast.astype(np.uint8)

    flake['flake_img'] = f_img
    flake['flake_mask'] = f_mask
    flake['flake_contrast'] = f_contrast
    flake['flake_img_withcontour'] = f_img_withcontour
    flake['bg_img'] = f_bg_img

    return flake
def process_one_img(ins_name,
                    img_dir,
                    rslt_dir,
                    ae_img_path,
                    ae_mask_path,
                    ae_contrast_path,
                    ae_bg_path,
                    output_img_size=256):
    ins_name = ins_name.split('.')[0]
    # load the detected flake and get features for the flake
    if not os.path.exists(os.path.join(rslt_dir, ins_name + '..p')):
        return
    flake_info = pickle.load(
        open(os.path.join(rslt_dir, ins_name + '..p'), 'rb'))
    image = Image.open(os.path.join(img_dir, ins_name + '.tiff'))
    # im_gray = np.array(image.convert('L', (0.2989, 0.5870, 0.1140, 0))).astype('float')
    # imH, imW = im_gray.shape
    # im_hsv = np.array(image.convert('HSV')).astype('float')
    # im_rgb = np.array(image).astype(np.uint8)

    im_rgb = np.array(image).astype('float')
    im_hsv = color.rgb2hsv(im_rgb)
    im_hsv[:, :, 2] = im_hsv[:, :, 2] / 255.0
    im_gray = color.rgb2gray(im_rgb)
    imH, imW = im_gray.shape

    # build a list of flakes
    num_flakes = len(flake_info['flakes'])
    image_labelmap = flake_info['image_labelmap']
    assert num_flakes == image_labelmap.max()
    flakes = flake_info['flakes']
    large_flake_idxs = []
    cnt = 0

    # get bg image
    bg_rgb = []
    [C, R] = np.meshgrid(np.arange(0, imW), np.arange(0, imH))
    Y = np.reshape(R, [-1]) / (imH - 1) - 0.5
    X = np.reshape(C, [-1]) / (imW - 1) - 0.5
    A = np.stack([
        np.ones([imH * imW]),
        X * X,
        Y * Y,
        X * Y,
        X,
        Y,
    ], axis=1)
    for c in range(3):
        brob_rlm_model = robustfit.RLM()
        brob_rlm_model.fit(A, np.reshape(im_rgb[:, :, c], [-1]))
        pred_map = np.reshape(brob_rlm_model.predict(A), [imH, imW])
        bg_rgb.append(pred_map)
    bg_rgb = np.stack(bg_rgb, axis=2).astype('float')
    bg_hsv = color.rgb2hsv(bg_rgb)
    bg_hsv[:, :, 2] = bg_hsv[:, :, 2] / 255.0
    bg_gray = color.rgb2gray(bg_rgb)

    for i in range(num_flakes):
        flake_size = flakes[i]['flake_size']
        flake_centroids = flakes[i]['flake_center'].astype('int')
        if flake_size > hyperparams['size_thre']:
            # if flake_size > hyperparams['size_thre'] and flake_centroids[0] - output_img_size/2 >=0 and flake_centroids[0] + output_img_size/2 < imH and flake_centroids[1] - output_img_size/2 >=0 and flake_centroids[1] + output_img_size/2 < imW:
            large_flake_idxs.append(i)
            flake_large_bbox = [
                max(0, flake_centroids[0] - output_img_size // 2),
                min(imH, flake_centroids[0] + output_img_size // 2),
                max(0, flake_centroids[1] - output_img_size // 2),
                min(imW, flake_centroids[1] + output_img_size // 2)
            ]

            f_img = np.zeros([output_img_size, output_img_size, 3],
                             dtype=np.uint8)
            r_min = output_img_size // 2 - (flake_centroids[0] -
                                            flake_large_bbox[0])
            r_max = r_min + (flake_large_bbox[1] - flake_large_bbox[0])
            c_min = output_img_size // 2 - (flake_centroids[1] -
                                            flake_large_bbox[2])
            c_max = c_min + (flake_large_bbox[3] - flake_large_bbox[2])
            # print(r_min, r_max, c_min, c_max)
            f_img[r_min:r_max, c_min:c_max, :] = im_rgb[
                flake_large_bbox[0]:flake_large_bbox[1],
                flake_large_bbox[2]:flake_large_bbox[3], :]
            f_img = f_img.astype(np.uint8)

            f_bg_img = np.zeros([output_img_size, output_img_size, 3],
                                dtype=np.uint8)
            f_bg_img[r_min:r_max, c_min:c_max, :] = bg_rgb[
                flake_large_bbox[0]:flake_large_bbox[1],
                flake_large_bbox[2]:flake_large_bbox[3], :]
            f_bg_img = f_bg_img.astype(np.uint8)

            # get mask
            mask = (image_labelmap == i + 1).astype(np.uint8)
            mask[mask == 1] = 255
            f_mask = np.zeros([output_img_size, output_img_size],
                              dtype=np.uint8)
            f_mask[r_min:r_max,
                   c_min:c_max] = mask[flake_large_bbox[0]:flake_large_bbox[1],
                                       flake_large_bbox[2]:flake_large_bbox[3]]
            f_contrast = np.zeros([output_img_size, output_img_size, 3],
                                  dtype=np.uint8)
            f_contrast[r_min:r_max, c_min:c_max, 0] = np.abs(im_gray[flake_large_bbox[0]: flake_large_bbox[1], flake_large_bbox[2]:flake_large_bbox[3]] - \
                                                        bg_gray[flake_large_bbox[0]: flake_large_bbox[1], flake_large_bbox[2]:flake_large_bbox[3]] )
            f_contrast[r_min:r_max, c_min:c_max, 1] = np.abs(im_hsv[flake_large_bbox[0]: flake_large_bbox[1], flake_large_bbox[2]:flake_large_bbox[3], 0] - \
                                                        bg_hsv[flake_large_bbox[0]: flake_large_bbox[1], flake_large_bbox[2]:flake_large_bbox[3], 0])
            f_contrast = f_contrast.astype(np.uint8)

            cv2.imwrite(
                os.path.join(ae_img_path, '%s-%d.png' % (ins_name, cnt)),
                np.flip(f_img, 2))
            cv2.imwrite(
                os.path.join(ae_mask_path, '%s-%d.png' % (ins_name, cnt)),
                f_mask)
            cv2.imwrite(
                os.path.join(ae_contrast_path, '%s-%d.png' % (ins_name, cnt)),
                f_contrast)
            cv2.imwrite(
                os.path.join(ae_bg_path, '%s-%d.png' % (ins_name, cnt)),
                np.flip(f_bg_img, 2))
            cnt += 1
def load_one_image(fname, flake_path, data_path, output_img_size=256):
    flake_info = pickle.load(open(os.path.join(flake_path, fname), 'rb'))
    img_name = fname.split('.')[0] + '.tiff'
    image = Image.open(os.path.join(data_path, img_name))

    im_rgb = np.array(image).astype('float')
    im_hsv = color.rgb2hsv(im_rgb)
    im_hsv[:, :, 2] = im_hsv[:, :, 2] / 255.0
    im_gray = color.rgb2gray(im_rgb)
    imH, imW = im_gray.shape

    # get bg image
    bg_rgb = []
    [C, R] = np.meshgrid(np.arange(0, imW), np.arange(0, imH))
    Y = np.reshape(R, [-1]) / (imH - 1) - 0.5
    X = np.reshape(C, [-1]) / (imW - 1) - 0.5
    A = np.stack([
        np.ones([imH * imW]),
        X * X,
        Y * Y,
        X * Y,
        X,
        Y,
    ], axis=1)
    for c in range(3):
        brob_rlm_model = robustfit.RLM()
        brob_rlm_model.fit(A, np.reshape(im_rgb[:, :, c], [-1]))
        pred_map = np.reshape(brob_rlm_model.predict(A), [imH, imW])
        bg_rgb.append(pred_map)
    bg_rgb = np.stack(bg_rgb, axis=2).astype('float')
    bg_hsv = color.rgb2hsv(bg_rgb)
    bg_hsv[:, :, 2] = bg_hsv[:, :, 2] / 255.0
    bg_gray = color.rgb2gray(bg_rgb)

    # build a list of flakes
    num_flakes = len(flake_info['flakes'])
    image_labelmap = flake_info['image_labelmap']
    flakes = flake_info['flakes']
    large_flake_idxs = []
    for i in range(num_flakes):
        flake_size = flakes[i]['flake_size']
        if flake_size > hyperparams['size_thre']:
            large_flake_idxs.append(i)
            flake_centroids = flakes[i]['flake_center'].astype('int')
            flake_large_bbox = [
                max(0, flake_centroids[0] - output_img_size // 2),
                min(imH, flake_centroids[0] + output_img_size // 2),
                max(0, flake_centroids[1] - output_img_size // 2),
                min(imW, flake_centroids[1] + output_img_size // 2)
            ]

            f_img = np.zeros([output_img_size, output_img_size, 3],
                             dtype=np.uint8)
            r_min = output_img_size // 2 - (flake_centroids[0] -
                                            flake_large_bbox[0])
            r_max = r_min + (flake_large_bbox[1] - flake_large_bbox[0])
            c_min = output_img_size // 2 - (flake_centroids[1] -
                                            flake_large_bbox[2])
            c_max = c_min + (flake_large_bbox[3] - flake_large_bbox[2])
            # print(r_min, r_max, c_min, c_max)
            f_img[r_min:r_max, c_min:c_max, :] = im_rgb[
                flake_large_bbox[0]:flake_large_bbox[1],
                flake_large_bbox[2]:flake_large_bbox[3], :]
            f_img = f_img.astype(np.uint8)

            # get mask
            mask = (image_labelmap == flakes[i]['flake_id']).astype(np.uint8)
            mask[mask == 1] = 255
            f_mask = np.zeros([output_img_size, output_img_size],
                              dtype=np.uint8)
            f_mask[r_min:r_max,
                   c_min:c_max] = mask[flake_large_bbox[0]:flake_large_bbox[1],
                                       flake_large_bbox[2]:flake_large_bbox[3]]
            f_contrast = np.zeros([output_img_size, output_img_size, 3],
                                  dtype=np.uint8)
            f_contrast[r_min:r_max, c_min:c_max, 0] = np.abs(im_gray[flake_large_bbox[0]: flake_large_bbox[1], flake_large_bbox[2]:flake_large_bbox[3]] - \
                                                            bg_gray[flake_large_bbox[0]: flake_large_bbox[1], flake_large_bbox[2]:flake_large_bbox[3]])
            f_contrast[r_min:r_max, c_min:c_max, 1] = np.abs(im_hsv[flake_large_bbox[0]: flake_large_bbox[1], flake_large_bbox[2]:flake_large_bbox[3], 0] - \
                                                            bg_hsv[flake_large_bbox[0]: flake_large_bbox[1], flake_large_bbox[2]:flake_large_bbox[3], 0])
            f_contrast = f_contrast.astype(np.uint8)

            flakes[i]['flake_img'] = f_img
            flakes[i]['flake_mask'] = f_mask
            flakes[i]['flake_contrast'] = f_contrast

    flakes = [flakes[j] for j in large_flake_idxs]
    return flakes