Skip to content

Commit 028be63

Browse files
committed
Add Vision Logo detection.
1 parent 4f74c7d commit 028be63

File tree

9 files changed

+1710
-8
lines changed

9 files changed

+1710
-8
lines changed

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
vision-usage
151151
vision-client
152152
vision-image
153+
vision-entity
153154
vision-feature
154155
vision-face
155156

docs/vision-entity.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Vision Entity
2+
=============
3+
4+
Entity
5+
~~~~~~
6+
7+
.. automodule:: google.cloud.vision.entity
8+
:members:
9+
:undoc-members:
10+
:show-inheritance:

google/cloud/vision/entity.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Copyright 2016 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Entity class for holding information returned from annotating an image."""
16+
17+
18+
from google.cloud.vision.geometry import Bounds
19+
20+
21+
class EntityAnnotation(object):
22+
"""Representation of an entity returned from the Vision API.
23+
24+
:type bounds: dict
25+
:param bounds: Dictionary of bounary information of detected entity.
26+
27+
:type description: str
28+
:param description: Description of entity detected in an image.
29+
30+
:type mid: str
31+
:param mid: Opaque entity ID.
32+
33+
:type score: float
34+
:param score: Overall score of the result. Range [0, 1].
35+
"""
36+
def __init__(self, bounds, description, mid, score):
37+
self._bounds = bounds
38+
self._description = description
39+
self._mid = mid
40+
self._score = score
41+
42+
@classmethod
43+
def from_api_repr(cls, response):
44+
"""Factory: construct entity from Vision API response.
45+
46+
:type response: dict
47+
:param response: Dictionary response from Vision API with entity data.
48+
49+
:rtype: :class:`~google.cloud.vision.entiy.EntityAnnotation`
50+
:returns: Instance of ``EntityAnnotation``.
51+
"""
52+
bounds = Bounds.from_api_repr(response['boundingPoly'])
53+
description = response['description']
54+
mid = response['mid']
55+
score = response['score']
56+
57+
return cls(bounds, description, mid, score)
58+
59+
@property
60+
def bounds(self):
61+
"""Bounding polygon of detected image feature.
62+
63+
:rtype: :class:`~google.cloud.vision.geometry.Bounds`
64+
:returns: Instance of ``Bounds`` with populated vertices.
65+
"""
66+
return self._bounds
67+
68+
@property
69+
def description(self):
70+
"""Description of feature detected in image.
71+
72+
:rtype: str
73+
:returns: String description of feature detected in image.
74+
"""
75+
return self._description
76+
77+
@property
78+
def mid(self):
79+
"""MID of feature detected in image.
80+
81+
:rtype: str
82+
:returns: String MID of feature detected in image.
83+
"""
84+
return self._mid
85+
86+
@property
87+
def score(self):
88+
"""Overall score of the result. Range [0, 1].
89+
90+
:rtype: float
91+
:returns: Overall score of the result. Range [0, 1].
92+
"""
93+
return self._score

google/cloud/vision/feature.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,32 @@ def __init__(self, feature_type, max_results=1):
5151
self._max_results = int(max_results)
5252

5353
def as_dict(self):
54-
"""Generate dictionary for Feature request format."""
54+
"""Generate dictionary for Feature request format.
55+
56+
:rtype: dict
57+
:returns: Dictionary representation of a
58+
:class:`~google.cloud.vision.feature.FeatureType`.
59+
"""
5560
return {
5661
'type': self.feature_type,
5762
'maxResults': self.max_results
5863
}
5964

6065
@property
6166
def feature_type(self):
62-
""""Feature type string."""
67+
""""Feature type string.
68+
69+
:rtype: :class:`~google.cloud.vision.feature.FeatureTypes`
70+
:returns: Instance of
71+
:class:`~google.cloud.vision.feature.FeatureTypes`
72+
"""
6373
return self._feature_type
6474

6575
@property
6676
def max_results(self):
67-
"""Maximum number of results for feature type."""
77+
"""Maximum number of results for feature type.
78+
79+
:rtype: int
80+
:returns: Maxium results to be returned.
81+
"""
6882
return self._max_results

google/cloud/vision/geometry.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616

1717

1818
class BoundsBase(object):
19-
"""Base class for handling bounds with vertices."""
19+
"""Base class for handling bounds with vertices.
20+
21+
:type vertices: list of :class:`~google.cloud.vision.geometry.Vertex`
22+
:param vertcies: List of vertcies describing points on an image.
23+
"""
2024
def __init__(self, vertices):
2125
self._vertices = vertices
2226

@@ -40,17 +44,34 @@ def from_api_repr(cls, response_vertices):
4044
def vertices(self):
4145
"""List of vertices.
4246
43-
:rtype: list
47+
:rtype: list of :class:`~google.cloud.vision.geometry.Vertex`
4448
:returns: List of populated vertices.
4549
"""
4650
return self._vertices
4751

4852

53+
class Bounds(BoundsBase):
54+
"""A polygon boundry of the detected feature."""
55+
56+
57+
class FDBounds(BoundsBase):
58+
"""The bounding polygon of just the skin portion of the face."""
59+
60+
4961
class Position(object):
5062
"""A 3D position in the image.
5163
5264
See:
5365
https://cloud.google.com/vision/reference/rest/v1/images/annotate#Position
66+
67+
:type x_coordinate: float
68+
:param x_coordinate: X position coordinate.
69+
70+
:type y_coordinate: float
71+
:param y_coordinate: Y position coordinate.
72+
73+
:type z_coordinate: float
74+
:param z_coordinate: Z position coordinate.
5475
"""
5576
def __init__(self, x_coordinate, y_coordinate, z_coordinate):
5677
self._x_coordinate = x_coordinate
@@ -102,6 +123,12 @@ class Vertex(object):
102123
103124
See:
104125
https://cloud.google.com/vision/reference/rest/v1/images/annotate#Vertex
126+
127+
:type x_coordinate: float
128+
:param x_coordinate: X position coordinate.
129+
130+
:type y_coordinate: float
131+
:param y_coordinate: Y position coordinate.
105132
"""
106133
def __init__(self, x_coordinate, y_coordinate):
107134
self._x_coordinate = x_coordinate

google/cloud/vision/image.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from base64 import b64encode
1919

2020
from google.cloud._helpers import _to_bytes
21+
from google.cloud.vision.entity import EntityAnnotation
2122
from google.cloud.vision.face import Face
2223
from google.cloud.vision.feature import Feature
2324
from google.cloud.vision.feature import FeatureTypes
@@ -98,3 +99,22 @@ def detect_faces(self, limit=10):
9899
faces.append(face)
99100

100101
return faces
102+
103+
def detect_logos(self, limit=10):
104+
"""Detect logos in an image.
105+
106+
:type limit: int
107+
:param limit: The maximum number of logos to find.
108+
109+
:rtype: list
110+
:returns: List of
111+
:class:`~google.cloud.vision.entity.EntityAnnotation`.
112+
"""
113+
logos = []
114+
logo_detection_feature = Feature(FeatureTypes.LOGO_DETECTION, limit)
115+
result = self.client.annotate(self, [logo_detection_feature])
116+
for logo_response in result['logoAnnotations']:
117+
logo = EntityAnnotation.from_api_repr(logo_response)
118+
logos.append(logo)
119+
120+
return logos

0 commit comments

Comments
 (0)