Skip to content

Commit 04517cd

Browse files
committed
Add GAPIC support for face detection.
1 parent 885397b commit 04517cd

File tree

13 files changed

+388
-135
lines changed

13 files changed

+388
-135
lines changed

system_tests/vision.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ class BaseVisionTestCase(unittest.TestCase):
6262
def _assert_coordinate(self, coordinate):
6363
if coordinate is None:
6464
return
65+
self.assertIsNotNone(coordinate)
6566
self.assertIsInstance(coordinate, (int, float))
66-
self.assertNotEqual(coordinate, 0.0)
6767

6868
def _assert_likelihood(self, likelihood):
6969
from google.cloud.vision.likelihood import Likelihood
@@ -73,8 +73,8 @@ def _assert_likelihood(self, likelihood):
7373
Likelihood.VERY_UNLIKELY]
7474
self.assertIn(likelihood, levels)
7575

76-
def _maybe_http_skip(self, message):
77-
if not Config.CLIENT._use_gax:
76+
def _pb_not_implemented_skip(self, message):
77+
if Config.CLIENT._use_gax:
7878
self.skipTest(message)
7979

8080

@@ -150,7 +150,7 @@ def _assert_landmarks(self, landmarks):
150150

151151
for landmark in LandmarkTypes:
152152
if landmark is not LandmarkTypes.UNKNOWN_LANDMARK:
153-
feature = getattr(landmarks, landmark.value.lower())
153+
feature = getattr(landmarks, landmark.name.lower())
154154
self.assertIsInstance(feature, Landmark)
155155
self.assertIsInstance(feature.position, Position)
156156
self._assert_coordinate(feature.position.x_coordinate)
@@ -194,7 +194,6 @@ def _assert_face(self, face):
194194

195195
def test_detect_faces_content(self):
196196
client = Config.CLIENT
197-
self._maybe_http_skip('gRPC is required for face detection.')
198197
with open(FACE_FILE, 'rb') as image_file:
199198
image = client.image(content=image_file.read())
200199
faces = image.detect_faces()
@@ -203,7 +202,6 @@ def test_detect_faces_content(self):
203202
self._assert_face(face)
204203

205204
def test_detect_faces_gcs(self):
206-
self._maybe_http_skip('gRPC is required for face detection.')
207205
bucket_name = Config.TEST_BUCKET.name
208206
blob_name = 'faces.jpg'
209207
blob = Config.TEST_BUCKET.blob(blob_name)
@@ -220,7 +218,6 @@ def test_detect_faces_gcs(self):
220218
self._assert_face(face)
221219

222220
def test_detect_faces_filename(self):
223-
self._maybe_http_skip('gRPC is required for face detection.')
224221
client = Config.CLIENT
225222
image = client.image(filename=FACE_FILE)
226223
faces = image.detect_faces()
@@ -367,7 +364,8 @@ def _assert_safe_search(self, safe_search):
367364
self._assert_likelihood(safe_search.violence)
368365

369366
def test_detect_safe_search_content(self):
370-
self._maybe_http_skip('gRPC is required for safe search detection.')
367+
self._pb_not_implemented_skip(
368+
'gRPC not implemented for safe search detection.')
371369
client = Config.CLIENT
372370
with open(FACE_FILE, 'rb') as image_file:
373371
image = client.image(content=image_file.read())
@@ -377,7 +375,8 @@ def test_detect_safe_search_content(self):
377375
self._assert_safe_search(safe_search)
378376

379377
def test_detect_safe_search_gcs(self):
380-
self._maybe_http_skip('gRPC is required for safe search detection.')
378+
self._pb_not_implemented_skip(
379+
'gRPC not implemented for safe search detection.')
381380
bucket_name = Config.TEST_BUCKET.name
382381
blob_name = 'faces.jpg'
383382
blob = Config.TEST_BUCKET.blob(blob_name)
@@ -395,7 +394,8 @@ def test_detect_safe_search_gcs(self):
395394
self._assert_safe_search(safe_search)
396395

