Skip to content

Commit c741476

Browse files
committed
Add Vision image properties detection.
1 parent 2498573 commit c741476

File tree

7 files changed

+347
-16
lines changed

7 files changed

+347
-16
lines changed

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149

150150
vision-usage
151151
vision-client
152+
vision-color
152153
vision-entity
153154
vision-feature
154155
vision-face

docs/vision-color.rst

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

google/cloud/vision/color.py

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
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+
"""Image properties class representation derived from Vision API response."""
16+
17+
18+
class ImagePropertiesAnnotation(object):
19+
"""Representation of image properties
20+
21+
:type colors: list
22+
:param colors: List of
23+
:class:`~google.cloud.vision.color.ColorInformation`.
24+
"""
25+
def __init__(self, colors):
26+
self._colors = colors
27+
28+
@classmethod
29+
def from_api_repr(cls, response):
30+
"""Factory: construct ``ImagePropertiesAnnotation`` from a response.
31+
32+
:type response: dict
33+
:param response: Dictionary response from Vision API with image
34+
properties data.
35+
36+
:rtype: :class:`~google.cloud.vision.color.ImagePropertiesAnnotation`.
37+
:returns: Populated instance of ``ImagePropertiesAnnotation``.
38+
"""
39+
colors = [ColorInformation.from_api_repr(color) for color in
40+
response['dominantColors']['colors']]
41+
return cls(colors)
42+
43+
@property
44+
def colors(self):
45+
"""Colors in an image.
46+
47+
:rtype: list of :class:`~google.cloud.vision.color.ColorInformation`
48+
:returns: Populated list of ``ColorInformation``.
49+
"""
50+
return self._colors
51+
52+
53+
class Color(object):
54+
"""Representation of RGBA color information.
55+
56+
:type red: int
57+
:param red: The amount of red in the color as a value in the interval
58+
[0, 1].
59+
60+
:type green: int
61+
:param green: The amount of green in the color as a value in the interval
62+
[0, 1].
63+
64+
:type blue: int
65+
:param blue: The amount of blue in the color as a value in the interval
66+
[0, 1].
67+
68+
:type alpha: float
69+
:param alpha: The fraction of this color that should be applied to the
70+
pixel.
71+
"""
72+
def __init__(self, red, green, blue, alpha):
73+
self._red = red
74+
self._green = green
75+
self._blue = blue
76+
self._alpha = alpha
77+
78+
@classmethod
79+
def from_api_repr(cls, response):
80+
"""Factory: construct a ``Color`` from a Vision API response.
81+
82+
:type response: dict
83+
:param response: Color from API Response.
84+
85+
:rtype: :class:`~google.cloud.vision.color.Color`
86+
:returns: Instance of :class:`~google.cloud.vision.color.Color`.
87+
"""
88+
red = response['red']
89+
green = response['green']
90+
blue = response['blue']
91+
alpha = response.get('alpha')
92+
93+
return cls(red, green, blue, alpha)
94+
95+
@property
96+
def red(self):
97+
"""Red color.
98+
99+
:rtype: int
100+
:returns: Red RGB value.
101+
"""
102+
return self._red
103+
104+
@property
105+
def green(self):
106+
"""Green color.
107+
108+
:rtype: int
109+
:returns: Green RGB value.
110+
"""
111+
return self._green
112+
113+
@property
114+
def blue(self):
115+
"""Blue color.
116+
117+
:rtype: int
118+
:returns: Blue RGB value.
119+
"""
120+
return self._blue
121+
122+
@property
123+
def alpha(self):
124+
"""Alpha level.
125+
126+
:rtype: float
127+
:returns: Alpha transparency level.
128+
"""
129+
return self._alpha
130+
131+
132+
class ColorInformation(object):
133+
"""Representation of color information from API response.
134+
135+
:type color: :class:`~google.cloud.vision.color.Color`
136+
:param color: RGB components of the color.
137+
138+
:type score: float
139+
:param score: Image-specific score for this color. Value in range [0, 1].
140+
141+
:type pixel_fraction: float
142+
:param pixel_fraction: Stores the fraction of pixels the color occupies in
143+
the image. Value in range [0, 1].
144+
"""
145+
def __init__(self, color, score, pixel_fraction):
146+
self._color = color
147+
self._score = score
148+
self._pixel_fraction = pixel_fraction
149+
150+
@classmethod
151+
def from_api_repr(cls, response):
152+
"""Factory: construct ``ColorInformation`` for a color found.
153+
154+
:type response: dict
155+
:param response: Color data with extra meta information.
156+
157+
:rtype: :class:`~google.cloud.vision.color.ColorInformation`
158+
:returns: Instance of ``ColorInformation``.
159+
"""
160+
color = Color.from_api_repr(response['color'])
161+
score = response['score']
162+
pixel_fraction = response['pixelFraction']
163+
164+
return cls(color, score, pixel_fraction)
165+
166+
@property
167+
def color(self):
168+
"""RGB components of the color.
169+
170+
:rtype: :class:`~google.vision.color.Color`
171+
:returns: Instance of ``Color``.
172+
"""
173+
return self._color
174+
175+
@property
176+
def score(self):
177+
"""Image-specific score for this color. Value in range [0, 1].
178+
179+
:rtype: float
180+
:returns: Image score for this color.
181+
"""
182+
return self._score
183+
184+
@property
185+
def pixel_fraction(self):
186+
"""Stores the fraction of pixels the color occupies in the image.
187+
188+
:rtype: float
189+
:returns: Pixel fraction value in range [0, 1].
190+
"""
191+
return self._pixel_fraction

