def get_report_df(filesdir, lengthValue):

        filepaths = NumDensityReporter.scanAllFiles(filesdir)

        report_df = pd.DataFrame(
            columns=['dir', 'xmlfile', 'index', 'diameter'])
        for i_xml, xmlPath in enumerate(filepaths):
            *dir_, _ = xmlPath.split('_')
            dir_ = os.path.basename("_".join(dir_)) if isinstance(
                dir_, (list, tuple)) else os.path.basename(dir_)

            xmlfilename = os.path.basename(xmlPath)
            if os.path.isfile(xmlPath) is False:
                continue
            tVocParseReader = PascalVocReader(xmlPath)
            shapes = tVocParseReader.getShapes()
            i_label = 0
            i_track = 0
            i_easytrack = 0
            for shape in shapes:
                shapeType, label, points, _, _, difficult = shape
                if shapeType == shapeTypes.ellipse:
                    diameter = getDiameter(points) * lengthValue
                    report_df = report_df.append([{
                        'dir': dir_,
                        'xmlfile': xmlfilename,
                        'index': i_label,
                        'diameter': diameter
                    }])
                    i_label += 1
        return report_df
Esempio n. 2
0
def get_meta(image_path=None, xml_dir=None):
    basename = os.path.basename(os.path.splitext(image_path)[0])
    meta_path = os.path.join(xml_dir, basename + XML_EXT)
    if os.path.isfile(meta_path):
        reader = PascalVocReader(meta_path)
        reader.parseXML()
        return reader
    else:
        return None
Esempio n. 3
0
 def __init__(self, filename=None):
     if filename is not None:
         reader = PascalVocReader(filename)
         self.shapes = reader.getShapes()
         self.imagePath = reader.imagePath
         self.imageData = read(self.imagePath, None)
         self.verified = reader.verified
     else:
         self.shapes = ()
         self.imagePath = None
         self.imageData = None
         self.verified = False
Esempio n. 4
0
    def loadPascalXMLByFilename(self, xmlPath):
        if self.filePath is None:
            return

        if os.path.isfile(xmlPath) is False:
            return

        tVocParseReader = PascalVocReader(xmlPath)
        shapes = tVocParseReader.getShapes()

        self.loadLabels(shapes)
        self.canvas.verified = tVocParseReader.verified
Esempio n. 5
0
def get_image(filename,label_num_dic = None):
    tVocParseReader = PascalVocReader(filename)
    raw_shapes = tVocParseReader.getShapes()
    print raw_shapes
    def format_shape(s):
        label,points,aa,bb,c = s
        return dict(label=unicode(label),
                    points=[(int(p[0]), int(p[1])) for p in points])

    shapes = [format_shape(shape) for shape in raw_shapes]
    image_size = tVocParseReader.get_img_size()
    result_path = '/mask'+filename.split('/')[1].split('.')[0]+'.png'
    mask_writer = save_mask_image.label_mask_writer(label_num_dic, result_path, image_size[0],
                                                    image_size[1])
    mask_writer.save_mask_image(shapes)
Esempio n. 6
0
def generate_mask_png(label_num_dic, xml_file_name, output_path):
    if os.path.exists(output_path) is False:
        os.makedirs(output_path)
    tVocParseReader = PascalVocReader(xml_file_name)
    shapes = tVocParseReader.getShapes()
    image_size = tVocParseReader.get_img_size()

    num = 1
    no_ext_name = os.path.splitext(xml_file_name)

    for shape in shapes:
        final_path = no_ext_name + u'_' + unicode(num) + '.png'
        mask_writer = label_mask_writer(label_num_dic, final_path,
                                        image_size[0], image_size[1])
        mask_writer.save_mask_image(shapes)
        num = num + 1
Esempio n. 7
0
    def get_label_info(self, dir_path):
        labels_path = os.path.join(dir_path, 'labels')
        labels_exist_path = labels_path if os.path.exists(
            labels_path) else dir_path

        self.label_to_num = {}
        for file_name in tqdm(os.listdir(labels_exist_path), "check label"):
            if os.path.splitext(file_name)[1] != XML_EXT:
                continue
            xml_path = os.path.join(labels_exist_path, file_name)
            reader = PascalVocReader(xml_path)
            for shape in reader.shapes:
                if shape[0] not in self.label_to_num:
                    self.label_to_num.setdefault(shape[0], 1)
                else:
                    self.label_to_num[shape[0]] += 1
        list_of_dataset = os.listdir(dir_path)
        self.label_to_num['origin_image_num'] = 0
        self.label_to_num['labeled_image_num'] = 0
        for each_item in list_of_dataset:
            if os.path.splitext(each_item)[1] == '.jpg':
                self.label_to_num['origin_image_num'] += 1
            else:
                self.check_label_exist(os.path.join(dir_path, each_item))
        QMessageBox.information(None, 'info', str(self.label_to_num))
Esempio n. 8
0
def get_image(filename, label_num_dic=None):
    tVocParseReader = PascalVocReader(filename)
    raw_shapes = tVocParseReader.getShapes()
    print raw_shapes

    def format_shape(s):
        label, points, aa, bb, c = s
        return dict(label=unicode(label),
                    points=[(int(p[0]), int(p[1])) for p in points])

    shapes = [format_shape(shape) for shape in raw_shapes]
    image_size = tVocParseReader.get_img_size()
    result_path = '/mask' + filename.split('/')[1].split('.')[0] + '.png'
    mask_writer = save_mask_image.label_mask_writer(label_num_dic, result_path,
                                                    image_size[0],
                                                    image_size[1])
    mask_writer.save_mask_image(shapes)
    def get_easy_track_report_df(dir, lengthValue, labelHist):
        easy_track_df = pd.DataFrame(columns=[
            'dir', 'xmlfilename', 'index', 'label', 'shapeType', 'points',
            'difficult'
        ])

        filepaths = NumDensityReporter.scanAllFiles(dir)

        for i_xml, xmlPath in enumerate(filepaths):
            *dir_, _ = xmlPath.split('_')
            dir_ = os.path.basename("_".join(dir_)) if isinstance(
                dir_, (list, tuple)) else os.path.basename(dir_)

            xmlfilename = os.path.basename(xmlPath)

            if os.path.isfile(xmlPath) is False:
                continue
            tVocParseReader = PascalVocReader(xmlPath)
            shapes = tVocParseReader.getShapes()

            i_easytrack = 0
            for shape in shapes:
                shapeType, label, points, _, _, difficult = shape

                if label not in labelHist:
                    easy_track_df = easy_track_df.append([{
                        'dir':
                        dir_,
                        # 'subdir':subdir,
                        'xmlfilename':
                        xmlfilename,
                        'index':
                        i_easytrack,
                        'label':
                        label,
                        'shapeType':
                        shapeType,
                        'points':
                        points,
                        'difficult':
                        difficult
                    }])
                    i_easytrack += 1
        return easy_track_df
