Exemplo n.º 1
0
def get_image_with_height_list(sample_txt, img_ext, info_type='training'):
    height_list = []
    width_list = []
    band_count = 0
    image_path_list = []
    dtype = 'unknown'
    with open(sample_txt, 'r') as f_obj:
        lines = f_obj.readlines()
        for line in lines:
            image_path = os.path.join('split_images', line.strip() + img_ext)
            height, width, band_count, dtype = raster_io.get_height_width_bandnum_dtype(image_path)
            image_path_list.append(image_path)
            height_list.append(height)
            width_list.append(width)

    # save info to file, if it exists, add information to the file
    img_count = len(image_path_list)
    with open('sub_images_patches_info.txt','a') as f_obj:
        f_obj.writelines('information of %s image patches: \n'%info_type)
        f_obj.writelines('number of %s image patches : %d \n' % (info_type,img_count))
        f_obj.writelines('band count : %d \n'%band_count)
        f_obj.writelines('data type : %s \n'%dtype)
        f_obj.writelines('maximum width and height: %d, %d \n'% (max(width_list), max(height_list)) )
        f_obj.writelines('minimum width and height: %d, %d \n'% (min(width_list), min(height_list)) )
        f_obj.writelines('mean width and height: %.2f, %.2f \n\n'% (sum(width_list)/img_count, sum(height_list)/img_count))

    return True
Exemplo n.º 2
0
def get_yolo_boxes_one_img(idx,
                           total,
                           image_path,
                           label_path,
                           num_classes_noBG,
                           rm_edge_obj=False):
    print('to yolo box: %d/%d' % (idx + 1, total))
    # a object : [ class_id,  minX, minY, maxX, maxY ]
    objects = get_boxes_from_label_image(label_path)
    save_object_txt = os.path.splitext(image_path)[0] + '.txt'
    height, width, count, dtype = raster_io.get_height_width_bandnum_dtype(
        label_path)

    with open(save_object_txt, 'w') as f_obj:
        for object in objects:
            class_id, minX, minY, maxX, maxY = object
            if class_id > num_classes_noBG:
                raise ValueError(
                    'Class ID: %d greater than number of classes in label: %s'
                    % (class_id, label_path))

            # remove objects touch the image edge, usually, target object is in the center of images,
            # but some targets close to this one may be cut when we extract sub-images or split imgaes
            if rm_edge_obj:
                if minX == 0 or minY == 0 or maxX == (width - 1) or maxY == (
                        height - 1):
                    print(
                        'warning, object (minX, minY, maxX, maxY): (%d %d %d %d) touched the edge in %s, ignore it'
                        % (minX, minY, maxX, maxY, label_path))
                    continue

            # in semantic, class_id 0 is background, yolo, class 0 is target, so minus 1
            class_id -= 1
            x, y, w, h = convert((width, height), (minX, maxX, minY, maxY))
            f_obj.writelines('%d %f %f %f %f\n' % (class_id, x, y, w, h))
Exemplo n.º 3
0
def test_darknet_batch_detection_rs_images():
    print('\n')
    print('Run test_darknet_batch_detection_rs_images')

    config_file = 'yolov4_obj_oneband.cfg'
    yolo_data = os.path.join('data', 'obj.data')
    weights = os.path.join('exp1', 'yolov4_obj_oneband_best.weights')
    batch_size = 1

    # these three have the same size
    # image_names = ['20200818_mosaic_8bit_rgb_p_1001.png'] #, '20200818_mosaic_8bit_rgb_p_1038.png', '20200818_mosaic_8bit_rgb_p_1131.png']
    image_names = ['Alaska_north_slope_hillshade_20170426_poly_28_p_0.png'] #, '20200818_mosaic_8bit_rgb_p_1038.png', '20200818_mosaic_8bit_rgb_p_1131.png']
    image_names = [os.path.join('debug_img', item) for item in image_names]
    image_path = image_names[0]
    save_dir = './'

    height, width, band_num, date_type = raster_io.get_height_width_bandnum_dtype(image_path)
    # print('input image: height, width, band_num, date_type',height, width, band_num, date_type)

    # divide the image the many small patches, then calcuate one by one, solving memory issues.
    patch_w = 480
    patch_h = 480
    overlay_x = 160
    overlay_y = 160
    image_patches = split_image.sliding_window(width,height,patch_w,patch_h,adj_overlay_x=overlay_x,adj_overlay_y=overlay_y)
    patch_count = len(image_patches)

    if os.path.isdir(save_dir) is False:
        io_function.mkdir(save_dir)

    # group patches based on size, each patch is (xoff,yoff ,xsize, ysize)
    patch_groups = {}
    for patch in image_patches:
        wh_str = 'w%d'%patch[2] + '_' + 'h%d'%patch[3]
        if wh_str in patch_groups.keys():
            patch_groups[wh_str].append(patch)
        else:
            patch_groups[wh_str] = [patch]


    # load network
    network, class_names, class_colors = load_darknet_network(config_file, yolo_data, weights, batch_size=batch_size)

    darknet_batch_detection_rs_images(network, image_path, save_dir, patch_groups, patch_count, class_names, batch_size,
                                      thresh=0.25, hier_thresh=.5, nms=.45)
