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))
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
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
def loadPascalXMLByFilename(self, xmlPath): if self.filePath is None: return if os.path.isfile(xmlPath) is False: return tVocParseReader = PascalVocReader(xmlPath) shapes = tVocParseReader.shapes self.loadLabels(shapes) self.canvas.verified = tVocParseReader.verified
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
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
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
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
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]):
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
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)
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
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()
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)
def loadPascalXMLByFilename(xmlPath): tVocParseReader = PascalVocReader(xmlPath) shapes = tVocParseReader.getShapes() return shapes