Esempio n. 10
0
def visualize(vis_params,
              logger,
              img_path,
              csv_path,
              class_dict,
              init_frame_id=0,
              n_frames=0,
              request_roi=None,
              generator_mode=0,
              enable_masks=0,
              label='',
              only_boxes=0,
              crop_size=()):
    """

    :param vis_params:
    :param logger:
    :param img_path:
    :param csv_path:
    :param class_dict:
    :param init_frame_id:
    :param n_frames:
    :param request_roi:
    :param generator_mode:
    :return:
    """
    global _pause, _quit
    save_fname_templ = os.path.splitext(os.path.basename(img_path))[0]

    # csv_path = os.path.join(img_path, 'annotations.csv')

    df = pd.read_csv(csv_path)

    frames_reader = get_frames_reader(img_path, save_as_bin=False)
    if request_roi is not None:
        frames_reader.setROI(request_roi)
    class_labels = dict((v, k) for k, v in class_dict.items())

    if generator_mode:
        vis_params.show = 0
        vis_params.save = 0

    visualizer = Visualizer(vis_params, logger, class_labels)
    init_frame = frames_reader.get_frame(init_frame_id)

    height, width, _ = init_frame.shape
    frame_size = width, height
    visualizer.initialize(save_fname_templ, frame_size, _pause)

    if n_frames <= 0:
        n_frames = frames_reader.num_frames
    print('Reading {:d} images from {:s}...'.format(n_frames, img_path))

    for frame_id in range(init_frame_id, n_frames):
        try:
            curr_frame = frames_reader.get_frame(frame_id)
        except IOError as e:
            print('{}'.format(e))
            break

        if only_boxes:
            curr_frame = np.zeros_like(curr_frame)

        file_path = frames_reader.get_file_path()
        if file_path is None:
            print('Visualization is only supported on image sequence data')
            return

        filename = os.path.basename(file_path)
        multiple_instance = df.loc[df['filename'] == filename]
        # Total # of object instances in a file
        n_bboxes = len(multiple_instance.index)
        # Remove from df (avoids duplication)
        df = df.drop(multiple_instance.index[:n_bboxes])

        frame_data = []
        masks = []

        generic_target_id = -1

        if enable_masks:
            filename = os.path.basename(file_path)
            xml_path = os.path.join(img_path, 'annotations',
                                    os.path.splitext(filename)[0] + '.xml')
            if not os.path.isfile(xml_path):
                print('{} :: annotations xml file not found: {}'.format(
                    filename, xml_path))
                continue
            xml_reader = PascalVocReader(xml_path)
            shapes = xml_reader.getShapes()
            n_shapes = len(shapes)

            if n_shapes != n_bboxes:
                raise IOError(
                    'Mismatch between n_bboxes in xml: {} and csv: {}'.format(
                        n_shapes, n_bboxes))

        for box_id in range(n_bboxes):

            bbox = multiple_instance.iloc[box_id]
            try:
                target_id = bbox['target_id']
            except KeyError:
                target_id = generic_target_id
                generic_target_id -= 1

            xmin = bbox.loc['xmin']
            ymin = bbox.loc['ymin']
            xmax = bbox.loc['xmax']
            ymax = bbox.loc['ymax']
            class_name = bbox.loc['class']

            try:
                class_id = class_dict[str(class_name)]
            except KeyError:
                print('Ignoring annotation with invalid class: {}'.format(
                    class_name))
                continue

            width = xmax - xmin
            height = ymax - ymin

            curr_frame_data = [
                frame_id, target_id, xmin, ymin, width, height, class_id
            ]

            if enable_masks:
                mask = shapes[box_id][-2]
                if mask is not None:
                    _contour_pts = Shape.getContourPts(mask)
                    masks.append(_contour_pts)

            frame_data.append(curr_frame_data)

        frame_data = np.asarray(frame_data)
        res = visualizer.update(frame_id, curr_frame, frame_data, masks, label,
                                crop_size)
        if generator_mode:
            yield res
        # elif not res:
        #     break

    _quit = visualizer._quit
    _pause = visualizer._pause

    visualizer.close()
    frames_reader.close()