Exemplo n.º 4
0
def get_sub_images_multi_regions(para_file):

    print(
        "extract sub-images and sub-labels for a given shape file (training polygons)"
    )

    if os.path.isfile(para_file) is False:
        raise IOError('File %s not exists in current folder: %s' %
                      (para_file, os.getcwd()))

    get_subImage_script = os.path.join(code_dir, 'datasets',
                                       'get_subImages.py')
    SECONDS = time.time()

    # get name of training areas
    multi_training_regions = parameters.get_string_list_parameters_None_if_absence(
        para_file, 'training_regions')
    if multi_training_regions is None or len(multi_training_regions) < 1:
        raise ValueError('No training area is set in %s' % para_file)

    # multi_training_files = parameters.get_string_parameters_None_if_absence(para_file, 'multi_training_files')

    dstnodata = parameters.get_string_parameters(para_file, 'dst_nodata')
    buffersize = parameters.get_string_parameters(para_file, 'buffer_size')
    rectangle_ext = parameters.get_string_parameters(para_file,
                                                     'b_use_rectangle')
    process_num = parameters.get_digit_parameters(para_file, 'process_num',
                                                  'int')

    b_no_label_image = parameters.get_bool_parameters_None_if_absence(
        para_file, 'b_no_label_image')

    if os.path.isfile('sub_images_labels_list.txt'):
        io_function.delete_file_or_dir('sub_images_labels_list.txt')

    subImage_dir = parameters.get_string_parameters_None_if_absence(
        para_file, 'input_train_dir')
    subLabel_dir = parameters.get_string_parameters_None_if_absence(
        para_file, 'input_label_dir')

    # loop each training regions
    for idx, area_ini in enumerate(multi_training_regions):

        input_image_dir = parameters.get_directory_None_if_absence(
            area_ini, 'input_image_dir')

        # it is ok consider a file name as pattern and pass it the following functions to get file list
        input_image_or_pattern = parameters.get_string_parameters(
            area_ini, 'input_image_or_pattern')

        b_sub_images_json = parameters.get_bool_parameters(
            area_ini, 'b_sub_images_json')
        if b_sub_images_json is True:
            # copy sub-images, then covert json files to label images.
            object_names = parameters.get_string_list_parameters(
                para_file, 'object_names')
            get_subImages_json.get_subimages_label_josn(
                input_image_dir,
                input_image_or_pattern,
                subImage_dir,
                subLabel_dir,
                object_names,
                b_no_label_image=b_no_label_image,
                process_num=process_num)

            pass
        else:

            all_train_shp = parameters.get_file_path_parameters_None_if_absence(
                area_ini, 'training_polygons')
            train_shp = parameters.get_string_parameters(
                area_ini, 'training_polygons_sub')

            # get subImage and subLabel for one training polygons
            print(
                'extract training data from image folder (%s) and polgyons (%s)'
                % (input_image_dir, train_shp))
            if b_no_label_image is True:
                get_subImage_one_shp(get_subImage_script,
                                     all_train_shp,
                                     buffersize,
                                     dstnodata,
                                     rectangle_ext,
                                     train_shp,
                                     input_image_dir,
                                     file_pattern=input_image_or_pattern,
                                     process_num=process_num)
            else:
                get_subImage_subLabel_one_shp(
                    get_subImage_script,
                    all_train_shp,
                    buffersize,
                    dstnodata,
                    rectangle_ext,
                    train_shp,
                    input_image_dir,
                    file_pattern=input_image_or_pattern,
                    process_num=process_num)

    # check black sub-images or most part of the sub-images is black (nodata)
    new_sub_image_label_list = []
    delete_sub_image_label_list = []
    subImage_dir_delete = subImage_dir + '_delete'
    subLabel_dir_delete = subLabel_dir + '_delete'
    io_function.mkdir(subImage_dir_delete)
    if b_no_label_image is None or b_no_label_image is False:
        io_function.mkdir(subLabel_dir_delete)
    get_valid_percent_entropy.plot_valid_entropy(subImage_dir)
    with open('sub_images_labels_list.txt', 'r') as f_obj:
        lines = f_obj.readlines()
        for line in lines:
            image_path, label_path = line.strip().split(':')
            # valid_per = raster_io.get_valid_pixel_percentage(image_path)
            valid_per, entropy = raster_io.get_valid_percent_shannon_entropy(
                image_path)  # base=10
            if valid_per > 60 and entropy >= 0.5:
                new_sub_image_label_list.append(line)
            else:
                delete_sub_image_label_list.append(line)
                io_function.movefiletodir(image_path, subImage_dir_delete)
                if os.path.isfile(label_path):
                    io_function.movefiletodir(label_path, subLabel_dir_delete)
    if len(delete_sub_image_label_list) > 0:
        with open('sub_images_labels_list.txt', 'w') as f_obj:
            for line in new_sub_image_label_list:
                f_obj.writelines(line)

    # check weather they have the same subImage and subLabel
    if b_no_label_image is None or b_no_label_image is False:
        sub_image_list = io_function.get_file_list_by_pattern(
            subImage_dir, '*.tif')
        sub_label_list = io_function.get_file_list_by_pattern(
            subLabel_dir, '*.tif')
        if len(sub_image_list) != len(sub_label_list):
            raise ValueError(
                'the count of subImage (%d) and subLabel (%d) is different' %
                (len(sub_image_list), len(sub_label_list)))

    # save brief information of sub-images
    height_list = []
    width_list = []
    band_count = 0
    dtype = 'unknown'
    for line in new_sub_image_label_list:
        image_path, label_path = line.strip().split(':')
        height, width, band_count, dtype = raster_io.get_height_width_bandnum_dtype(
            image_path)
        height_list.append(height)
        width_list.append(width)
    # save info to file, if it exists, it will be overwritten
    img_count = len(new_sub_image_label_list)
    with open('sub_images_patches_info.txt', 'w') as f_obj:
        f_obj.writelines('information of sub-images: \n')
        f_obj.writelines('number of sub-images : %d \n' % img_count)
        f_obj.writelines('band count : %d \n' % band_count)
        f_obj.writelines('data type : %s \n' % dtype)
        f_obj.writelines('maximum width and height: %d, %d \n' %
                         (max(width_list), max(height_list)))
        f_obj.writelines('minimum width and height: %d, %d \n' %
                         (min(width_list), min(height_list)))
        f_obj.writelines(
            'mean width and height: %.2f, %.2f \n\n' %
            (sum(width_list) / img_count, sum(height_list) / img_count))

    duration = time.time() - SECONDS
    os.system(
        'echo "$(date): time cost of getting sub images and labels: %.2f seconds">>time_cost.txt'
        % duration)
Exemplo n.º 5
0
def predict_rs_image_yolo_poythonAPI(image_path,
                                     save_dir,
                                     model,
                                     config_file,
                                     yolo_data,
                                     patch_w,
                                     patch_h,
                                     overlay_x,
                                     overlay_y,
                                     batch_size=1):
    '''
    predict an remote sensing using YOLO Python API
    :param image_path:
    :param save_dir:
    :param model:
    :param config_file:
    :param yolo_data:
    :param patch_w:
    :param patch_h:
    :param overlay_x:
    :param overlay_y:
    :param batch_size:
    :return:
    '''
    height, width, band_num, date_type = raster_io.get_height_width_bandnum_dtype(
        image_path)
    # print('input image: height, width, band_num, date_type',height, width, band_num, date_type)

    # divide the image the many small patches, then calcuate one by one, solving memory issues.
    image_patches = split_image.sliding_window(width,
                                               height,
                                               patch_w,
                                               patch_h,
                                               adj_overlay_x=overlay_x,
                                               adj_overlay_y=overlay_y)
    patch_count = len(image_patches)

    if os.path.isdir(save_dir) is False:
        io_function.mkdir(save_dir)

    # group patches based on size, each patch is (xoff,yoff ,xsize, ysize)
    patch_groups = {}
    for patch in image_patches:
        wh_str = 'w%d' % patch[2] + '_' + 'h%d' % patch[3]
        if wh_str in patch_groups.keys():
            patch_groups[wh_str].append(patch)
        else:
            patch_groups[wh_str] = [patch]

    network, class_names, _ = load_darknet_network(config_file,
                                                   yolo_data,
                                                   model,
                                                   batch_size=batch_size)

    # batch detection
    if batch_size > 1:
        return darknet_batch_detection_rs_images(network, image_path, save_dir,
                                                 patch_groups, patch_count,
                                                 class_names, batch_size)

    # read the entire image
    entire_img_data, nodata = raster_io.read_raster_all_bands_np(image_path)
    entire_img_data = entire_img_data.transpose(1, 2, 0)  # to opencv format
    # # RGB to BGR: Matplotlib image to OpenCV https://www.scivision.dev/numpy-image-bgr-to-rgb/
    # entire_img_data = entire_img_data[..., ::-1].copy() # cancel RGB to BGR, since it make results worse, (maybe darknet already read images as RGB during training)
    entire_height, entire_width, band_num = entire_img_data.shape
    print("entire_height, entire_width, band_num", entire_height, entire_width,
          band_num)
    if band_num not in [1, 3]:
        raise ValueError('only accept one band or three band images')

    patch_idx = 0
    for key in patch_groups.keys():
        patches_sameSize = patch_groups[key]

        # get width, height, and band_num of a patch, then create a darknet image.
        # img_data, nodata = raster_io.read_raster_all_bands_np(image_path, boundary=patches_sameSize[0])
        # img_data = img_data.transpose(1, 2, 0)
        # height, width, band_num = img_data.shape
        # if band_num not in [1, 3]:
        #     raise ValueError('only accept one band or three band images')

        height, width = patches_sameSize[0][3], patches_sameSize[0][2]

        # Create one with image we reuse for each detect : images with the same size.
        darknet_image = darknet.make_image(width, height, band_num)

        for idx, patch in enumerate(patches_sameSize):
            t0 = time.time()
            # patch: (xoff,yoff ,xsize, ysize)
            # img_data, nodata = raster_io.read_raster_all_bands_np(image_path,boundary=patch)
            # img_data = img_data.transpose(1, 2, 0)
            img_data = copy_one_patch_image_data(patch, entire_img_data)

            # prediction
            darknet.copy_image_from_bytes(darknet_image, img_data.tobytes())
            # thresh=0.25, relative low, set to 0 will output too many, post-process later
            detections = darknet.detect_image(network,
                                              class_names,
                                              darknet_image,
                                              thresh=0.25)

            # save results
            save_res_json = os.path.join(save_dir, '%d.json' % patch_idx)
            save_one_patch_detection_json(patch, detections, class_names,
                                          save_res_json)

            if patch_idx % 100 == 0:
                print('saving %d patch, total: %d, cost %f second' %
                      (patch_idx, patch_count, time.time() - t0))

            patch_idx += 1

        darknet.free_image(darknet_image)
Exemplo n.º 6
0
def merge_subImages_from_gan(multi_gan_source_regions, multi_gan_regions,
                             gan_working_dir, gan_dir_pre_name, save_image_dir,
                             save_label_dir):
    '''
    merge translate subimages from GAN to orginal sub_images
    :param multi_gan_regions:
    :param gan_working_dir:
    :param gan_dir_pre_name:
    :return:
    '''

    current_dir = os.getcwd()
    sub_img_label_txt_noGAN, sub_img_label_txt, area_ini_sub_images_labels_dict = original_sub_images_labels_list_before_gan(
    )

    # # get original sub-images and labels
    # org_sub_images = []
    # org_sub_labels = []
    # with open(sub_img_label_txt_noGAN) as txt_obj:
    #     line_list = [name.strip() for name in txt_obj.readlines()]
    #     for line in line_list:
    #         sub_image, sub_label = line.split(':')
    #         org_sub_images.append(os.path.join(current_dir,sub_image))
    #         org_sub_labels.append(os.path.join(current_dir,sub_label))
    #
    # # merge new sub images, and copy sub labels if necessary.
    new_sub_images = []
    new_sub_labels = []

    area_ini_sub_images_labels = io_function.read_dict_from_txt_json(
        area_ini_sub_images_labels_dict)
    # copy the original sub images and labels before GAN
    for key in area_ini_sub_images_labels.keys():
        for line in area_ini_sub_images_labels[key]:
            sub_image, sub_label = line.split(':')
            new_sub_images.append(sub_image)
            new_sub_labels.append(sub_label)

    for area_idx, (area_ini, area_src_ini) in enumerate(
            zip(multi_gan_regions, multi_gan_source_regions)):
        area_name = parameters.get_string_parameters(area_ini, 'area_name')
        area_remark = parameters.get_string_parameters(area_ini, 'area_remark')
        area_time = parameters.get_string_parameters(area_ini, 'area_time')

        gan_project_save_dir = get_gan_project_save_dir(
            gan_working_dir, gan_dir_pre_name, area_name, area_remark,
            area_time, area_src_ini)

        org_sub_images = []
        org_sub_labels = []
        for line in area_ini_sub_images_labels[os.path.basename(area_src_ini)]:
            sub_image, sub_label = line.split(':')
            org_sub_images.append(os.path.join(current_dir, sub_image))
            org_sub_labels.append(os.path.join(current_dir, sub_label))

        # the new images, keep the same order of original images
        for idx, (org_img,
                  org_label) in enumerate(zip(org_sub_images, org_sub_labels)):
            new_img = os.path.join(gan_project_save_dir, 'subImages_translate',
                                   'I%d.tif' % idx)

            if os.path.isfile(new_img) is False:
                basic.outputlogMessage(
                    'warning, %d th image does not exist, '
                    'may exceed gen_max_dataset_size, skip the following images '
                    % idx)
                break

            # check height, width, band count, datatype
            height, width, count, dtype = raster_io.get_height_width_bandnum_dtype(
                new_img)
            o_height, o_width, o_count, o_dtype = raster_io.get_height_width_bandnum_dtype(
                org_img)
            if height != o_height or width != o_width or count != o_count or dtype != o_dtype:
                raise ValueError(
                    'inconsistence between new GAN image and original images: %s vs %s'
                    % (str([height, width, count, dtype
                            ]), str([o_height, o_width, o_count, o_dtype])))

            # copy subimage and sublabel
            new_file_name_no_ext = io_function.get_name_no_ext(
                org_img) + '_' + os.path.basename(gan_project_save_dir)
            save_img_path = os.path.join(save_image_dir,
                                         new_file_name_no_ext + '_gan.tif')
            save_label_path = os.path.join(save_label_dir,
                                           new_file_name_no_ext + '_label.tif')
            io_function.copy_file_to_dst(new_img,
                                         save_img_path,
                                         overwrite=False)
            io_function.copy_file_to_dst(org_label,
                                         save_label_path,
                                         overwrite=False)

            new_sub_images.append(save_img_path)
            new_sub_labels.append(save_label_path)

    # save new images_labels_list.txt, overwrite the original one
    with open(sub_img_label_txt, 'w') as f_obj:
        lines = [
            img + ':' + label + '\n'
            for img, label in zip(new_sub_images, new_sub_labels)
        ]
        f_obj.writelines(lines)

    return True