2828
2929_SYS_TESTS_DIR = os .path .abspath (os .path .dirname (__file__ ))
3030LOGO_FILE = os .path .join (_SYS_TESTS_DIR , 'data' , 'logo.png' )
31+ FACE_FILE = os .path .join (_SYS_TESTS_DIR , 'data' , 'faces.jpg' )
3132
3233
3334class 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,104 @@ 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 True
125+
126+ self .assertIn (type (coordinate ), [int , float ])
127+ self .assertGreater (abs (coordinate ), 0.0 )
128+
129+ def _assert_likelihood (self , likelihood ):
130+ from google .cloud .vision .likelihood import Likelihood
131+
132+ levels = [Likelihood .UNKNOWN , Likelihood .VERY_LIKELY ,
133+ Likelihood .UNLIKELY , Likelihood .POSSIBLE , Likelihood .LIKELY ,
134+ Likelihood .VERY_UNLIKELY ]
135+ self .assertIn (likelihood , levels )
136+
137+ def _assert_landmark (self , landmark ):
138+ from google .cloud .vision .face import Landmark
139+ from google .cloud .vision .face import FaceLandmarkTypes
140+
141+ self .assertIsInstance (landmark , Landmark )
142+
143+ valid_landmark_type = getattr (FaceLandmarkTypes ,
144+ landmark .landmark_type , False )
145+ if valid_landmark_type :
146+ return True
147+ return False
148+
149+ def _assert_face (self , face ):
150+ from google .cloud .vision .face import Bounds
151+ from google .cloud .vision .face import FDBounds
152+ from google .cloud .vision .face import Face
153+ from google .cloud .vision .geometry import Vertex
154+
155+ self .assertIsInstance (face , Face )
156+ self .assertGreater (face .detection_confidence , 0.0 )
157+ self ._assert_likelihood (face .anger )
158+ self ._assert_likelihood (face .joy )
159+ self ._assert_likelihood (face .sorrow )
160+ self ._assert_likelihood (face .surprise )
161+ self ._assert_likelihood (face .image_properties .blurred )
162+ self ._assert_likelihood (face .image_properties .underexposed )
163+ self ._assert_likelihood (face .headwear )
164+ self .assertGreater (abs (face .angles .roll ), 0.0 )
165+ self .assertGreater (abs (face .angles .pan ), 0.0 )
166+ self .assertGreater (abs (face .angles .tilt ), 0.0 )
167+
168+ self .assertIsInstance (face .bounds , Bounds )
169+ for vertex in face .bounds .vertices :
170+ self .assertIsInstance (vertex , Vertex )
171+ self ._assert_coordinate (vertex .x_coordinate )
172+ self ._assert_coordinate (vertex .y_coordinate )
173+
174+ self .assertIsInstance (face .fd_bounds , FDBounds )
175+ for vertex in face .fd_bounds .vertices :
176+ self .assertIsInstance (vertex , Vertex )
177+ self ._assert_coordinate (vertex .x_coordinate )
178+ self ._assert_coordinate (vertex .y_coordinate )
179+
180+ def test_detect_faces_content (self ):
181+ client = Config .CLIENT
182+ with open (FACE_FILE , 'rb' ) as image_file :
183+ image = client .image (content = image_file .read ())
184+ faces = image .detect_faces ()
185+ self .assertEqual (len (faces ), 5 )
186+ for face in faces :
187+ self ._assert_face (face )
188+
189+ def test_detect_faces_gcs (self ):
190+ bucket_name = Config .TEST_BUCKET .name
191+ blob_name = 'faces.jpg'
192+ blob = Config .TEST_BUCKET .blob (blob_name )
193+ self .to_delete_by_case .append (blob ) # Clean-up.
194+ with open (FACE_FILE , 'rb' ) as file_obj :
195+ blob .upload_from_file (file_obj )
196+
197+ source_uri = 'gs://%s/%s' % (bucket_name , blob_name )
198+
199+ client = Config .CLIENT
200+ image = client .image (source_uri = source_uri )
201+ faces = image .detect_faces ()
202+ self .assertEqual (len (faces ), 5 )
203+ for face in faces :
204+ self ._assert_face (face )
205+
206+ def test_detect_faces_filename (self ):
207+ client = Config .CLIENT
208+ image = client .image (filename = FACE_FILE )
209+ faces = image .detect_faces ()
210+ self .assertEqual (len (faces ), 5 )
211+ for face in faces :
212+ self ._assert_face (face )
0 commit comments