Esempio n. 11
0
    printname=Path(name).stem





    xmlfilepath=PurePath(inputpath, filexml)
    jpgfilepath=PurePath(outputpath, filename)

    pngfilepath=PurePath(outputpath, filepng)


    print("XML file %s" % xmlfilepath)

    reader = PascalVocReader(xmlfilepath)
    shapes = reader.getShapes()
    print(reader.verified)

    print(shapes)
    print(len(shapes))

    #[('salmon', [(1, 262), (337, 262), (337, 588), (1, 588)], None, None, True)]
    # Scale font to picture but anything smaller than 0.55 is not readable
    font_scale=max(float(cols/1000),0.55)
    #fontsize=float(cols/1000)
    text_offset_x=int(cols/40)
    text_offset_y=int(rows/40) + 10
    #linesize=1
    font = cv.FONT_HERSHEY_PLAIN
    #double scale = 0.4;
    filenames = sorted(glob.glob(IN_DIR + "/*.png"))

    count = 0

    for filename in filenames:
        xmlName = filename[:-4] + ".xml"
        basename = os.path.basename(filename)
        dirname = os.path.basename(os.path.dirname(filename))

        if (not os.path.exists(TRAIN_OUT_DIR + dirname)):
            os.makedirs(TRAIN_OUT_DIR + dirname)
        if (not os.path.exists(VALID_OUT_DIR + dirname)):
            os.makedirs(VALID_OUT_DIR + dirname)

        src = cv2.imread(filename)
        xmlReader = PascalVocReader(xmlName)
        shapes = xmlReader.getShapes()

        xmin = src.shape[1]
        ymin = src.shape[0]
        xmax = 0
        ymax = 0

        for i in range(len(shapes)):
            if (xmin > shapes[i][1][0][0]):
                xmin = shapes[i][1][0][0]
            if (ymin > shapes[i][1][0][1]):
                ymin = shapes[i][1][0][1]
            if (xmax < shapes[i][1][2][0]):
                xmax = shapes[i][1][2][0]
            if (ymax < shapes[i][1][2][1]):
Esempio n. 13
0
def loadPascalXMLByFilename(xmlPath):
    tVocParseReader = PascalVocReader(xmlPath)
    shapes = tVocParseReader.getShapes()
    return shapes
Esempio n. 14
0
    def run(self):

        xmls = []
        for index, (dirpath, dirnames,
                    filenames) in enumerate(os.walk(self.dir)):
            xmls.extend(
                list(
                    map(
                        lambda s: os.path.join(dirpath, s),
                        filter(lambda s: True
                               if s.endswith(".xml") else False, filenames))))

        easy_track_df = pd.DataFrame()
        for xml in xmls:
            tVocParseReader = PascalVocReader(xml)
            shapes = tVocParseReader.getShapes()

            xmlfilename = os.path.basename(xml)
            *dir_, _ = xml.split('_')
            dir_ = os.path.basename("_".join(dir_)) if isinstance(
                dir_, (list, tuple)) else os.path.basename(dir_)

            i_easytrack = 0
            for shape in shapes:
                shapeType, label, points, _, _, difficult = shape
                if label not in self.labelHist:
                    easy_track_df = easy_track_df.append(
                        [{
                            'subdir': dir_,
                            'xmlfilename': xmlfilename,
                            'index': i_easytrack,
                            'label': label,
                            'shapeType': shapeType,
                            'points': points,
                            'difficult': difficult
                        }],
                        ignore_index=True)
                    i_easytrack += 1

        easy_track_df.sort_values(
            by=["subdir", "xmlfilename", "label"]).reindex(
                range(len(easy_track_df)))

        ShapeObj = namedtuple('ShapeObj', ['subdir', 'label', 'shape'])
        shape_obj_list = []
        shape_obj_dict_list = []

        subdirs = sorted(list(easy_track_df.subdir.value_counts().keys()))

        for i_subdir, subdir in enumerate(subdirs):
            tmp_sub_df = easy_track_df[easy_track_df["subdir"] ==
                                       subdir].sort_values(by="label")
            shape_obj_list_tmp = []

            for i, row in tmp_sub_df.iterrows():
                subdir = row.subdir
                xmlfilename = row.xmlfilename
                shapeType = row.shapeType
                label = row.label.lower().strip()
                points = row.points
                difficult = row.difficult
                shapeFac = shapeFactory()
                shapeFac.setType(shapeType)
                shape = shapeFac.getShape()
                shape.points = [QPointF(*xy) for xy in points]
                shape.label = label
                shape.difficult = difficult
                shape.close()

                shape_obj = ShapeObj(subdir, label, shape)
                shape_obj_list_tmp.append(shape_obj)

            shape_obj_dict = OrderedDict()
            for shape in shape_obj_list_tmp:
                just_found_one = False
                key = " "
                if " " not in shape.label:
                    key = shape.label
                    shape_obj_dict[key] = []
                    just_found_one = True
                if shape.label.split(" ", 1)[0] in shape_obj_dict.keys():
                    if not just_found_one:
                        shape_obj_dict[shape.label.split(" ",
                                                         1)[0]].append(shape)

            # 去除字典中小于1个的情况
            to_del = []
            for key, value in shape_obj_dict.items():
                if len(value) <= 1:
                    to_del.append(key)
            for key in to_del:
                shape_obj_dict.pop(key)

            shape_obj_list.extend(shape_obj_list_tmp)
            shape_obj_dict_list.append(shape_obj_dict)

        broken_info_dict = defaultdict(list)
        for shape_obj_dict_tmp in shape_obj_dict_list:
            for _, shape_objs in shape_obj_dict_tmp.items():
                n_break = len(shape_objs)
                diameters = tuple(shape_obj.shape.getDiameter()
                                  for shape_obj in shape_objs)
                if n_break in broken_info_dict.keys():
                    broken_info_dict[n_break].append(diameters)
                else:
                    broken_info_dict[n_break] = [diameters]

        def genSheetname(s):
            return "broken {}".format(s)

        def genColname(i):
            return "diameter {}".format(i + 1)

        df_dict = dict()
        for key, value in broken_info_dict.items():
            columns = [genColname(i) for i in range(key)]  # range(len(value))
            df = pd.DataFrame(value, columns=columns)
            df['diameter of mother drop'] = reduce(
                lambda x, y: (x**3 + y**3)**(1 / 3),
                [df[col] for col in columns])
            columns_frac = [col + " frac" for col in columns]
            for col in columns_frac:
                df[col] = df[
                    col[:-len(" frac")]]**3 / df['diameter of mother drop']**3

            df_dict[key] = df

        summary_df_data = []
        for i_df, df in df_dict.items():
            columns = [genColname(i) for i in range(i_df)]
            for i, row in df.iterrows():
                drops = list(row[columns])
                assert (len(drops) == i_df)
                drops.sort()
                mother_drops = [0 for _ in range(len(drops))]
                mother_drops[0] = drops[0]
                for i in range(len(drops) - 1):
                    drop_1 = mother_drops[i]
                    drop_2 = drops[i + 1]
                    mother_drops[i + 1] = (drop_1**3 + drop_2**3)**(1 / 3)
                    drop_1_frac = drop_1**3 / mother_drops[i + 1]**3
                    drop_2_frac = drop_2**3 / mother_drops[i + 1]**3
                    n_breakage = i_df
                    summary_df_data.append(
                        (drop_1, drop_2, mother_drops[i + 1], drop_1_frac,
                         drop_2_frac, n_breakage))
        summary_df = pd.DataFrame(summary_df_data,
                                  columns=[
                                      'drop_1', 'drop_2', 'mothoer_drop',
                                      'drop_1_frac', "drop_2_frac",
                                      "n_breakage"
                                  ])

        filename = os.path.join(
            os.path.dirname(self.dir),
            "summary-{}.xlsx".format(os.path.basename(self.dir)))
        writer = pd.ExcelWriter(filename)
        for i_df, df in df_dict.items():
            df.to_excel(writer, genSheetname(i_df))
        summary_df.to_excel(writer, "summary")
        writer.save()

        text = "\n".join([
            "# {i}-elem break: {num}".format(
                i=str(i).rjust(2), num=str(len(broken_info_dict[i])).rjust(3))
            for i in range(2, 11)
        ])
        text += "\n" + "# total: {total}".format(total=len(summary_df))
        self.finished.emit(text)