397396
def test_detect_safe_search_filename(self):
398-
self._maybe_http_skip('gRPC is required for safe search detection.')
397+
self._pb_not_implemented_skip(
398+
'gRPC not implemented for safe search detection.')
399399
client = Config.CLIENT
400400
image = client.image(filename=FACE_FILE)
401401
safe_searches = image.detect_safe_search()
@@ -493,7 +493,8 @@ def _assert_properties(self, image_property):
493493
self.assertNotEqual(color_info.score, 0.0)
494494

495495
def test_detect_properties_content(self):
496-
self._maybe_http_skip('gRPC is required for text detection.')
496+
self._pb_not_implemented_skip(
497+
'gRPC not implemented for image properties detection.')
497498
client = Config.CLIENT
498499
with open(FACE_FILE, 'rb') as image_file:
499500
image = client.image(content=image_file.read())
@@ -503,7 +504,8 @@ def test_detect_properties_content(self):
503504
self._assert_properties(image_property)
504505

505506
def test_detect_properties_gcs(self):
506-
self._maybe_http_skip('gRPC is required for text detection.')
507+
self._pb_not_implemented_skip(
508+
'gRPC not implemented for image properties detection.')
507509
client = Config.CLIENT
508510
bucket_name = Config.TEST_BUCKET.name
509511
blob_name = 'faces.jpg'
@@ -521,7 +523,8 @@ def test_detect_properties_gcs(self):
521523
self._assert_properties(image_property)
522524

523525
def test_detect_properties_filename(self):
524-
self._maybe_http_skip('gRPC is required for text detection.')
526+
self._pb_not_implemented_skip(
527+
'gRPC not implemented for image properties detection.')
525528
client = Config.CLIENT
526529
image = client.image(filename=FACE_FILE)
527530
properties = image.detect_properties()

vision/google/cloud/vision/_gax.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
from google.cloud.gapic.vision.v1 import image_annotator_client
1818
from google.cloud.grpc.vision.v1 import image_annotator_pb2
1919

20-
from google.cloud._helpers import _to_bytes
21-
2220
from google.cloud.vision.annotations import Annotations
2321

2422

@@ -85,7 +83,7 @@ def _to_gapic_image(image):
8583
:class:`~google.cloud.vision.image.Image`.
8684
"""
8785
if image.content is not None:
88-
return image_annotator_pb2.Image(content=_to_bytes(image.content))
86+
return image_annotator_pb2.Image(content=image.content)
8987
if image.source is not None:
9088
return image_annotator_pb2.Image(
9189
source=image_annotator_pb2.ImageSource(

vision/google/cloud/vision/annotations.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ def _process_image_annotations(image):
119119
:returns: Dictionary populated with entities from response.
120120
"""
121121
return {
122+
'faces': _make_faces_from_pb(image.face_annotations),
122123
'labels': _make_entity_from_pb(image.label_annotations),
123124
'landmarks': _make_entity_from_pb(image.landmark_annotations),
124125
'logos': _make_entity_from_pb(image.logo_annotations),
@@ -139,6 +140,19 @@ def _make_entity_from_pb(annotations):
139140
return [EntityAnnotation.from_pb(annotation) for annotation in annotations]
140141

141142

143+
def _make_faces_from_pb(faces):
144+
"""Create face objects from a gRPC response.
145+
146+
:type faces:
147+
:class:`~google.cloud.grpc.vision.v1.image_annotator_pb2.FaceAnnotation`
148+
:param faces: Protobuf instance of ``FaceAnnotation``.
149+
150+
:rtype: list
151+
:returns: List of ``Face``.
152+
"""
153+
return [Face.from_pb(face) for face in faces]
154+
155+
142156
def _entity_from_response_type(feature_type, results):
143157
"""Convert a JSON result to an entity type based on the feature.
144158

vision/google/cloud/vision/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class Client(JSONClient):
5858
_vision_api_internal = None
5959

6060
def __init__(self, project=None, credentials=None, http=None,
61-
use_gax=False):
61+
use_gax=None):
6262
super(Client, self).__init__(
6363
project=project, credentials=credentials, http=http)
6464
self._connection = Connection(

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy