Esempio n. 1
0
def create_byn_mask(img_eq, parameters, img_name, to_byn_folder, _save=False):
    # opencv k-means clustering segmentation
    K = int(parameters['K_cluster'])
    img_k4, center, label = opencv_th_k_means_th(img=img_eq, K=K)

    # choice label for segmentation
    k_true_by_param = int(parameters['K_true'])
    unique, counts = np.unique(img_k4, return_counts=True)

    # check cluster dimension
    if counts[1] > counts[0]:
        k_true = k_true_by_param - 1  # 2th cluster is too big -> 1th and 2th are mapped to black
    else:
        k_true = k_true_by_param  # 2th cluster is ok -> only 1th cluster is mapped to black

    # create binary mask from segmented images
    cells_mask = make_cells_mask(center, label, img_eq.shape, K=K,
                                 true=k_true)  # pixels are ZERO or ONE

    # prepare defintive mask
    t_ratio_holes = parameters['t_ratio_holes']
    BW_cells_mask = widens_mask_deconv(cells_mask, t_ratio_holes)

    if _save:
        save_tiff(img=BW_cells_mask,
                  img_name=img_name,
                  comment='bin',
                  folder_path=to_byn_folder)
    return BW_cells_mask, np.count_nonzero(BW_cells_mask)
Esempio n. 2
0
def create_and_save_segmented_images(bw_cells_mask,
                                     img_eq,
                                     img_name,
                                     to_seg_folder,
                                     _save=False):
    final = img_eq * bw_cells_mask.astype(bool)
    if _save:
        save_tiff(img=final,
                  img_name=img_name,
                  comment='seg',
                  folder_path=to_seg_folder)
Esempio n. 3
0
def clahe(img, parameters, img_name, to_folder, _save=False):
    ksize = parameters['clahe_ksize']
    clip = parameters['clip_clahe']
    img = normalize(
        exposure.equalize_adapthist(img, clip_limit=clip, kernel_size=ksize))
    if _save:
        save_tiff(img=img,
                  img_name=img_name,
                  comment='eq',
                  folder_path=to_folder)
    return img
Esempio n. 4
0
def save_contours(img_name, contours, img_shape, countours_folder):
    # empty black image
    black = np.zeros(img_shape)

    # draw contours
    cv2.drawContours(black, contours, -1, 255, 1)

    # save singular images
    save_tiff(img=black,
              img_name=img_name,
              comment='only_cont',
              folder_path=countours_folder)
Esempio n. 5
0
def segment_by_masks(parsers):
    print('START')
    args = parser.parse_args()
    if args.source_file_list == None or args.mask_file_list == None:
        print('You should select the Path of Source Images and masks Images.')
        parser.print_help()

    source_data = make_dataset(args.source_file_list)
    print('source_file_list ', args.source_file_list)
    print('source_data.len() = ', len(source_data))

    mask_data = make_dataset(args.mask_file_list)
    print('mask_file_list ', args.mask_file_list)
    print('mask_data.len() = ', len(mask_data))

    dest_folder = args.output
    print('dest_folder ', dest_folder)

    imgs = create_stack(source_data)
    print('imgs.shape[2] = ', imgs.shape[2])

    masks = create_stack(mask_data)
    print('imgs.shape[2] = ', imgs.shape[2])

    if imgs is not None and masks is not None:

        if imgs.shape[2] != masks.shape[2]:
            print('Warning! Dimension of Images and masks mismatch.')

        else:
            # todo script
            print('write in {} \n'.format(dest_folder))

            segmented = np.zeros(imgs.shape)
            print('\n segmented shape: ', segmented.shape)
            print('imgs shape: ', imgs.shape)
            print('masks shape: ', masks.shape)

            for z in range(imgs.shape[2]):
                img = normalize(imgs[:, :, z])
                img_eq = exposure.equalize_adapthist(img, clip_limit=0.03)

                segmented[:, :, z] = img_eq * masks[:, :, z]

                save_tiff(img=segmented[:, :, z],
                          img_name=str(z),
                          prefix='s',
                          comment='dec_seg',
                          folder_path=dest_folder)
                print('img n° {}'.format(z))

            print(' \n ** Proces Finished \n')