Esempio n. 15
0
def saveMasks(seq_path,
              xml_path,
              out_mask_size,
              out_border,
              fixed_ar,
              save_raw_mask,
              show_img,
              out_root_path='',
              save_test=1,
              save_train=1,
              frames_reader=None,
              masks_per_seq=0,
              enable_out_suffix=1,
              train_fnames=None,
              test_fnames=None,
              map_to_bbox=0,
              out_img_dir='',
              enable_xml_annotations=0,
              allow_skipping_images=0):
    global _pause, _exit

    if not xml_path or not os.path.isdir(xml_path):
        raise IOError(
            'Folder containing the loaded boxes does not exist: {}'.format(
                xml_path))

    files = glob.glob(os.path.join(xml_path, '*.xml'))
    n_files = len(files)
    if n_files == 0:
        raise IOError('No loaded boxes found')

    if frames_reader is None:
        frames_reader = get_frames_reader(seq_path, save_as_bin=False)

    min_dim = max_dim = 0
    out_w, out_h = out_mask_size
    print('out_mask_size: {}'.format(out_mask_size))

    if out_w == -1 and out_h == -1:
        out_w = out_h = 0

    if out_w == -1:
        max_dim = out_h
    elif out_h == -1:
        min_dim = out_w

    if fixed_ar:
        print('Using fixed aspect ratio: {}'.format(fixed_ar))

    print('out_border: {}'.format(out_border))

    def getint(fn):
        basename = os.path.basename(fn)
        num = re.sub("\D", "", basename)
        try:
            return int(num)
        except:
            return 0

    if len(files) > 0:
        files = sorted(files, key=getint)

    print('Loading annotations from {:d} files'.format(n_files))
    file_id = 0
    n_boxes = 0

    seq_root_dir = os.path.dirname(seq_path)
    seq_name = os.path.basename(seq_path)
    if not out_root_path:
        out_root_path = os.path.join(seq_root_dir, 'masks')

    if not enable_out_suffix:
        out_seq_name = seq_name
    else:
        if map_to_bbox:
            out_seq_name = '{}_mapped'.format(seq_name)
        else:
            out_seq_name = '{}_{}x{}'.format(seq_name, out_w, out_h)
            if fixed_ar:
                out_seq_name = '{}_ar_{}'.format(out_seq_name, fixed_ar)
            else:
                out_seq_name = '{}_{}'.format(out_seq_name, out_border)

        out_seq_name = out_seq_name.replace('.', 'p')

    train_root_path = os.path.join(out_root_path, out_seq_name)

    if not save_test and not save_train:
        raise AssertionError('Either save_test or save_train must be on')

    # print('Saving output sequences to  {}'.format(out_root_path))

    if save_train:
        out_img_root_path = train_root_path
        if out_img_dir:
            out_img_root_path = os.path.join(out_img_root_path, out_img_dir)

        out_mask_root_path = os.path.join(train_root_path, 'labels')
        print('Saving training mask sequence to {}'.format(train_root_path))

        if not os.path.isdir(out_img_root_path):
            os.makedirs(out_img_root_path)

        if not os.path.isdir(out_mask_root_path):
            os.makedirs(out_mask_root_path)

        if enable_xml_annotations:
            out_xml_path = os.path.join(out_img_root_path, 'annotations')
            print('Saving xml_annotations to {}'.format(out_xml_path))
            if not os.path.isdir(out_xml_path):
                os.makedirs(out_xml_path)

    if save_test:
        out_test_seq_name = out_seq_name + '_test'
        test_img_root_path = os.path.join(out_root_path, out_test_seq_name)

        print('Saving unlabeled testing mask sequence to {}'.format(
            test_img_root_path))
        if not os.path.isdir(test_img_root_path):
            os.makedirs(test_img_root_path)

    win_name = 'patch and mask'

    disable_resizing = 0
    scale_x = scale_y = 1.0
    if out_w == 0 and out_h == 0:
        print('Resizing disabled')
        disable_resizing = 1

    csv_raw = []
    test_csv_raw = []

    n_files = len(files)

    if save_raw_mask:
        print('Saving raw labels')
        mask_pix_val = (1, 1, 1)
    else:
        mask_pix_val = (255, 255, 255)

    n_masks = 0

    _train_fnames = []
    _test_fnames = []

    _exit_seq = 0

    disp_img = None

    for file_id, file in enumerate(files):
        xml_reader = PascalVocReader(file)
        filename = os.path.basename(xml_reader.filename)
        filename_no_ext = os.path.splitext(filename)[0]
        # file_id = int(re.sub("\D", "", filename))

        # print('filename: {}'.format(filename))
        # print('file_id: {}'.format(file_id))

        img = frames_reader.get_frame_by_name(filename, convert_to_rgb=0)
        if img is None:
            print('image {} could not be read'.format(filename))
            continue

        img_h, img_w = img.shape[:2]

        mask_img = None

        shapes = xml_reader.getShapes()
        n_shapes = len(shapes)
        if n_shapes > 1:
            print('{} boxes found for {} in {}'.format(n_shapes, filename,
                                                       file))

        obj_id = 0

        img_written = 0
        for shape in shapes:
            label, points, _, _, difficult, bbox_source, id_number, score, mask, mask_img = shape
            if not mask:
                if not save_test:
                    continue

                xmin, ymin = points[0]
                xmax, ymax = points[2]
                img_root_path = test_img_root_path
            else:

                if not save_train:
                    continue

                mask_pts_list = Shape.getContourPts(mask, verbose=0)

                mask_pts = np.asarray(mask_pts_list)
                xmin, ymin = np.min(mask_pts, axis=0).astype(np.int32)
                xmax, ymax = np.max(mask_pts, axis=0).astype(np.int32)

                img_root_path = out_img_root_path

            if fixed_ar:
                w, h = xmax - xmin, ymax - ymin
                src_ar = float(w) / float(h)
                if fixed_ar > src_ar:
                    border_x = int((h * fixed_ar - w) / 2.0)
                    border_y = 0
                else:
                    border_y = int((w / fixed_ar - h) / 2.0)
                    border_x = 0
            else:
                border_x = border_y = out_border

            # start_row, start_col = max(0, ymin - border_y), max(0, xmin - border_x)
            # end_row, end_col = min(img_h - 1, ymax + border_y), min(img_w - 1, xmax + border_x)

            start_row, start_col = ymin - border_y, xmin - border_x
            end_row, end_col = ymax + border_y, xmax + border_x

            if start_row < 0 or start_col < 0 or end_row >= img_h or end_col >= img_w:
                msg = 'Invalid border {} for box {} in image {} of size {}'.format(
                    [border_x, border_y], [xmin, ymin, xmax, ymax], filename,
                    [img_w, img_h])
                if allow_skipping_images:
                    print('\n' + msg + '\n')
                    continue
                else:
                    raise AssertionError(msg)

            if mask:
                n_masks += 1

            w, h = end_col - start_col, end_row - start_row
            patch_img = img[start_row:end_row, start_col:end_col, :]

            if not disable_resizing:
                if max_dim > 0:
                    if w > h:
                        out_w = max_dim
                        out_h = 0
                    else:
                        out_h = max_dim
                        out_w = 0
                elif min_dim > 0:
                    if w < h:
                        out_w = min_dim
                        out_h = 0
                    else:
                        out_h = min_dim
                        out_w = 0
                else:
                    out_w, out_h = out_mask_size

                scale_x = float(out_w) / float(w)
                scale_y = float(out_h) / float(h)
                if scale_x == 0:
                    scale_x = scale_y
                    out_w = int(w * scale_x)
                elif scale_y == 0:
                    scale_y = scale_x
                    out_h = int(h * scale_y)
                try:
                    patch_img = cv2.resize(patch_img, (out_w, out_h))
                    # print('patch_img: {}'.format(patch_img.shape))
                except cv2.error as e:
                    print('patch_img: {}'.format(patch_img.shape))
                    print('out_size: {}, {}'.format(start_row, start_col))
                    print('out_size: {}, {}'.format(end_row, end_col))
                    print('out_size: {}, {}'.format(out_w, out_h))
                    raise cv2.error(e)
            else:
                out_w, out_h = w, h

            _label = label
            if id_number is None:
                id_number = -1
            if id_number > 0:
                _label = '{}_{}'.format(_label, id_number)

            if enable_out_suffix:
                out_fname = '{}_{}_{}'.format(filename_no_ext, obj_id, label)
            else:
                out_fname = filename_no_ext

            _xmin, _ymin = int((xmin - start_col) * scale_x), int(
                (ymin - start_row) * scale_y)
            _xmax, _ymax = int((xmax - start_col) * scale_x), int(
                (ymax - start_row) * scale_y)

            if map_to_bbox:
                if not img_written:
                    img_written = 1
                    out_img_path = os.path.join(img_root_path, filename)
                    cv2.imwrite(out_img_path, img)
                    if enable_xml_annotations:
                        imageShape = [xml_reader.height, xml_reader.width, 3]
                        xml_writer = PascalVocWriter(out_xml_path, filename,
                                                     imageShape)

                if mask:
                    if enable_xml_annotations:
                        bndbox = [xmin, ymin, xmax, ymax]
                        xml_writer.addBndBox(bndbox[0], bndbox[1], bndbox[2],
                                             bndbox[3], label, difficult,
                                             bbox_source, id_number, score,
                                             mask, mask_img)

                raw_data = {
                    'target_id': int(id_number),
                    'filename': filename,
                    'width': img_w,
                    'height': img_h,
                    'class': label,
                    'xmin': xmin,
                    'ymin': ymin,
                    'xmax': xmax,
                    'ymax': ymax
                }

                if show_img:
                    cv2.rectangle(img, (xmin, ymin), (xmax, ymax), (0, 255, 0),
                                  2)
                    disp_img = img
            else:
                img_out_fname = out_fname + '.jpg'
                if mask:
                    out_img_path = os.path.join(img_root_path, img_out_fname)
                    cv2.imwrite(out_img_path, patch_img)

                    if enable_xml_annotations:
                        n_mask = len(mask)

                        _mask = []
                        for i in range(n_mask):
                            _mask.append([(mask[i][0] - start_col) * scale_x,
                                          (mask[i][1] - start_row) * scale_y,
                                          mask[i][2]])

                        imageShape = [xml_reader.height, xml_reader.width, 3]
                        xml_writer = PascalVocWriter(out_xml_path,
                                                     xml_reader.filename,
                                                     imageShape)
                        bndbox = [_xmin, _ymin, _xmax, _ymax]
                        xml_writer.addBndBox(_xmin, _ymin, _xmax, _ymax, label,
                                             difficult, bbox_source, id_number,
                                             score, _mask)
                raw_data = {
                    'target_id': int(id_number),
                    'filename': img_out_fname,
                    'width': out_w,
                    'height': out_h,
                    'class': label,
                    'xmin': _xmin,
                    'ymin': _ymin,
                    'xmax': _xmax,
                    'ymax': _ymax
                }

                if show_img:
                    cv2.rectangle(patch_img, (_xmin, _ymin), (_xmax, _ymax),
                                  (0, 255, 0), 2)
                    disp_img = patch_img

            if mask:
                if mask_img is None:
                    mask_img = np.zeros_like(img)
                # print('border_x: {}'.format(border_x))
                # print('border_y: {}'.format(border_y))
                # print('scale_x: {}'.format(scale_x))
                # print('scale_y: {}'.format(scale_y))
                #
                # print('xmin: {}'.format(xmin))
                # print('ymin: {}'.format(ymin))

                mask_pts = [[(x - xmin + border_x) * scale_x,
                             (y - ymin + border_y) * scale_y]
                            for x, y in mask_pts]
                curr_mask = np.zeros_like(patch_img, dtype=np.uint8)
                # print('mask_img: {}'.format(mask_img.shape))
                mask_out_fname = out_fname + '.png'

                # np.savetxt('mask_seq_mask_pts.txt', mask_pts, fmt='%.6f')

                curr_mask = cv2.fillPoly(
                    curr_mask, np.array([
                        mask_pts,
                    ], dtype=np.int32), mask_pix_val)

                # print('min: {} max: {}'.format(
                #     np.min(mask_img.flatten()),
                #     np.max(mask_img.flatten()))
                # )

                if map_to_bbox:
                    mask_img = map_mask_to_bbox(
                        (xmin, ymin, xmax, ymax), curr_mask, fixed_ar,
                        out_border, mask_img.shape, mask_img)
                else:
                    mask_img = curr_mask
                    out_mask_path = os.path.join(out_mask_root_path,
                                                 mask_out_fname)
                    cv2.imwrite(out_mask_path, mask_img)

                    _train_fnames.append((out_img_path, out_mask_path))

                    if show_img:
                        disp_mask_img = mask_img.copy()
                        if save_raw_mask:
                            disp_mask_img[disp_mask_img > 0] = 255
                        blended_img = np.asarray(
                            Image.blend(Image.fromarray(patch_img),
                                        Image.fromarray(disp_mask_img), 0.5))
                        disp_img = np.concatenate(
                            (disp_img, disp_mask_img, blended_img), axis=1)
                csv_raw.append(raw_data)
            else:
                test_csv_raw.append(raw_data)
                if not map_to_bbox:
                    _test_fnames.append(out_img_path)

            if show_img and not map_to_bbox:
                # if _pause:
                #     print('frame {} :: {}'.format(file_id, filename))
                cv2.imshow(win_name, disp_img)
                k = cv2.waitKey(1 - _pause)
                if k == ord('q'):
                    _exit = 1
                    break
                elif k == 27:
                    _exit_seq = 1
                    break
                elif k == 32:
                    _pause = 1 - _pause
            obj_id += 1

        if map_to_bbox and img is not None:
            out_img_path = os.path.join(out_img_root_path, filename)
            if save_train and mask_img is not None:
                mask_out_fname = filename_no_ext + '.png'
                out_mask_path = os.path.join(out_mask_root_path,
                                             mask_out_fname)
                cv2.imwrite(out_mask_path, mask_img)

                if enable_xml_annotations:
                    out_xml_file = os.path.join(out_xml_path,
                                                os.path.basename(file))
                    xml_writer.save(targetFile=out_xml_file)

                _train_fnames.append((out_img_path, out_mask_path))

                if show_img:
                    disp_mask_img = mask_img
                    if save_raw_mask:
                        disp_mask_img[disp_mask_img > 0] = 255
                    blended_img = np.asarray(
                        Image.blend(Image.fromarray(img),
                                    Image.fromarray(disp_mask_img), 0.5))
                    disp_img = np.concatenate(
                        (disp_img, disp_mask_img, blended_img), axis=1)

            elif save_test:
                out_img_path = os.path.join(test_img_root_path, filename)
                if out_img_path in _test_fnames:
                    raise IOError(
                        'Duplicate out_img_path: {}'.format(out_img_path))
                _test_fnames.append(out_img_path)

            if show_img and disp_img is not None:
                cv2.imshow(win_name, disp_img)
                k = cv2.waitKey(1 - _pause)
                if k == ord('q'):
                    _exit = 1
                    break
                elif k == 27:
                    break
                elif k == 32:
                    _pause = 1 - _pause
        if _exit:
            break

        sys.stdout.write(
            '\rDone {:d}/{:d} files {:s} ({:d} masks found)'.format(
                file_id + 1, n_files, filename, n_masks))
        sys.stdout.flush()

        if masks_per_seq > 0 and n_masks >= masks_per_seq:
            break

    sys.stdout.write('\n')
    sys.stdout.flush()

    if not _exit_seq and save_train and n_masks == 0:
        raise IOError('\nNo masks found for {}\n'.format(seq_path))

    train_csv_path = test_csv_path = ''
    if csv_raw:
        print('Saved {} labeled files in training sequence'.format(
            len(csv_raw)))
        train_csv_path = os.path.join(out_img_root_path, 'annotations.csv')
        pd.DataFrame(csv_raw).to_csv(train_csv_path)
    if test_csv_raw:
        print('Saved {} unlabeled files in test sequence'.format(
            len(test_csv_raw)))
        test_csv_path = os.path.join(test_img_root_path, 'annotations.csv')
        pd.DataFrame(test_csv_raw).to_csv(test_csv_path)

    if show_img:
        cv2.destroyWindow(win_name)

    if save_train and train_fnames is not None:
        train_fnames[
            out_seq_name] = _train_fnames, train_root_path, csv_raw, train_csv_path

    if save_test and test_fnames is not None:
        test_fnames[
            out_test_seq_name] = _test_fnames, test_img_root_path, test_csv_raw, test_csv_path

    return n_masks
