def _step(self): # grab image container from port using traits optical_c = self.grab_input_using_trait('optical_image') thermal_c = self.grab_input_using_trait('thermal_image') # Get python image from conatiner (just for show) optical_npy = optical_c.image().asarray().astype('uint8') thermal_npy = thermal_c.image().asarray().astype('uint16') thermal_norm = normalize_thermal(thermal_npy) if thermal_norm is not None and optical_npy is not None: # compute transform ret, transform, _ = compute_transform( optical_npy, thermal_norm, warp_mode=cv2.MOTION_HOMOGRAPHY, match_low_res=True, good_match_percent=self._good_match_percent, ratio_test=self._ratio_test, match_height=self._match_height, min_matches=self._min_matches, min_inliers=self._min_inliers) else: ret = False if ret: # TODO: Make all of these computations conditional on port connection inv_transform = np.linalg.inv(transform) thermal_warped = cv2.warpPerspective( thermal_npy, transform, \ ( optical_npy.shape[1], optical_npy.shape[0] ) ) optical_warped = cv2.warpPerspective( optical_npy, inv_transform, \ ( thermal_npy.shape[1], thermal_npy.shape[0] ) ) #self.push_to_port_using_trait( 'thermal_to_optical_homog', # F2FHomography.from_matrix( transform, 'd' ) #self.push_to_port_using_trait( 'optical_to_thermal_homog', # F2FHomography.from_matrix( inv_transform, 'd' ) self.push_to_port_using_trait( 'warped_thermal_image', ImageContainer.fromarray(thermal_warped)) self.push_to_port_using_trait( 'warped_optical_image', ImageContainer.fromarray(optical_warped)) else: print('alignment failed!') #self.push_to_port_using_trait( "thermal_to_optical_homog", F2FHomography() ) #self.push_to_port_using_trait( "optical_to_thermal_homog", F2FHomography() ) self.push_to_port_using_trait('warped_optical_image', ImageContainer()) self.push_to_port_using_trait('warped_thermal_image', ImageContainer()) self._base_step()
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 _test_numpy(dtype_name, nchannels, order='c'): np_img = create_numpy_image(dtype_name, nchannels, order) img_container = ImageContainer.fromarray(np_img) recast = img_container.asarray() # asarray always returns 3 channels np_img = np.atleast_3d(np_img) vital_img = img_container.image() pixel_type_name = vital_img.pixel_type_name() pixel_type_name = vital_img.pixel_type_name() want = map_dtype_name_to_pixel_type(dtype_name) assert pixel_type_name == want, 'want={} but got={}'.format( want, pixel_type_name) if not np.all(np_img == recast): raise AssertionError( 'Failed dtype={}, nchannels={}, order={}'.format( dtype_name, nchannels, order))
def draw(self, detected_object_set, image): u_image = cv2.cvtColor(image.asarray(), cv2.COLOR_RGB2BGR) for detected_object in detected_object_set: bbox = detected_object.bounding_box() confidence = detected_object.confidence() if self.bbox_shape == "rectangle": u_image = cv2.rectangle(u_image, (int(bbox.min_x()), int(bbox.min_y())), (int(bbox.max_x()), int(bbox.max_y())), self.bbox_color, self.bbox_thickness) text_origin = (int(bbox.min_x()),int(bbox.min_y()-self.bbox_thickness)) else: center = ((int(bbox.min_x()) + int(bbox.max_x()))//2, (int(bbox.min_y()) + int(bbox.max_y()))//2) radius = int(math.sqrt(math.pow(float(bbox.max_y()) - \ float(bbox.min_y()), 2) + \ math.pow(float(bbox.max_x()) - \ float(bbox.min_x()), 2))) u_image = cv2.circle(u_image, center, radius, self.bbox_color, self.bbox_thickness) text_origin = (center[0]-radius, center[1]-radius-self.bbox_thickness) types = detected_object.type() if types is None: label = "{0}".format(confidence) else: label = "{0}: {1}".format(types.get_most_likely_class(), types.get_most_likely_score()) u_image = cv2.putText(u_image, label, text_origin, self.font, self.font_scale, self.bbox_color, self.font_thickness) u_image = cv2.cvtColor(u_image, cv2.COLOR_BGR2RGB) image_container = ImageContainer.fromarray(u_image) return image_container
def test_save_directory(self): dummy_image = np.zeros([100, 100]) image_container = ImageContainer.fromarray(dummy_image) with tempfile.TemporaryDirectory() as directory_name: self.instance.save(directory_name, image_container)
def test_save_nonexistant(self): dummy_image = np.zeros([100, 100]) image_container = ImageContainer.fromarray(dummy_image) self.instance.save("nonexistant_filename.txt", image_container)