google/cloud/vision/feature.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class FeatureTypes(object):
2727
LABEL_DETECTION = 'LABEL_DETECTION'
2828
TEXT_DETECTION = 'TEXT_DETECTION'
2929
SAFE_SEARCH_DETECTION = 'SAFE_SEARCH_DETECTION'
30+
IMAGE_PROPERTIES = 'IMAGE_PROPERTIES'
3031

3132

3233
class Feature(object):

google/cloud/vision/image.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from google.cloud.vision.face import Face
2323
from google.cloud.vision.feature import Feature
2424
from google.cloud.vision.feature import FeatureTypes
25+
from google.cloud.vision.color import ImagePropertiesAnnotation
2526
from google.cloud.vision.safe import SafeSearchAnnotation
2627

2728

@@ -125,22 +126,6 @@ def detect_faces(self, limit=10):
125126

126127
return faces
127128

128-
def detect_safe_search(self, limit=10):
129-
"""Retreive safe search properties from an image.
130-
131-
:type limit: int
132-
:param limit: The number of faces to try and detect.
133-
134-
:rtype: list
135-
:returns: List of
136-
:class:`~google.cloud.vision.sage.SafeSearchAnnotation`.
137-
"""
138-
safe_detection_feature = Feature(FeatureTypes.SAFE_SEARCH_DETECTION,
139-
limit)
140-
result = self.client.annotate(self, [safe_detection_feature])
141-
safe_search_response = result['safeSearchAnnotation']
142-
return SafeSearchAnnotation.from_api_repr(safe_search_response)
143-
144129
def detect_labels(self, limit=10):
145130
"""Detect labels that describe objects in an image.
146131
@@ -179,6 +164,21 @@ def detect_logos(self, limit=10):
179164
feature = Feature(FeatureTypes.LOGO_DETECTION, limit)
180165
return self._detect_annotation(feature)
181166

167+
def detect_properties(self, limit=10):
168+
"""Detect the color properties of an image.
169+
170+
:type limit: int
171+
:param limit: The maximum number of image properties to find.
172+
173+
:rtype: list
174+
:returns: List of
175+
:class:`~google.cloud.vision.color.ImagePropertiesAnnotation`.
176+
"""
177+
feature = Feature(FeatureTypes.IMAGE_PROPERTIES, limit)
178+
result = self.client.annotate(self, [feature])
179+
response = result['imagePropertiesAnnotation']
180+
return ImagePropertiesAnnotation.from_api_repr(response)
181+
182182
def detect_safe_search(self, limit=10):
183183
"""Retreive safe search properties from an image.
184184

unit_tests/vision/_fixtures.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,107 @@
1+
IMAGE_PROPERTIES_RESPONSE = {
2+
'responses': [
3+
{
4+
'imagePropertiesAnnotation': {
5+
'dominantColors': {
6+
'colors': [
7+
{
8+
'color': {
9+
'red': 253,
10+
'green': 203,
11+
'blue': 65,
12+
'alpha': 0.0
13+
},
14+
'score': 0.42258179,
15+
'pixelFraction': 0.025376344
16+
},
17+
{
18+
'color': {
19+
'red': 216,
20+
'green': 69,
21+
'blue': 56
22+
},
23+
'score': 0.34945792,
24+
'pixelFraction': 0.026093191
25+
},
26+
{
27+
'color': {
28+
'red': 79,
29+
'green': 142,
30+
'blue': 245
31+
},
32+
'score': 0.050921876,
33+
'pixelFraction': 0.014193549
34+
},
35+
{
36+
'color': {
37+
'red': 249,
38+
'green': 246,
39+
'blue': 246
40+
},
41+
'score': 0.0059412993,
42+
'pixelFraction': 0.86896056
43+
},
44+
{
45+
'color': {
46+
'red': 222,
47+
'green': 119,
48+
'blue': 51
49+
},
50+
'score': 0.0043299114,
51+
'pixelFraction': 0.00021505376
52+
},
53+
{
54+
'color': {
55+
'red': 226,
56+
'green': 138,
57+
'blue': 130
58+
},
59+
'score': 0.0038594988,
60+
'pixelFraction': 0.00086021505
61+
},
62+
{
63+
'color': {
64+
'red': 165,
65+
'green': 194,
66+
'blue': 243
67+
},
68+
'score': 0.0029492097,
69+
'pixelFraction': 0.0015053763
70+
},
71+
{
72+
'color': {
73+
'red': 231,
74+
'green': 169,
75+
'blue': 164
76+
},
77+
'score': 0.0017002203,
78+
'pixelFraction': 0.00043010752
79+
},
80+
{
81+
'color': {
82+
'red': 137,
83+
'green': 98,
84+
'blue': 142
85+
},
86+
'score': 0.0013974205,
87+
'pixelFraction': 0.00071684585
88+
},
89+
{
90+
'color': {
91+
'red': 239,
92+
'green': 179,
93+
'blue': 56
94+
},
95+
'score': 0.050473157,
96+
'pixelFraction': 0.0022222223
97+
}
98+
]
99+
}
100+
}
101+
}
102+
]
103+
}
104+
1105
LABEL_DETECTION_RESPONSE = {
2106
'responses': [
3107
{

0 commit comments

Comments
 (0)