Esempio n. 16
0
def saveBoxesTXT(_type, voc_path, class_dict, out_dir=''):
    if _type == 0:
        _type_str = 'mAP'
    else:
        _type_str = 'yolo'

    if not voc_path or not os.path.isdir(voc_path):
        print('Folder containing the loaded boxes does not exist')
        return None

    files = glob.glob(os.path.join(voc_path, '*.xml'))
    n_files = len(files)
    if n_files == 0:
        print('No loaded boxes found')
        return None

    def convert_to_yolo(size, box):
        dw = 1. / size[0]
        dh = 1. / size[1]
        x = (box[0] + box[1]) / 2.0
        y = (box[2] + box[3]) / 2.0
        w = box[1] - box[0]
        h = box[3] - box[2]
        x = x * dw
        w = w * dw
        y = y * dh
        h = h * dh
        return x, y, w, h

    def getint(fn):
        basename = os.path.basename(fn)
        num = re.sub("\D", "", basename)
        try:
            return int(num)
        except:
            return 0

    if len(files) > 0:
        files = sorted(files, key=getint)

    if not out_dir:
        out_dir = os.path.join(os.path.dirname(voc_path), _type_str)
    if not os.path.isdir(out_dir):
        os.makedirs(out_dir)

    list_file = None
    if _type == 1:
        list_path = os.path.join(out_dir, 'list.txt')
        list_file = open(list_path, 'w')

    print('Loading VOC annotations from {:d} files at {:s}...'.format(n_files, voc_path))
    print('Writing {} annotations to {:s}...'.format(_type_str, out_dir))

    file_id = 0
    n_boxes = 0
    for file in files:
        file_no_ext = os.path.splitext(os.path.basename(file))[0]

        out_file_path = os.path.join(out_dir, '{}.txt'.format(file_no_ext))
        out_file = open(out_file_path, 'w')

        xml_reader = PascalVocReader(file)
        shapes = xml_reader.getShapes()

        img_width = xml_reader.width
        img_height = xml_reader.height

        for shape in shapes:
            label, points, _, _, difficult, bbox_source, id_number, score, _, _ = shape

            xmin, ymin = points[0]
            xmax, ymax = points[2]

            def clamp(x, min_value=0.0, max_value=1.0):
                return max(min(x, max_value), min_value)

            xmin = int(clamp(xmin, 0, img_width-1))
            xmax = int(clamp(xmax, 0, img_width-1))

            ymin = int(clamp(ymin, 0, img_height-1))
            ymax = int(clamp(ymax, 0, img_height-1))

            if _type == 0:
                out_file.write('{:s} {:d} {:d} {:d} {:d}\n'.format(label, xmin, ymin, xmax, ymax))
            else:
                class_id = class_dict[label] + 1
                bb = convert_to_yolo((xml_reader.width, xml_reader.height), [xmin, xmax, ymin, ymax])
                out_file.write('{:d} {:f} {:f} {:f} {:f}\n'.format(class_id, bb[0], bb[1], bb[2], bb[3]))
            if _type == 1:
                list_file.write('{:s}\n'.format(xml_reader.filename))
            n_boxes += 1

        file_id += 1
        sys.stdout.write('\rDone {:d}/{:d} files with {:d} boxes ({:d}x{:d})'.format(
            file_id, n_files, n_boxes, img_width, img_height))
        sys.stdout.flush()

        out_file.close()
    if _type == 1:
        list_file.close()

    sys.stdout.write('\n')
    sys.stdout.flush()

    return out_dir
