def _classification_to_kwiver_detections(classification, w, h): """ Convert kwarray classifications to kwiver deteted object sets Args: classification (bioharn.clf_predict.Classification) w (int): width of image h (int): height of image Returns: kwiver.vital.types.DetectedObjectSet """ detected_objects = DetectedObjectSet() if classification.data.get('prob', None) is not None: # If we have a probability for each class, uses that class_names = list(classification.classes) class_prob = classification.prob detected_object_type = DetectedObjectType(class_names, class_prob) else: # Otherwise we only have the score for the predicted calss class_name = classification.classes[classification.cidx] class_score = classification.conf detected_object_type = DetectedObjectType(class_name, class_score) bounding_box = BoundingBoxD(0, 0, w, h) detected_object = DetectedObject(bounding_box, classification.conf, detected_object_type) detected_objects.add(detected_object) return detected_objects
def filter_truth(self, init_truth, categories): filtered_truth = DetectedObjectSet() use_frame = True max_length = int(self._max_scale_wrt_chip * float(self._chip_width)) for i, item in enumerate(init_truth): if item.type is None: continue class_lbl = item.type.get_most_likely_class() if categories is not None and not categories.has_class_name( class_lbl): if self._mode == "detection_refiner": class_lbl = self._negative_category else: continue if categories is not None: class_lbl = categories.get_class_name(class_lbl) elif class_lbl not in self._categories: self._categories.append(class_lbl) item.type = DetectedObjectType(class_lbl, 1.0) if self._mode == "detector" and \ ( item.bounding_box.width() > max_length or \ item.bounding_box.height() > max_length ): use_frame = False break filtered_truth.add(item) if self._gt_frames_only and len(init_truth) == 0: use_frame = False return filtered_truth, use_frame
def _kwimage_to_kwiver_detections(detections): """ Convert kwimage detections to kwiver deteted object sets Args: detected_objects (kwimage.Detections) Returns: kwiver.vital.types.DetectedObjectSet """ # convert segmentation masks if 'segmentations' in detections.data: print("Warning: segmentations not implemented") boxes = detections.boxes.to_tlbr() scores = detections.scores class_idxs = detections.class_idxs # convert to kwiver format, apply threshold detected_objects = DetectedObjectSet() for tlbr, score, cidx in zip(boxes.data, scores, class_idxs): class_name = detections.classes[cidx] bbox_int = np.round(tlbr).astype(np.int32) bounding_box = BoundingBox(bbox_int[0], bbox_int[1], bbox_int[2], bbox_int[3]) detected_object_type = DetectedObjectType(class_name, score) detected_object = DetectedObject(bounding_box, score, detected_object_type) detected_objects.add(detected_object) return detected_objects
def _create_object_track_set(self): bbox = BoundingBox(10, 10, 20, 20) dot = DetectedObjectType("test", 0.4) do = DetectedObject(bbox, 0.4, dot) track = Track() for i in range(10): track.append(ObjectTrackState(i, i, do)) return ObjectTrackSet([track])
def detect(self, in_img_c): import tensorflow as tf import humanfriendly image_height = in_img_c.height() image_width = in_img_c.width() if (self.norm_image_type and self.norm_image_type != "none"): print("Normalizing input image") in_img = in_img_c.image().asarray().astype("uint16") bottom, top = self.get_scaling_values(self.norm_image_type, in_img, image_height) in_img = self.lin_normalize_image(in_img, bottom, top) in_img = np.tile(in_img, (1, 1, 3)) else: in_img = np.array(get_pil_image(in_img_c.image()).convert("RGB")) start_time = time.time() boxes, scores, classes = self.generate_detection( self.detection_graph, in_img) elapsed = time.time() - start_time print("Done running detector in {}".format( humanfriendly.format_timespan(elapsed))) good_boxes = [] detections = DetectedObjectSet() for i in range(0, len(scores)): if (scores[i] >= self.confidence_thresh): bbox = boxes[i] good_boxes.append(bbox) top_rel = bbox[0] left_rel = bbox[1] bottom_rel = bbox[2] right_rel = bbox[3] xmin = left_rel * image_width ymin = top_rel * image_height xmax = right_rel * image_width ymax = bottom_rel * image_height dot = DetectedObjectType(self.category_name, scores[i]) obj = DetectedObject(BoundingBoxD(xmin, ymin, xmax, ymax), scores[i], dot) detections.add(obj) print("Detected {}".format(len(good_boxes))) return detections
def test_get_set_type(self): # Check default do = DetectedObject(self.bbox) nt.ok_(self.check_det_obj_types_equal(do.type, None)) # Check setting through setter do.type = self.dot nt.ok_(self.check_det_obj_types_equal(do.type, self.dot)) # Check setting through constructor new_dot = DetectedObjectType("other_example_class", -3.14) do = DetectedObject(self.bbox, classifications=new_dot) nt.ok_(self.check_det_obj_types_equal(do.type, new_dot))
def setUp(self): bbox = BoundingBox(10, 10, 20, 20) dot = DetectedObjectType("test", 0.4) do = DetectedObject(bbox, 0.4, dot) track = Track() for i in range(10): track.append(ObjectTrackState(i, i, do)) self.track_ = track self.time_1 = Timestamp() self.time_1.set_time_seconds(1234) self.time_2 = Timestamp() self.time_2.set_time_seconds(4321) self.obj_ts = ObjectTrackSet([self.track_]) self.act_type = ActivityType("self_act", 0.87) self.act = Activity(1, "self_act", 0.87, self.act_type, self.time_1, self.time_2, self.obj_ts)
def _dowork(self, img_container): """ Helper to decouple the algorithm and pipeline logic CommandLine: xdoctest viame.processes.camtrawl.processes CamtrawlDetectFishProcess._dowork Example: >>> from viame.processes.camtrawl.processes import * >>> from kwiver.vital.types import ImageContainer >>> import kwiver.sprokit.pipeline.config >>> # construct dummy process instance >>> conf = kwiver.sprokit.pipeline.config.empty_config() >>> self = CamtrawlDetectFishProcess(conf) >>> self._configure() >>> # construct test data >>> from vital.util import VitalPIL >>> from PIL import Image as PILImage >>> pil_img = PILImage.open(ub.grabdata('https://i.imgur.com/Jno2da3.png')) >>> pil_img = PILImage.fromarray(np.zeros((512, 512, 3), dtype=np.uint8)) >>> img_container = ImageContainer(VitalPIL.from_pil(pil_img)) >>> # Initialize the background detector by sending 10 black frames >>> for i in range(10): >>> empty_set = self._dowork(img_container) >>> # now add a white box that should be detected >>> np_img = np.zeros((512, 512, 3), dtype=np.uint8) >>> np_img[300:340, 220:380] = 255 >>> img_container = ImageContainer.fromarray(np_img) >>> detection_set = self._dowork(img_container) >>> assert len(detection_set) == 1 >>> obj = detection_set[0] """ # This should be read as np.uint8 np_img = img_container.asarray() detection_set = DetectedObjectSet() ct_detections = self.detector.detect(np_img) for detection in ct_detections: bbox = BoundingBoxD(*detection.bbox.coords) mask = detection.mask.astype(np.uint8) vital_mask = ImageContainer.fromarray(mask) dot = DetectedObjectType("Motion", 1.0) obj = DetectedObject(bbox, 1.0, dot, mask=vital_mask) detection_set.add(obj) return detection_set
def _step(self): image_container = self.grab_input_using_trait("image") timestamp = self.grab_input_using_trait("timestamp") file_name = self.grab_input_using_trait("file_name") image = image_container.asarray() h, w, _ = image.shape bbox_x = w//2 bbox_y = h//2 bbox = BoundingBox( bbox_x - int(self.config_value("bbox_width"))//2, bbox_y - int(self.config_value("bbox_height"))//2, bbox_x + int(self.config_value("bbox_width"))//2, bbox_y + int(self.config_value("bbox_height"))//2 ) dot = DetectedObjectType("Test", 1.0) do = DetectedObject(bbox, 1.0, dot) dos = DetectedObjectSet() dos.add(do) self.push_to_port_using_trait("detected_object_set", dos)
def merge(self, det_sets): # Get detection HL info in a list pred_sets = [] for det_set in det_sets: pred_set = [] for det in det_set: # Extract box info for this det bbox = det.bounding_box bbox_min_x = int(bbox.min_x()) bbox_max_x = int(bbox.max_x()) bbox_min_y = int(bbox.min_y()) bbox_max_y = int(bbox.max_y()) # Extract type info for this det if det.type is None: continue #class_names = list( det.type.class_names() ) #class_scores = [ det.type.score( n ) for n in class_names ] class_name = det.type.get_most_likely_class() class_score = det.type.score(class_name) pred_set.append([ bbox_min_x, bbox_min_y, bbox_max_x, bbox_max_y, class_name, class_score ]) pred_sets.append(pred_set) # Run merging algorithm #ensemble_preds = ensemble_box( preds_set, self._fusion_weights, # self._iou_thr, self._skip_box_thr, self._sigma, self._fusion_type ) ensemble_preds = [] # Compile output detections output = DetectedObjectSet() for pred in ensemble_preds: score = pred[5] bbox = BoundingBoxD(pred[0], pred[1], pred[2], pred[3]) dot = DetectedObjectType(pred[4], score) det = DetectedObject(bbox, score, dot) output.add(det) return output
def _kwimage_to_kwiver_detections(detections): """ Convert kwimage detections to kwiver deteted object sets Args: detected_objects (kwimage.Detections) Returns: kwiver.vital.types.DetectedObjectSet """ from kwiver.vital.types.types import ImageContainer, Image segmentations = None # convert segmentation masks if 'segmentations' in detections.data: segmentations = detections.data['segmentations'] boxes = detections.boxes.to_tlbr() scores = detections.scores class_idxs = detections.class_idxs if not segmentations: # Placeholders segmentations = (None, ) * len(boxes) # convert to kwiver format, apply threshold detected_objects = DetectedObjectSet() for tlbr, score, cidx, seg in zip(boxes.data, scores, class_idxs, segmentations): class_name = detections.classes[cidx] bbox_int = np.round(tlbr).astype(np.int32) bounding_box = BoundingBoxD(bbox_int[0], bbox_int[1], bbox_int[2], bbox_int[3]) detected_object_type = DetectedObjectType(class_name, score) detected_object = DetectedObject(bounding_box, score, detected_object_type) if seg: mask = seg.to_relative_mask().numpy().data detected_object.mask = ImageContainer(Image(mask)) detected_objects.add(detected_object) return detected_objects
def setUp(self): self.loc1 = np.array([-73.759291, 42.849631]) self.loc2 = np.array([-149.484444, -17.619482]) self.bbox = BoundingBox(10, 10, 20, 20) self.conf = 0.5 self.dot = DetectedObjectType("example_class", 0.4) self.mask = ImageContainer(Image(1080, 720)) # Values to set outside of constructor self.geo_point = GeoPoint(self.loc1, geodesy.SRID.lat_lon_WGS84) self.index = 5 self.detector_name = "example_detector_name" self.descriptor = descriptor.new_descriptor(5) self.descriptor[:] = 10 self.note_to_add = "example_note" self.keypoint_to_add = Point2d() self.keypoint_to_add.value = self.loc2 self.keypoint_id = "example_keypoint_id"
def test_id(self): a = self.act self.assertEqual(a.id, 1) a.id = 10 self.assertEqual(a.id, 10) self.assertEqual(a.label, "self_act") a.label = "second_act" self.assertEqual(a.label, "second_act") self.assertEqual(a.activity_type.score("self_act"), 0.87) a.activity_type = ActivityType() self.assertEqual(a.confidence, 0.87) a.confidence = 1 self.assertEqual(a.confidence, 1) self.assertEqual(a.start_time.get_time_seconds(), 1234) tmp_time = Timestamp().set_time_seconds(1237) a.start_time = tmp_time self.assertEqual(a.start_time.get_time_seconds(), 1237) self.assertEqual(a.end_time.get_time_seconds(), 4321) tmp_time = Timestamp() tmp_time.set_time_seconds(4322) a.end_time = tmp_time self.assertEqual(a.end_time.get_time_seconds(), 4322) self.assertEqual(a.participants.all_frame_ids(), set(range(10))) bbox = BoundingBox(10, 10, 20, 20) dot = DetectedObjectType("test", 0.4) do = DetectedObject(bbox, 0.4, dot) track = Track() for i in range(5): track.append(ObjectTrackState(i, i, do)) new_t = track new_ots = ObjectTrackSet([new_t]) a.participants = new_ots self.assertEqual(a.participants.all_frame_ids(), set(range(5))) self.assertEqual(a.duration[0].get_time_seconds(), a.start_time.get_time_seconds()) self.assertEqual(a.duration[1].get_time_seconds(), a.end_time.get_time_seconds())
def detect(self, image_data): input_image = image_data.asarray().astype('uint8') if self._rgb_to_bgr: input_image = cv2.cvtColor(input_image, cv2.COLOR_RGB2BGR) from mmdet.apis import inference_detector detections = inference_detector(self._model, input_image) if isinstance(detections, tuple): bbox_result, segm_result = detections else: bbox_result, segm_result = detections, None if np.size(bbox_result) > 0: bboxes = np.vstack(bbox_result) else: bboxes = [] # convert segmentation masks masks = [] if segm_result is not None: segms = mmcv.concat_list(segm_result) inds = np.where(bboxes[:, -1] > score_thr)[0] for i in inds: masks.append(maskUtils.decode(segms[i]).astype(np.bool)) # collect labels labels = [ np.full(bbox.shape[0], i, dtype=np.int32) for i, bbox in enumerate(bbox_result) ] if np.size(labels) > 0: labels = np.concatenate(labels) else: labels = [] # convert to kwiver format, apply threshold output = DetectedObjectSet() for bbox, label in zip(bboxes, labels): class_confidence = float(bbox[-1]) if class_confidence < self._thresh: continue bbox_int = bbox.astype(np.int32) bounding_box = BoundingBoxD(bbox_int[0], bbox_int[1], bbox_int[2], bbox_int[3]) class_name = self._labels[label] detected_object_type = DetectedObjectType(class_name, class_confidence) detected_object = DetectedObject(bounding_box, np.max(class_confidence), detected_object_type) output.add(detected_object) if np.size(labels) > 0 and self._display_detections: mmcv.imshow_det_bboxes(input_image, bboxes, labels, class_names=self._labels, score_thr=self._thresh, show=True) return output
def refine(self, image_data, detections): if len(detections) == 0: return detections img = image_data.asarray().astype('uint8') predictor = self.predictor scale = 1.0 img_max_x = np.shape(img)[1] img_max_y = np.shape(img)[0] if self._target_type_scales: scale = self.compute_scale_factor(detections) if scale != 1.0: img_max_x = int(img_max_x * scale) img_max_y = int(img_max_y * scale) img = cv2.resize(img, (img_max_x, img_max_y)) # Extract patches for ROIs image_chips = [] detection_ids = [] for i, det in enumerate(detections): # Extract chip for this detection bbox = det.bounding_box bbox_min_x = int(bbox.min_x() * scale) bbox_max_x = int(bbox.max_x() * scale) bbox_min_y = int(bbox.min_y() * scale) bbox_max_y = int(bbox.max_y() * scale) if self._kwiver_config['chip_method'] == "fixed_width": chip_width = int(self._kwiver_config['chip_width']) half_width = int(chip_width / 2) bbox_min_x = int((bbox_min_x + bbox_max_x) / 2) - half_width bbox_min_y = int((bbox_min_y + bbox_max_y) / 2) - half_width bbox_max_x = bbox_min_x + chip_width bbox_max_y = bbox_min_y + chip_width if self._border_exclude > 0: if bbox_min_x <= self._border_exclude: continue if bbox_min_y <= self._border_exclude: continue if bbox_max_x >= img_max_x - self._border_exclude: continue if bbox_max_y >= img_max_y - self._border_exclude: continue else: if bbox_min_x < 0: bbox_min_x = 0 if bbox_min_y < 0: bbox_min_y = 0 if bbox_max_x > img_max_x: bbox_max_x = img_max_x if bbox_max_y > img_max_y: bbox_max_y = img_max_y bbox_area = (bbox_max_x - bbox_min_x) * (bbox_max_y - bbox_min_y) if self._area_lower_bound > 0 and bbox_area < self._area_lower_bound: continue if self._area_upper_bound > 0 and bbox_area > self._area_upper_bound: continue crop = img[bbox_min_y:bbox_max_y, bbox_min_x:bbox_max_x] image_chips.append(crop) detection_ids.append(i) # Run classifier on ROIs classifications = list(predictor.predict(image_chips)) # Put classifications back into detections output = DetectedObjectSet() for i, det in enumerate(detections): if len(detection_ids) == 0 or i != detection_ids[0]: output.add(det) continue new_class = classifications[0] if new_class.data.get('prob', None) is not None: # If we have a probability for each class, uses that class_names = list(new_class.classes) class_scores = list(new_class.prob) else: # Otherwise we only have the score for the predicted class class_names = [new_class.classes[new_class.cidx]] class_scores = [new_class.conf] if self._average_prior and det.type is not None: priors = det.type prior_names = priors.class_names() for name in prior_names: if name in class_names: class_scores[class_names.index(name)] += priors.score( name) else: class_names.append(name) class_scores.append(priors.score(name)) for i in range(len(class_scores)): class_scores[i] = class_scores[i] * 0.5 detected_object_type = DetectedObjectType(class_names, class_scores) det.type = detected_object_type output.add(det) detection_ids.pop(0) classifications.pop(0) return output
def create_detected_object_type(): return DetectedObjectType("Test", 0.25)
def extract_chips_for_dets(self, image_files, truth_sets): import cv2 output_files = [] output_dets = [] for i in range(len(image_files)): filename = image_files[i] groundtruth = truth_sets[i] detections = [] scale = 1.0 if self._target_type_scales: scale = self.compute_scale_factor(groundtruth) if len(groundtruth) > 0: img = cv2.imread(filename) if len(np.shape(img)) < 2: continue img_max_x = np.shape(img)[1] img_max_y = np.shape(img)[0] # Optionally scale image if scale != 1.0: img_max_x = int(scale * img_max_x) img_max_y = int(scale * img_max_y) img = cv2.resize(img, (img_max_x, img_max_y)) # Run optional background detector on data if self._detector_model: kw_image = Image(img) kw_image_container = ImageContainer(kw_image) detections = self._detector.detect(kw_image_container) if len(groundtruth) == 0 and len(detections) == 0: continue overlaps = np.zeros((len(detections), len(groundtruth))) det_boxes = [] for det in detections: bbox = det.bounding_box det_boxes.append((int(bbox.min_x()), int(bbox.min_y()), int(bbox.width()), int(bbox.height()))) for i, gt in enumerate(groundtruth): # Extract chip for this detection bbox = gt.bounding_box bbox_min_x = int(bbox.min_x() * scale) bbox_max_x = int(bbox.max_x() * scale) bbox_min_y = int(bbox.min_y() * scale) bbox_max_y = int(bbox.max_y() * scale) bbox_width = bbox_max_x - bbox_min_x bbox_height = bbox_max_y - bbox_min_y max_overlap = 0.0 for j, det in enumerate(det_boxes): # Compute overlap between detection and truth (det_min_x, det_min_y, det_width, det_height) = det # Get the overlap rectangle overlap_x0 = max(bbox_min_x, det_min_x) overlap_y0 = max(bbox_min_y, det_min_y) overlap_x1 = min(bbox_max_x, det_min_x + det_width) overlap_y1 = min(bbox_max_y, det_min_y + det_height) # Check if there is an overlap if overlap_x1 - overlap_x0 <= 0 or overlap_y1 - overlap_y0 <= 0: continue # If yes, calculate the ratio of the overlap det_area = float(det_width * det_height) gt_area = float(bbox_width * bbox_height) int_area = float( (overlap_x1 - overlap_x0) * (overlap_y1 - overlap_y0)) overlap = min(int_area / det_area, int_area / gt_area) overlaps[j, i] = overlap if overlap >= self._min_overlap_for_association and overlap > max_overlap: max_overlap = overlap bbox_min_x = det_min_x bbox_min_y = det_min_y bbox_max_x = det_min_x + det_width bbox_max_y = det_min_y + det_height bbox_width = det_width bbox_height = det_height if self._chip_method == "fixed_width": chip_width = int(self._chip_width) half_width = int(chip_width / 2) bbox_min_x = int( (bbox_min_x + bbox_max_x) / 2) - half_width bbox_min_y = int( (bbox_min_y + bbox_max_y) / 2) - half_width bbox_max_x = bbox_min_x + chip_width bbox_max_y = bbox_min_y + chip_width bbox_width = chip_width bbox_height = chip_width bbox_area = bbox_width * bbox_height if self._area_lower_bound > 0 and bbox_area < self._area_lower_bound: continue if self._area_upper_bound > 0 and bbox_area > self._area_upper_bound: continue if self._reduce_category and gt.type() and \ gt.type().get_most_likely_class() == self._reduce_category and \ random.uniform( 0, 1 ) < 0.90: continue if self._border_exclude > 0: if bbox_min_x <= self._border_exclude: continue if bbox_min_y <= self._border_exclude: continue if bbox_max_x >= img_max_x - self._border_exclude: continue if bbox_max_y >= img_max_y - self._border_exclude: continue crop = img[bbox_min_y:bbox_max_y, bbox_min_x:bbox_max_x] self._sample_count = self._sample_count + 1 crop_str = ('%09d' % self._sample_count) + ".png" new_file = os.path.join(self._chip_directory, crop_str) cv2.imwrite(new_file, crop) # Set new box size for this detection gt.bounding_box = BoundingBoxD(0, 0, np.shape(crop)[1], np.shape(crop)[0]) new_set = DetectedObjectSet() new_set.add(gt) output_files.append(new_file) output_dets.append(new_set) neg_count = 0 for j, det in enumerate(detections): if max(overlaps[j]) >= self._max_overlap_for_negative: continue bbox = det.bounding_box bbox_min_x = int(bbox.min_x()) bbox_max_x = int(bbox.max_x()) bbox_min_y = int(bbox.min_y()) bbox_max_y = int(bbox.max_y()) bbox_width = bbox_max_x - bbox_min_x bbox_height = bbox_max_y - bbox_min_y bbox_area = bbox_width * bbox_height if self._chip_method == "fixed_width": chip_width = int(self._chip_width) half_width = int(chip_width / 2) bbox_min_x = int( (bbox_min_x + bbox_max_x) / 2) - half_width bbox_min_y = int( (bbox_min_y + bbox_max_y) / 2) - half_width bbox_max_x = bbox_min_x + chip_width bbox_max_y = bbox_min_y + chip_width bbox_width = chip_width bbox_height = chip_width if self._area_lower_bound > 0 and bbox_area < self._area_lower_bound: continue if self._area_upper_bound > 0 and bbox_area > self._area_upper_bound: continue if self._border_exclude > 0: if bbox_min_x <= self._border_exclude: continue if bbox_min_y <= self._border_exclude: continue if bbox_max_x >= img_max_x - self._border_exclude: continue if bbox_max_y >= img_max_y - self._border_exclude: continue # Handle random factor if self._max_neg_per_frame < 1.0 and random.uniform( 0, 1) > self._max_neg_per_frame: break crop = img[bbox_min_y:bbox_max_y, bbox_min_x:bbox_max_x] self._sample_count = self._sample_count + 1 crop_str = ('%09d' % self._sample_count) + ".png" new_file = os.path.join(self._chip_directory, crop_str) cv2.imwrite(new_file, crop) # Set new box size for this detection det.bounding_box = BoundingBoxD(0, 0, np.shape(crop)[1], np.shape(crop)[0]) det.type = DetectedObjectType(self._negative_category, 1.0) new_set = DetectedObjectSet() new_set.add(det) output_files.append(new_file) output_dets.append(new_set) # Check maximum negative count neg_count = neg_count + 1 if neg_count > self._max_neg_per_frame: break return [output_files, output_dets]
def test_methods(self): t = DOT(np.array(["name1","class_name2","class3"]),np.array([1.0,2.3,3.14])) # str/repr/itr self.assertIsInstance(str(t),str) self.assertIsInstance(t.__repr__(), str) itr = iter(t) self.assertIsInstance(next(itr),tuple) # Has Class Name self.assertTrue(t.has_class_name("name1")) self.assertFalse(t.has_class_name("foo")) # Score self.assertEqual(t.score("class_name2"),2.3) # Get most likely self.assertEqual(t.get_most_likely_class(),"class3") self.assertEqual(3.14,t.get_most_likely_score()) # Set Score t.set_score("foo1",3.8) self.assertEqual(3.8,t.score("foo1")) t.set_score("foo2",3.9) self.assertTrue(t.has_class_name("foo2")) self.assertEqual(t.score("foo2"),3.9) # Delete Score t.delete_score("foo1") self.assertFalse(t.has_class_name("foo1")) # Class Names np.testing.assert_array_equal(t.class_names(), np.array(["foo2","class3","class_name2","name1"])) np.testing.assert_array_equal(t.class_names(3.0), np.array(["foo2","class3"])) np.testing.assert_array_equal(t.all_class_names(),np.array(["class3","class_name2","foo1","foo2","name","name1"])) print() print("--------------------------") print(t.all_class_names()) print("--------------------------") for item in t.all_class_names(): print() print("--------------") print(item) print("--------------")