def test_origin_location(self): p2c = Pixel2coord(DB()) p2c.calibration_params['image_bot_origin_location'] = [0, 0] p2c.calibration_params['center_pixel_location'] = [100, 200] p2c._block_rotations(90) self.assertEqual( p2c.calibration_params['image_bot_origin_location'], [1, 0])
def test_location_rotation(self): """Detect using different calibration object locations and rotations.""" i = 0 for flip in range(3): for angle in [-10, 10]: img = 'test_objects_{}.jpg'.format(i) i += 1 calibration_img = cv2.imread( 'plant_detection/p2c_test_calibration.jpg', 1) if flip > 1: cv2.circle(calibration_img, (465, 290), int(1000), (255, 255, 255), -1) cv2.circle(calibration_img, (172, 290), int(25), (0, 0, 255), -1) cv2.circle(calibration_img, (755, 290), int(25), (0, 0, 255), -1) elif flip: calibration_img = cv2.flip(calibration_img, 0) calibration_img = rotate(calibration_img, angle) cv2.imwrite(img, calibration_img) p2c = Pixel2coord(DB(), calibration_image=img, calibration_data=self.calibration_data) p2c.calibration() self.assertAlmostEqual( p2c.calibration_params['total_rotation_angle'], -angle, delta=1) self.assertAlmostEqual( p2c.calibration_params['coord_scale'], 1.7, delta=0.1)
def test_three_objects(self): """Detect three objects during calibration""" db = DB() p2c = Pixel2coord( db, calibration_image=image_file('three.jpg', self.three_objects)) exit_flag = p2c.calibration() self.assertEqual(db.object_count, 3) self.assertFalse(exit_flag)
def test_one_object(self): """Detect one object during calibration""" db = DB() p2c = Pixel2coord( db, calibration_image=image_file('one.jpg', self.one_object)) exit_flag = p2c.calibration() self.assertEqual(db.object_count, 1) self.assertTrue(exit_flag)
def test_zero_objects(self): """Detect zero objects during calibration""" db = DB() p2c = Pixel2coord( db, calibration_image=image_file('zero.jpg', self.zero_objects)) exit_flag = p2c.calibration() self.assertEqual(db.object_count, 0) self.assertTrue(exit_flag)
def test_orientation(self): """Detect calibration objects based on image origin. | top (0) | bottom (1) | --------- ---------- left (0) | 00 | 01 | --------- ---------- right (1) | 10 | 11 | --------- ---------- """ orientations = [[0, 0], [0, 1], [1, 0], [1, 1]] expectations = [{ "x": 1300, "y": 800 }, { "x": 1300, "y": 200 }, { "x": 300, "y": 800 }, { "x": 300, "y": 200 }] for orientation, expectation in zip(orientations, expectations): image_origin = '{} {}'.format(['top', 'bottom'][orientation[1]], ['left', 'right'][orientation[0]]) convert_to_env_var = { '[0, 0]': 'TOP_LEFT', '[1, 0]': 'TOP_RIGHT', '[0, 1]': 'BOTTOM_LEFT', '[1, 1]': 'BOTTOM_RIGHT' } os.environ[ 'CAMERA_CALIBRATION_image_bot_origin_location'] = json.dumps( convert_to_env_var[str(orientation)]) os.environ[ 'CAMERA_CALIBRATION_calibration_object_separation'] = '1000' os.environ['CAMERA_CALIBRATION_camera_offset_x'] = '200' os.environ['CAMERA_CALIBRATION_camera_offset_y'] = '100' os.environ['CAMERA_CALIBRATION_calibration_along_axis'] = 'X' p2c = Pixel2coord( DB(), calibration_image='plant_detection/p2c_test_calibration.jpg', load_data_from='env_var') p2c.calibration() p2c.image.load('single_object.jpg') coordinates = p2c.determine_coordinates() for axis in ['x', 'y']: self.assertAlmostEqual( coordinates[0][axis], expectation[axis], delta=5, msg="object {} coordinate {} != {} within 5 delta for {}" " image origin".format(axis, coordinates[0][axis], expectation[axis], image_origin))
def _coordinate_conversion(self): # determine detected object coordinates # Load calibration data load_data_from = None calibration_data = None if self.args['from_env_var']: load_data_from = 'env_var' elif self.args['from_file']: load_data_from = 'file' else: # use data saved in self.params calibration_data = self.params.calibration_data # Initialize coordinate conversion module self.p2c = Pixel2coord(self.plant_db, load_data_from=load_data_from, calibration_data=calibration_data) self.p2c.debug = self.args['debug'] # Check for coordinate conversion calibration results present = { 'coord_scale': False, 'camera_z': False, 'center_pixel_location': False, 'total_rotation_angle': False } try: for key in present: present[key] = self.p2c.calibration_params[key] except KeyError: log( "ERROR: Coordinate conversion calibration values " "not found. Run calibration first.", message_type='error', title='plant-detection') sys.exit(0) # Validate coordinate conversion calibration data for image calibration_data_valid = self.p2c.validate_calibration_data( self.image.images['current']) if not calibration_data_valid: log( "ERROR: Coordinate conversion calibration values " "invalid for provided image.", message_type='error', title='plant-detection') sys.exit(0) # Determine object coordinates self.image.coordinates(self.p2c, draw_contours=self.args['draw_contours']) # Organize objects into plants and weeds self.plant_db.identify(self.params.parameters) if self.plant_db.plants['safe_remove']: self.image.safe_remove(self.p2c)
def _calibration_input(self): # provide inputs to calibration if self.args['app_image_id'] is not None: self.args['calibration_img'] = int(self.args['app_image_id']) if self.args['calibration_img'] is None and self.args['coordinates']: # Calibration requested, but no image provided. # Take a calibration image. self.args['calibration_img'] = self.capture() # Set calibration input parameters if self.args['from_env_var']: calibration_input = 'env_var' elif self.args['from_file']: # try to load from file calibration_input = 'file' else: # Use default calibration inputs calibration_input = None # Call coordinate conversion module self.p2c = Pixel2coord(self.plant_db, calibration_image=self.args['calibration_img'], calibration_data=self.args['calibration_data'], load_data_from=calibration_input) self.p2c.debug = self.args['debug']