Esempio n. 17
0
def saveBoxesCSV(seq_path,
                 voc_path,
                 sources_to_include,
                 enable_mask,
                 img_ext='jpg',
                 verbose=True):
    if not voc_path or not os.path.isdir(voc_path):
        raise IOError(
            'Folder containing the loaded boxes does not exist: {}'.format(
                voc_path))
        # return None

    # src_files = [os.path.join(seq_path, k) for k in os.listdir(seq_path) if
    #              os.path.splitext(k.lower())[1][1:] == img_ext]
    # src_files.sort(key=sortKey)

    # seq_name = os.path.basename(img_path)
    files = glob.glob(os.path.join(voc_path, '*.xml'))
    n_files = len(files)
    if n_files == 0:
        print('No loaded boxes found')
        return None

    def getint(fn):
        basename = os.path.basename(fn)
        num = re.sub("\D", "", basename)
        try:
            return int(num)
        except:
            return 0

    if len(files) > 0:
        files = sorted(files, key=getint)

    print('Loading annotations from {:d} files at {:s}...'.format(
        n_files, voc_path))

    file_id = 0
    n_boxes = 0
    csv_raw = []

    sources_to_exclude = [
        k[1:] for k in sources_to_include if k.startswith('!')
    ]
    sources_to_include = [
        k for k in sources_to_include if not k.startswith('!')
    ]

    if sources_to_include:
        print('Including only boxes from following sources: {}'.format(
            sources_to_include))
    if sources_to_exclude:
        print('Excluding boxes from following sources: {}'.format(
            sources_to_exclude))

    for file in files:
        xml_reader = PascalVocReader(file)
        shapes = xml_reader.getShapes()
        for shape in shapes:
            label, points, _, _, difficult, bbox_source, id_number, score, mask_pts, _ = shape

            if sources_to_include and bbox_source not in sources_to_include:
                continue

            if sources_to_exclude and bbox_source in sources_to_exclude:
                continue

            if id_number is None:
                id_number = -1

            xmin, ymin = points[0]
            xmax, ymax = points[2]

            filename = os.path.splitext(
                os.path.basename(file))[0] + '.{}'.format(img_ext)
            filename_from_xml = xml_reader.filename
            # if filename != filename_from_xml:
            #     sys.stdout.write('\n\nImage file name from xml: {} does not match the expected one: {}'.format(
            #         filename_from_xml, filename))
            #     sys.stdout.flush()

            raw_data = {
                'target_id': int(id_number),
                'filename': filename,
                'width': xml_reader.width,
                'height': xml_reader.height,
                'class': label,
                'xmin': int(xmin),
                'ymin': int(ymin),
                'xmax': int(xmax),
                'ymax': int(ymax)
            }
            if enable_mask:
                mask_txt = ''
                if mask_pts is not None and mask_pts:
                    mask_txt = '{},{};'.format(*(mask_pts[0][:2]))
                    for _pt in mask_pts[1:]:
                        mask_txt = '{}{},{};'.format(mask_txt, _pt[0], _pt[1])
                raw_data.update({'mask': mask_txt})
            csv_raw.append(raw_data)
            n_boxes += 1

        file_id += 1
        if verbose:
            sys.stdout.write('\rDone {:d}/{:d} files with {:d} boxes'.format(
                file_id, n_files, n_boxes))
            sys.stdout.flush()

    if verbose:
        sys.stdout.write('\n')
        sys.stdout.flush()

    df = pd.DataFrame(csv_raw)
    out_dir = os.path.dirname(voc_path)
    out_file_path = os.path.join(out_dir, 'annotations.csv')

    csv_columns = [
        'target_id', 'filename', 'width', 'height', 'class', 'xmin', 'ymin',
        'xmax', 'ymax'
    ]
    if enable_mask:
        csv_columns.append('mask')

    df.to_csv(out_file_path, columns=csv_columns)

    return out_file_path
