Skip to content

Commit dff8675

Browse files
authored
Merge pull request googleapis#2827 from daspecster/vision-face-system-tests
Add system tests for detect_faces().
2 parents cfe5b88 + 34c7616 commit dff8675

2 files changed

Lines changed: 108 additions & 1 deletion

File tree

system_tests/data/faces.jpg

277 KB
Loading

system_tests/vision.py

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
_SYS_TESTS_DIR = os.path.abspath(os.path.dirname(__file__))
3030
LOGO_FILE = os.path.join(_SYS_TESTS_DIR, 'data', 'logo.png')
31+
FACE_FILE = os.path.join(_SYS_TESTS_DIR, 'data', 'faces.jpg')
3132

3233

3334
class Config(object):
@@ -53,7 +54,7 @@ def tearDownModule():
5354
bucket_retry(Config.TEST_BUCKET.delete)(force=True)
5455

5556

56-
class TestVisionClient(unittest.TestCase):
57+
class TestVisionClientLogo(unittest.TestCase):
5758
def setUp(self):
5859
self.to_delete_by_case = []
5960

@@ -108,3 +109,109 @@ def test_detect_logos_gcs(self):
108109
self.assertEqual(len(logos), 1)
109110
logo = logos[0]
110111
self._assert_logo(logo)
112+
113+
114+
class TestVisionClientFace(unittest.TestCase):
115+
def setUp(self):
116+
self.to_delete_by_case = []
117+
118+
def tearDown(self):
119+
for value in self.to_delete_by_case:
120+
value.delete()
121+
122+
def _assert_coordinate(self, coordinate):
123+
if coordinate is None:
124+
return
125+
self.assertIsInstance(coordinate, (int, float))
126+
self.assertGreater(abs(coordinate), 0.0)
127+
128+
def _assert_likelihood(self, likelihood):
129+
from google.cloud.vision.likelihood import Likelihood
130+
131+
levels = [Likelihood.UNKNOWN, Likelihood.VERY_LIKELY,
132+
Likelihood.UNLIKELY, Likelihood.POSSIBLE, Likelihood.LIKELY,
133+
Likelihood.VERY_UNLIKELY]
134+
self.assertIn(likelihood, levels)
135+
136+
def _assert_landmarks(self, landmarks):
137+
from google.cloud.vision.face import Landmark
138+
from google.cloud.vision.face import LandmarkTypes
139+
from google.cloud.vision.face import Position
140+
141+
for landmark in LandmarkTypes:
142+
if landmark is not LandmarkTypes.UNKNOWN_LANDMARK:
143+
feature = getattr(landmarks, landmark.value.lower())
144+
self.assertIsInstance(feature, Landmark)
145+
self.assertIsInstance(feature.position, Position)
146+
self._assert_coordinate(feature.position.x_coordinate)
147+
self._assert_coordinate(feature.position.y_coordinate)
148+
self._assert_coordinate(feature.position.z_coordinate)
149+
150+
def _assert_face(self, face):
151+
from google.cloud.vision.face import Bounds
152+
from google.cloud.vision.face import FDBounds
153+
from google.cloud.vision.face import Face
154+
from google.cloud.vision.face import Landmarks
155+
from google.cloud.vision.geometry import Vertex
156+
157+
self.assertIsInstance(face, Face)
158+
self.assertGreater(face.detection_confidence, 0.0)
159+
self._assert_likelihood(face.anger)
160+
self._assert_likelihood(face.joy)
161+
self._assert_likelihood(face.sorrow)
162+
self._assert_likelihood(face.surprise)
163+
self._assert_likelihood(face.image_properties.blurred)
164+
self._assert_likelihood(face.image_properties.underexposed)
165+
self._assert_likelihood(face.headwear)
166+
self.assertNotEqual(face.angles.roll, 0.0)
167+
self.assertNotEqual(face.angles.pan, 0.0)
168+
self.assertNotEqual(face.angles.tilt, 0.0)
169+
170+
self.assertIsInstance(face.bounds, Bounds)
171+
for vertex in face.bounds.vertices:
172+
self.assertIsInstance(vertex, Vertex)
173+
self._assert_coordinate(vertex.x_coordinate)
174+
self._assert_coordinate(vertex.y_coordinate)
175+
176+
self.assertIsInstance(face.fd_bounds, FDBounds)
177+
for vertex in face.fd_bounds.vertices:
178+
self.assertIsInstance(vertex, Vertex)
179+
self._assert_coordinate(vertex.x_coordinate)
180+
self._assert_coordinate(vertex.y_coordinate)
181+
182+
self.assertIsInstance(face.landmarks, Landmarks)
183+
self._assert_landmarks(face.landmarks)
184+
185+
def test_detect_faces_content(self):
186+
client = Config.CLIENT
187+
with open(FACE_FILE, 'rb') as image_file:
188+
image = client.image(content=image_file.read())
189+
faces = image.detect_faces()
190+
self.assertEqual(len(faces), 5)
191+
for face in faces:
192+
self._assert_face(face)
193+
194+
def test_detect_faces_gcs(self):
195+
bucket_name = Config.TEST_BUCKET.name
196+
blob_name = 'faces.jpg'
197+
blob = Config.TEST_BUCKET.blob(blob_name)
198+
self.to_delete_by_case.append(blob) # Clean-up.
199+
with open(FACE_FILE, 'rb') as file_obj:
200+
blob.upload_from_file(file_obj)
201+
202+
source_uri = 'gs://%s/%s' % (bucket_name, blob_name)
203+
204+
client = Config.CLIENT
205+
image = client.image(source_uri=source_uri)
206+
faces = image.detect_faces()
207+
self.assertEqual(len(faces), 5)
208+
for face in faces:
209+
self._assert_face(face)
210+
211+
def test_detect_faces_filename(self):
212+
client = Config.CLIENT
213+
image = client.image(filename=FACE_FILE)
214+
faces = image.detect_faces()
215+
self.assertEqual(len(faces), 5)
216+
for face in faces:
217+
self._assert_face(face)

0 commit comments

Comments
 (0)