diff --git a/system_tests/data/faces.jpg b/system_tests/data/faces.jpg new file mode 100644 index 000000000000..af26c6e3f334 Binary files /dev/null and b/system_tests/data/faces.jpg differ diff --git a/system_tests/vision.py b/system_tests/vision.py index 258f67c8f890..d783994b78d7 100644 --- a/system_tests/vision.py +++ b/system_tests/vision.py @@ -28,6 +28,7 @@ _SYS_TESTS_DIR = os.path.abspath(os.path.dirname(__file__)) LOGO_FILE = os.path.join(_SYS_TESTS_DIR, 'data', 'logo.png') +FACE_FILE = os.path.join(_SYS_TESTS_DIR, 'data', 'faces.jpg') class Config(object): @@ -53,7 +54,7 @@ def tearDownModule(): bucket_retry(Config.TEST_BUCKET.delete)(force=True) -class TestVisionClient(unittest.TestCase): +class TestVisionClientLogo(unittest.TestCase): def setUp(self): self.to_delete_by_case = [] @@ -108,3 +109,109 @@ def test_detect_logos_gcs(self): self.assertEqual(len(logos), 1) logo = logos[0] self._assert_logo(logo) + + +class TestVisionClientFace(unittest.TestCase): + def setUp(self): + self.to_delete_by_case = [] + + def tearDown(self): + for value in self.to_delete_by_case: + value.delete() + + def _assert_coordinate(self, coordinate): + if coordinate is None: + return + self.assertIsInstance(coordinate, (int, float)) + self.assertGreater(abs(coordinate), 0.0) + + def _assert_likelihood(self, likelihood): + from google.cloud.vision.likelihood import Likelihood + + levels = [Likelihood.UNKNOWN, Likelihood.VERY_LIKELY, + Likelihood.UNLIKELY, Likelihood.POSSIBLE, Likelihood.LIKELY, + Likelihood.VERY_UNLIKELY] + self.assertIn(likelihood, levels) + + def _assert_landmarks(self, landmarks): + from google.cloud.vision.face import Landmark + from google.cloud.vision.face import LandmarkTypes + from google.cloud.vision.face import Position + + for landmark in LandmarkTypes: + if landmark is not LandmarkTypes.UNKNOWN_LANDMARK: + feature = getattr(landmarks, landmark.value.lower()) + self.assertIsInstance(feature, Landmark) + self.assertIsInstance(feature.position, Position) + self._assert_coordinate(feature.position.x_coordinate) + self._assert_coordinate(feature.position.y_coordinate) + self._assert_coordinate(feature.position.z_coordinate) + + def _assert_face(self, face): + from google.cloud.vision.face import Bounds + from google.cloud.vision.face import FDBounds + from google.cloud.vision.face import Face + from google.cloud.vision.face import Landmarks + from google.cloud.vision.geometry import Vertex + + self.assertIsInstance(face, Face) + self.assertGreater(face.detection_confidence, 0.0) + self._assert_likelihood(face.anger) + self._assert_likelihood(face.joy) + self._assert_likelihood(face.sorrow) + self._assert_likelihood(face.surprise) + self._assert_likelihood(face.image_properties.blurred) + self._assert_likelihood(face.image_properties.underexposed) + self._assert_likelihood(face.headwear) + self.assertNotEqual(face.angles.roll, 0.0) + self.assertNotEqual(face.angles.pan, 0.0) + self.assertNotEqual(face.angles.tilt, 0.0) + + self.assertIsInstance(face.bounds, Bounds) + for vertex in face.bounds.vertices: + self.assertIsInstance(vertex, Vertex) + self._assert_coordinate(vertex.x_coordinate) + self._assert_coordinate(vertex.y_coordinate) + + self.assertIsInstance(face.fd_bounds, FDBounds) + for vertex in face.fd_bounds.vertices: + self.assertIsInstance(vertex, Vertex) + self._assert_coordinate(vertex.x_coordinate) + self._assert_coordinate(vertex.y_coordinate) + + self.assertIsInstance(face.landmarks, Landmarks) + self._assert_landmarks(face.landmarks) + + def test_detect_faces_content(self): + client = Config.CLIENT + with open(FACE_FILE, 'rb') as image_file: + image = client.image(content=image_file.read()) + faces = image.detect_faces() + self.assertEqual(len(faces), 5) + for face in faces: + self._assert_face(face) + + def test_detect_faces_gcs(self): + bucket_name = Config.TEST_BUCKET.name + blob_name = 'faces.jpg' + blob = Config.TEST_BUCKET.blob(blob_name) + self.to_delete_by_case.append(blob) # Clean-up. + with open(FACE_FILE, 'rb') as file_obj: + blob.upload_from_file(file_obj) + + source_uri = 'gs://%s/%s' % (bucket_name, blob_name) + + client = Config.CLIENT + image = client.image(source_uri=source_uri) + faces = image.detect_faces() + self.assertEqual(len(faces), 5) + for face in faces: + self._assert_face(face) + + def test_detect_faces_filename(self): + client = Config.CLIENT + image = client.image(filename=FACE_FILE) + faces = image.detect_faces() + self.assertEqual(len(faces), 5) + for face in faces: + self._assert_face(face)