Esempio n. 18
0
    def run(self):
        path = self.msg['path']
        frame_number = self.msg['frame_number']
        width = self.msg['width']
        height = self.msg['height']
        channel = self.msg['channel']
        bboxes = self.msg['bboxes']
        scores = self.msg['scores']
        labels = self.msg['labels']
        bbox_source = self.msg['bbox_source']
        id_numbers = self.msg['id_numbers']
        last_frame_number = self.msg['last_frame_number']
        trigger_tracking_request = self.msg['trigger_tracking_request']
        num_frames = self.msg['num_frames']
        new_box_from_pt = (bbox_source == 'single_object_tracker')
        num_new_bboxes = len(bboxes)

        if 'masks' in self.msg.keys():
            masks = self.msg['masks']
        else:
            masks = None
        trigger_batch_message = num_frames > 1
        if not self.main_window.frames_reader or os.path.abspath(
                path) != self.main_window.frames_reader.get_path():
            print("Incorrect path!")
            # send_self.msg_to_connection(dict(status="failure", error="Incorrect path!"), connection)
        else:
            if new_box_from_pt or self.save_boxes:
                xml_path = self.main_window.get_annotation_path(frame_number)
                if os.path.exists(xml_path):
                    try:
                        tVocParseReader = PascalVocReader(xml_path)
                        shapes = tVocParseReader.getShapes()
                    except:
                        shapes = []
                else:
                    shapes = []
                imageShape = [height, width, channel]
                if isinstance(self.main_window.frames_reader, DirectoryReader):
                    img_full_path = self.main_window.mImgList[frame_number]
                    folder_name = os.path.dirname(img_full_path)
                    file_name = os.path.basename(img_full_path)
                else:
                    folder_name = self.main_window.frames_reader.video_fn
                    file_name = str(frame_number)

                tVocWriter = PascalVocWriter(folder_name, file_name,
                                             imageShape)  #
                for label, points, _, _, difficult, _bbox_source, id_number, score, mask, mask_img in shapes:
                    existing_box_from_gt = _bbox_source == "ground_truth"
                    if new_box_from_pt and existing_box_from_gt and id_number == id_numbers[
                            0]:
                        print(
                            'Received duplicale target {:d} bbox for frame {:d} for which GT exists'
                            .format(id_numbers[0], frame_number))
                        return
                    bndbox = LabelFile.convertPoints2BndBox(points, label)
                    if existing_box_from_gt or _bbox_source != bbox_source or label == 'gate' or \
                            (_bbox_source == "single_object_tracker" and id_number != id_numbers[0]):
                        # Override previous bboxes from the same source
                        tVocWriter.addBndBox(bndbox[0], bndbox[1], bndbox[2],
                                             bndbox[3], label, difficult,
                                             _bbox_source, id_number, score,
                                             mask, mask_img)
                for j in range(num_new_bboxes):
                    bbox = bboxes[j]
                    xmin = bbox['xmin']
                    ymin = bbox['ymin']
                    xmax = bbox['xmax']
                    ymax = bbox['ymax']
                    label = labels[j]
                    score = scores[j]
                    difficulty = False
                    id_number = id_numbers[j]
                    if masks is not None:
                        # box_h = ymax - ymin
                        # box_w = xmax - xmin
                        # mask_img = np.array(masks[j]).reshape((box_h, box_w))
                        # mask_img = np.array(masks[j])
                        print('Loading mask from {:s}'.format(masks[j]))
                        # mask_img = cv2.imread(masks[j])
                        mask_img = np.load(masks[j])

                        if mask_img is None:
                            print('mask image could not be read')
                    else:
                        mask_img = None

                    tVocWriter.addBndBox(xmin, ymin, xmax, ymax, label,
                                         difficulty, bbox_source, id_number,
                                         score, None, mask_img)
                    # print('bbox: ', bbox)
                tVocWriter.save(targetFile=xml_path)

            if self.currIndex == frame_number:
                self.reload_signal.emit()
            if new_box_from_pt:
                print('Received target {:d} bbox for frame {:d}'.format(
                    id_numbers[0], frame_number))

            else:
                self.update_status_signal.emit(
                    "Received {:d} {:s} bboxes for frame {:d}.".format(
                        num_new_bboxes, bbox_source, frame_number))
            if last_frame_number == frame_number and not trigger_tracking_request:
                self.update_status_signal.emit(
                    "Running finished for {:d} frames.".format(num_frames))
                self.finish_signal.emit(trigger_batch_message)