Esempio n. 6
0
def create_surrounded_images(BW_mask,
                             img_eq,
                             img_name,
                             to_countourned_folder,
                             _save=False):
    # plot contour mak over original image
    contours = (cv2.findContours(BW_mask.copy(), cv2.RETR_TREE,
                                 cv2.CHAIN_APPROX_NONE))[1]

    # prepare image
    img_eq_with_contour = normalize(img_eq.copy())

    # draw contour
    cv2.drawContours(img_eq_with_contour, contours, -1, 255, 1)

    if _save:
        save_tiff(img=img_eq_with_contour,
                  img_name=img_name,
                  comment='cont',
                  folder_path=to_countourned_folder)
    return contours
Esempio n. 7
0
def main(parser):

    # read args from console
    args = parser.parse_args()

    # read source path (path of binary segmentation images)
    source_path = manage_path_argument(args.source_folder)

    # take base path and stack name
    base_path = os.path.dirname(os.path.dirname(source_path))
    stack_name = os.path.basename(source_path)

    # create path and folder where save section images
    sections_path = os.path.join(base_path, 'xz_sections', stack_name)
    filled_sections_path = os.path.join(base_path, 'xz_filled_sections',
                                        stack_name)
    for path in [sections_path, filled_sections_path]:
        if not os.path.exists(path):
            os.makedirs(path)

    # portion of y axes for section estimation
    y_start = np.uint16(args.y_start[0])
    y_stop = np.uint16(args.y_stop[0])

    # preference for fill or not the holes
    _fill_holes = args.fill_holes

    print('\n\n\n _fill_holes : ', _fill_holes)

    # Def .txt filepath
    txt_parameters_path = os.path.join(base_path, 'parameters.txt')
    if _fill_holes:
        txt_results_path = os.path.join(base_path,
                                        'Measure_analysis_filled.txt')
    else:
        txt_results_path = os.path.join(base_path, 'Measure_analysis.txt')

    # SCRIPT ----------------------------------------------------------------------

    # print to video and write in results.txt init message
    init_message = [
        ' ****  Script for Estimation of Section Area and Volume **** \n \n'
        ' Source from path : {}'.format(base_path),
        ' Stack : {}'.format(stack_name), '\n\n *** Start processing... \n'
    ]
    error_message = '\n *** ERROR *** : stack in this path is None'
    with open(txt_results_path, 'w') as f:
        for line in init_message:
            print(line)
            f.write(line + '\n')

    # reads parameters
    parameters = extract_parameters(txt_parameters_path)

    # measure units
    x_step = parameters['res_xy']  # micron
    y_step = parameters['res_xy']  # micron
    z_step = parameters['res_z']  # micron
    pixel_xy_in_micron2 = x_step * y_step  # micron^2
    pixel_xz_in_micron2 = x_step * z_step  # micron^2
    voxel_in_micron3 = x_step * y_step * z_step  # micron^3

    # preferences
    _save_binary_sections = bool(parameters['save_binary_sections'])

    # create images stack from source path
    print(' *** Start to load the Stack...')

    # old version:
    # masks, mess = load_stack_into_numpy_ndarray([source_path])
    # print(mess)

    #new version:
    masks = load_tif_data(source_path)
    if len(masks.shape) == 2:
        masks = np.expand_dims(masks, axis=2)  # add the zeta axis

    # count selected sections
    total_sections = masks.shape[0]  # row -> y -> number of sections
    print('\n Volume shape:', masks.shape)
    print('Number of total sections: ', total_sections)
    print('\n')

    # set y portion
    if y_stop < y_start:
        y_start = np.uint16(total_sections / 4)
        y_stop = np.uint16(total_sections * 3 / 4)
        print(
            ' *** ATTENTION : y portion selected by DEFAULT: {} -> {}'.format(
                y_start, y_stop))

    # Every Section(y) is XZ projection of mask. Estimated Area is the sum of the Non_Zero pixel
    selected_sections = np.uint16(y_stop - y_start)
    sections_micron2 = np.zeros(selected_sections)
    print('Number of selected sections: ', y_stop - y_start)

    # Initializing to zero the Volume counter
    effective_myocites_volume = 0  # real estimated volume of myocites (sum of area of real cells)

    t_start = time.time()
    analyzed_section = 0  # counter, only for control the for loop (remove)

    with open(txt_results_path, 'a') as f:

        pre_info = list()
        pre_info.append('\nPortion of y selected: [{} -> {}]'.format(
            y_start, y_stop))
        pre_info.append('Option for fill the holes: {}'.format(_fill_holes))
        pre_info.append('\n')
        for l in pre_info:
            print(l)
            f.write(l + '\n')

        if masks is not None:

            # *** 1 ***  - Mean Section Estimation
            print('\n... Estimation of mean section...')
            for y in range(y_start, y_stop):

                # extract section
                section = masks[y, :, :]
                sec_name = create_img_name_from_index(total_sections - y -
                                                      1)  # img_name.tif

                # filled the section holes and set comment for tiff filenames
                if _fill_holes:
                    section = ndimage.morphology.binary_fill_holes(section)
                    comment = 'filled_section'
                    dest_path = filled_sections_path
                else:
                    comment = 'section'
                    dest_path = sections_path

                # count cell pixel
                pixels_with_cell = np.count_nonzero(section.astype(bool))

                if pixels_with_cell > 0:
                    area_in_micron2 = pixels_with_cell * pixel_xz_in_micron2
                    sections_micron2[y - y_start] = area_in_micron2
                    measure = ' - {}   ---->   {} um^2'.format(
                        sec_name, area_in_micron2)

                    if _save_binary_sections:
                        # transform point of view
                        section = np.rot90(m=np.flipud(section),
                                           k=1,
                                           axes=(0, 1))
                        # save section in correct path
                        save_tiff(img=section,
                                  img_name=sec_name,
                                  comment=comment,
                                  folder_path=dest_path)

                else:
                    measure = ' - {} is empty'.format(sec_name)

                analyzed_section += 1
                print(measure)
                # f.write(measure+'\n')

            # *** 2 ***  - Volume Estimation
            print('\n\n ...Estimation of Volume...\n')
            for z in range(masks.shape[2]):
                # check fill option
                if _fill_holes:
                    print('... filling {} xy frame'.format(z))
                    z_frame = ndimage.morphology.binary_fill_holes(masks[:, :,
                                                                         z])
                else:
                    z_frame = masks[:, :, z]
                # add pixels_of_real_cells of current z-slice to the counter
                effective_myocites_volume += np.count_nonzero(z_frame)

            # execution time
            (h, m, s) = seconds_to_min_sec(time.time() - t_start)

            # volumes in micron^3
            effective_volume_in_micron3 = effective_myocites_volume * voxel_in_micron3

            # count empty sections
            sections_with_cell = np.count_nonzero(sections_micron2)
            empties = selected_sections - sections_with_cell

            # Mean sections:
            mean_section = np.sum(
                sections_micron2) / sections_with_cell  # (original images)

            # create results string
            result_message = list()
            result_message.append(
                '\n ***  Process successfully completed, time of execution: {0:2d}h {1:2d}m {2:2d}s \n'
                .format(int(h), int(m), int(s)))
            result_message.append(' Total number of frames: {}'.format(
                masks.shape[2]))
            result_message.append(' Total sections: {}'.format(total_sections))
            result_message.append(
                ' Selected sections: {}'.format(selected_sections))
            result_message.append(
                ' Effective analyzed sections: {}'.format(analyzed_section))
            result_message.append(
                ' Number of empty section: {}'.format(empties))
            result_message.append(
                ' Number of section with cells: {}'.format(sections_with_cell))
            result_message.append('\n')
            result_message.append(
                ' Mean sections: {0:.3f} um^2'.format(mean_section))
            result_message.append(
                ' Effective miocytes tissue volume : {0:.6f} mm^3'.format(
                    effective_volume_in_micron3 / 10**9))

            result_message.append('\n')
            result_message.append(' \n OUTPUT SAVED IN: \n')
            result_message.append(txt_results_path)

            # write and print results
            for l in result_message:
                print(l)
                f.write(l + '\n')

        else:
            print(error_message)
            f.write(error_message)

        print(' \n \n \n ')