google-cloud-vision 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/google-cloud-vision.rb +120 -0
- data/lib/google/cloud/vision.rb +477 -0
- data/lib/google/cloud/vision/annotate.rb +235 -0
- data/lib/google/cloud/vision/annotation.rb +449 -0
- data/lib/google/cloud/vision/annotation/entity.rb +228 -0
- data/lib/google/cloud/vision/annotation/face.rb +1512 -0
- data/lib/google/cloud/vision/annotation/properties.rb +222 -0
- data/lib/google/cloud/vision/annotation/safe_search.rb +154 -0
- data/lib/google/cloud/vision/annotation/text.rb +222 -0
- data/lib/google/cloud/vision/annotation/vertex.rb +92 -0
- data/lib/google/cloud/vision/credentials.rb +31 -0
- data/lib/google/cloud/vision/image.rb +578 -0
- data/lib/google/cloud/vision/location.rb +99 -0
- data/lib/google/cloud/vision/project.rb +284 -0
- data/lib/google/cloud/vision/service.rb +75 -0
- data/lib/google/cloud/vision/version.rb +22 -0
- metadata +202 -0
@@ -0,0 +1,235 @@
|
|
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
|
+
|
16
|
+
require "google/cloud/vision/image"
|
17
|
+
require "google/apis/vision_v1"
|
18
|
+
|
19
|
+
module Google
|
20
|
+
module Cloud
|
21
|
+
module Vision
|
22
|
+
##
|
23
|
+
# # Annotate
|
24
|
+
#
|
25
|
+
# Accumulates configuration for an image annotation request. Users
|
26
|
+
# describe the type of Google Cloud Vision API tasks to perform over
|
27
|
+
# images by configuring features such as `faces`, `landmarks`, `text`,
|
28
|
+
# etc. This configuration captures the Cloud Vision API vertical to
|
29
|
+
# operate on and the number of top-scoring results to return.
|
30
|
+
#
|
31
|
+
# See {Project#annotate}.
|
32
|
+
#
|
33
|
+
# @example
|
34
|
+
# require "google/cloud"
|
35
|
+
#
|
36
|
+
# gcloud = Google::Cloud.new
|
37
|
+
# vision = gcloud.vision
|
38
|
+
#
|
39
|
+
# face_image = vision.image "path/to/face.jpg"
|
40
|
+
# landmark_image = vision.image "path/to/landmark.jpg"
|
41
|
+
#
|
42
|
+
# annotation = vision.annotate do |annotate|
|
43
|
+
# annotate.annotate face_image, faces: true, labels: true
|
44
|
+
# annotate.annotate landmark_image, landmarks: true
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# annotation.faces.count #=> 1
|
48
|
+
# annotation.labels.count #=> 4
|
49
|
+
# annotation.landmarks.count #=> 1
|
50
|
+
#
|
51
|
+
class Annotate
|
52
|
+
# @private
|
53
|
+
attr_accessor :requests
|
54
|
+
|
55
|
+
##
|
56
|
+
# @private Creates a new Annotate instance.
|
57
|
+
def initialize project
|
58
|
+
@project = project
|
59
|
+
@requests = []
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Performs detection of Cloud Vision
|
64
|
+
# [features](https://cloud.google.com/vision/reference/rest/v1/images/annotate#Feature)
|
65
|
+
# on the given images. If no options for features are provided, **all**
|
66
|
+
# image detection features will be performed, with a default of `100`
|
67
|
+
# results for faces, landmarks, logos, and labels. If any feature option
|
68
|
+
# is provided, only the specified feature detections will be performed.
|
69
|
+
# Please review [Pricing](https://cloud.google.com/vision/docs/pricing)
|
70
|
+
# before use, as a separate charge is incurred for each feature
|
71
|
+
# performed on an image.
|
72
|
+
#
|
73
|
+
# Cloud Vision sets upper limits on file size as well as on the total
|
74
|
+
# combined size of all images in a request. Reducing your file size can
|
75
|
+
# significantly improve throughput; however, be careful not to reduce
|
76
|
+
# image quality in the process. See [Best Practices - Image
|
77
|
+
# Sizing](https://cloud.google.com/vision/docs/image-best-practices#image_sizing)
|
78
|
+
# for current file size limits.
|
79
|
+
#
|
80
|
+
# See {Project#annotate} for requests that do not involve multiple
|
81
|
+
# feature configurations.
|
82
|
+
#
|
83
|
+
# @see https://cloud.google.com/vision/docs/requests-and-responses Cloud
|
84
|
+
# Vision API Requests and Responses
|
85
|
+
# @see https://cloud.google.com/vision/reference/rest/v1/images/annotate#AnnotateImageRequest
|
86
|
+
# AnnotateImageRequest
|
87
|
+
# @see https://cloud.google.com/vision/docs/pricing Cloud Vision Pricing
|
88
|
+
#
|
89
|
+
# @param [Image, Object] images The image or images to annotate. This
|
90
|
+
# can be an {Image} instance, or any other type that converts to an
|
91
|
+
# {Image}. See {#image} for details.
|
92
|
+
# @param [Boolean, Integer] faces Whether to perform the facial
|
93
|
+
# detection feature. The maximum number of results is configured in
|
94
|
+
# {Google::Cloud::Vision.default_max_faces}, or may be provided here.
|
95
|
+
# Optional.
|
96
|
+
# @param [Boolean, Integer] landmarks Whether to perform the landmark
|
97
|
+
# detection feature. The maximum number of results is configured in
|
98
|
+
# {Google::Cloud::Vision.default_max_landmarks}, or may be provided
|
99
|
+
# here. Optional.
|
100
|
+
# @param [Boolean, Integer] logos Whether to perform the logo detection
|
101
|
+
# feature. The maximum number of results is configured in
|
102
|
+
# {Google::Cloud::Vision.default_max_logos}, or may be provided here.
|
103
|
+
# Optional.
|
104
|
+
# @param [Boolean, Integer] labels Whether to perform the label
|
105
|
+
# detection feature. The maximum number of results is configured in
|
106
|
+
# {Google::Cloud::Vision.default_max_labels}, or may be provided here.
|
107
|
+
# Optional.
|
108
|
+
# @param [Boolean] text Whether to perform the text (OCR) feature.
|
109
|
+
# Optional.
|
110
|
+
# @param [Boolean] safe_search Whether to perform the safe search
|
111
|
+
# feature. Optional.
|
112
|
+
# @param [Boolean] properties Whether to perform the image properties
|
113
|
+
# feature (currently, the image's dominant colors.) Optional.
|
114
|
+
#
|
115
|
+
# @return [Annotation, Array<Annotation>] The results for all image
|
116
|
+
# detections, returned as a single {Annotation} instance for one
|
117
|
+
# image, or as an array of {Annotation} instances, one per image, for
|
118
|
+
# multiple images.
|
119
|
+
#
|
120
|
+
# @example
|
121
|
+
# require "google/cloud"
|
122
|
+
#
|
123
|
+
# gcloud = Google::Cloud.new
|
124
|
+
# vision = gcloud.vision
|
125
|
+
#
|
126
|
+
# face_image = vision.image "path/to/face.jpg"
|
127
|
+
# landmark_image = vision.image "path/to/landmark.jpg"
|
128
|
+
# text_image = vision.image "path/to/text.png"
|
129
|
+
#
|
130
|
+
# annotations = vision.annotate do |annotate|
|
131
|
+
# annotate.annotate face_image, faces: true, labels: true
|
132
|
+
# annotate.annotate landmark_image, landmarks: true
|
133
|
+
# annotate.annotate text_image, text: true
|
134
|
+
# end
|
135
|
+
#
|
136
|
+
# annotations[0].faces.count #=> 1
|
137
|
+
# annotations[0].labels.count #=> 4
|
138
|
+
# annotations[1].landmarks.count #=> 1
|
139
|
+
# annotations[2].text.words.count #=> 28
|
140
|
+
#
|
141
|
+
def annotate *images, faces: false, landmarks: false, logos: false,
|
142
|
+
labels: false, text: false, safe_search: false,
|
143
|
+
properties: false
|
144
|
+
add_requests(images, faces, landmarks, logos, labels, text,
|
145
|
+
safe_search, properties)
|
146
|
+
end
|
147
|
+
|
148
|
+
protected
|
149
|
+
|
150
|
+
def image source
|
151
|
+
return source if source.is_a? Image
|
152
|
+
Image.from_source source, @project
|
153
|
+
end
|
154
|
+
|
155
|
+
def add_requests images, faces, landmarks, logos, labels, text,
|
156
|
+
safe_search, properties
|
157
|
+
features = annotate_features(faces, landmarks, logos, labels, text,
|
158
|
+
safe_search, properties)
|
159
|
+
|
160
|
+
Array(images).flatten.each do |img|
|
161
|
+
i = image(img)
|
162
|
+
@requests << Google::Apis::VisionV1::AnnotateImageRequest.new(
|
163
|
+
image: i.to_gapi,
|
164
|
+
features: features,
|
165
|
+
imageContext: i.context.to_gapi
|
166
|
+
)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def annotate_features faces, landmarks, logos, labels, text,
|
171
|
+
safe_search, properties
|
172
|
+
return default_features if default_features?(
|
173
|
+
faces, landmarks, logos, labels, text, safe_search, properties)
|
174
|
+
|
175
|
+
faces, landmarks, logos, labels = validate_max_values(
|
176
|
+
faces, landmarks, logos, labels)
|
177
|
+
|
178
|
+
f = []
|
179
|
+
f << feature("FACE_DETECTION", faces) unless faces.zero?
|
180
|
+
f << feature("LANDMARK_DETECTION", landmarks) unless landmarks.zero?
|
181
|
+
f << feature("LOGO_DETECTION", logos) unless logos.zero?
|
182
|
+
f << feature("LABEL_DETECTION", labels) unless labels.zero?
|
183
|
+
f << feature("TEXT_DETECTION", 1) if text
|
184
|
+
f << feature("SAFE_SEARCH_DETECTION", 1) if safe_search
|
185
|
+
f << feature("IMAGE_PROPERTIES", 1) if properties
|
186
|
+
f
|
187
|
+
end
|
188
|
+
|
189
|
+
def feature type, max_results
|
190
|
+
Google::Apis::VisionV1::Feature.new(
|
191
|
+
type: type, max_results: max_results)
|
192
|
+
end
|
193
|
+
|
194
|
+
def default_features? faces, landmarks, logos, labels, text,
|
195
|
+
safe_search, properties
|
196
|
+
faces == false && landmarks == false && logos == false &&
|
197
|
+
labels == false && text == false && safe_search == false &&
|
198
|
+
properties == false
|
199
|
+
end
|
200
|
+
|
201
|
+
def default_features
|
202
|
+
[
|
203
|
+
feature("FACE_DETECTION", Google::Cloud::Vision.default_max_faces),
|
204
|
+
feature("LANDMARK_DETECTION",
|
205
|
+
Google::Cloud::Vision.default_max_landmarks),
|
206
|
+
feature("LOGO_DETECTION", Google::Cloud::Vision.default_max_logos),
|
207
|
+
feature("LABEL_DETECTION",
|
208
|
+
Google::Cloud::Vision.default_max_labels),
|
209
|
+
feature("TEXT_DETECTION", 1),
|
210
|
+
feature("SAFE_SEARCH_DETECTION", 1),
|
211
|
+
feature("IMAGE_PROPERTIES", 1)
|
212
|
+
]
|
213
|
+
end
|
214
|
+
|
215
|
+
def validate_max_values faces, landmarks, logos, labels
|
216
|
+
faces = validate_max_value(
|
217
|
+
faces, Google::Cloud::Vision.default_max_faces)
|
218
|
+
landmarks = validate_max_value(
|
219
|
+
landmarks, Google::Cloud::Vision.default_max_landmarks)
|
220
|
+
logos = validate_max_value(
|
221
|
+
logos, Google::Cloud::Vision.default_max_logos)
|
222
|
+
labels = validate_max_value(
|
223
|
+
labels, Google::Cloud::Vision.default_max_labels)
|
224
|
+
[faces, landmarks, logos, labels]
|
225
|
+
end
|
226
|
+
|
227
|
+
def validate_max_value value, default_value
|
228
|
+
return value.to_int if value.respond_to? :to_int
|
229
|
+
return default_value if value
|
230
|
+
0 # not a number, not a truthy value
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
@@ -0,0 +1,449 @@
|
|
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
|
+
|
16
|
+
require "google/cloud/vision/annotation/face"
|
17
|
+
require "google/cloud/vision/annotation/entity"
|
18
|
+
require "google/cloud/vision/annotation/text"
|
19
|
+
require "google/cloud/vision/annotation/safe_search"
|
20
|
+
require "google/cloud/vision/annotation/properties"
|
21
|
+
|
22
|
+
module Google
|
23
|
+
module Cloud
|
24
|
+
module Vision
|
25
|
+
##
|
26
|
+
# # Annotation
|
27
|
+
#
|
28
|
+
# The results of all requested image annotations.
|
29
|
+
#
|
30
|
+
# See {Project#annotate} and {Image}.
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# require "google/cloud"
|
34
|
+
#
|
35
|
+
# gcloud = Google::Cloud.new
|
36
|
+
# vision = gcloud.vision
|
37
|
+
# image = vision.image "path/to/face.jpg"
|
38
|
+
#
|
39
|
+
# annotation = vision.annotate image, faces: true, labels: true
|
40
|
+
# annotation.faces.count #=> 1
|
41
|
+
# annotation.labels.count #=> 4
|
42
|
+
# annotation.text #=> nil
|
43
|
+
#
|
44
|
+
class Annotation
|
45
|
+
##
|
46
|
+
# @private The AnnotateImageResponse Google API Client object.
|
47
|
+
attr_accessor :gapi
|
48
|
+
|
49
|
+
##
|
50
|
+
# @private Creates a new Annotation instance.
|
51
|
+
def initialize
|
52
|
+
@gapi = nil
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# The results of face detection.
|
57
|
+
#
|
58
|
+
# @return [Array<Face>]
|
59
|
+
#
|
60
|
+
# @example
|
61
|
+
# require "google/cloud"
|
62
|
+
#
|
63
|
+
# gcloud = Google::Cloud.new
|
64
|
+
# vision = gcloud.vision
|
65
|
+
# image = vision.image "path/to/face.jpg"
|
66
|
+
#
|
67
|
+
# annotation = vision.annotate image, faces: true
|
68
|
+
# annotation.faces.count #=> 1
|
69
|
+
# face = annotation.faces.first
|
70
|
+
#
|
71
|
+
def faces
|
72
|
+
@faces ||= Array(@gapi.face_annotations).map do |fa|
|
73
|
+
Face.from_gapi fa
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# The first face result, if there is one.
|
79
|
+
#
|
80
|
+
# @return [Face]
|
81
|
+
#
|
82
|
+
# @example
|
83
|
+
# require "google/cloud"
|
84
|
+
#
|
85
|
+
# gcloud = Google::Cloud.new
|
86
|
+
# vision = gcloud.vision
|
87
|
+
# image = vision.image "path/to/face.jpg"
|
88
|
+
#
|
89
|
+
# annotation = vision.annotate image, faces: 1
|
90
|
+
# face = annotation.face
|
91
|
+
#
|
92
|
+
def face
|
93
|
+
faces.first
|
94
|
+
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# Whether there is at least one result from face detection.
|
98
|
+
#
|
99
|
+
# @return [Boolean]
|
100
|
+
#
|
101
|
+
# @example
|
102
|
+
# require "google/cloud"
|
103
|
+
#
|
104
|
+
# gcloud = Google::Cloud.new
|
105
|
+
# vision = gcloud.vision
|
106
|
+
# image = vision.image "path/to/face.jpg"
|
107
|
+
#
|
108
|
+
# annotation = vision.annotate image, faces: 1
|
109
|
+
# annotation.face? #=> true
|
110
|
+
#
|
111
|
+
def face?
|
112
|
+
faces.count > 0
|
113
|
+
end
|
114
|
+
|
115
|
+
##
|
116
|
+
# The results of landmark detection.
|
117
|
+
#
|
118
|
+
# @return [Array<Entity>]
|
119
|
+
#
|
120
|
+
# @example
|
121
|
+
# require "google/cloud"
|
122
|
+
#
|
123
|
+
# gcloud = Google::Cloud.new
|
124
|
+
# vision = gcloud.vision
|
125
|
+
# image = vision.image "path/to/landmark.jpg"
|
126
|
+
#
|
127
|
+
# annotation = vision.annotate image, landmarks: 1
|
128
|
+
# annotation.landmarks.count #=> 1
|
129
|
+
# landmark = annotation.landmarks.first
|
130
|
+
#
|
131
|
+
def landmarks
|
132
|
+
@landmarks ||= Array(@gapi.landmark_annotations).map do |lm|
|
133
|
+
Entity.from_gapi lm
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
##
|
138
|
+
# The first landmark result, if there is one.
|
139
|
+
#
|
140
|
+
# @return [Entity]
|
141
|
+
#
|
142
|
+
# @example
|
143
|
+
# require "google/cloud"
|
144
|
+
#
|
145
|
+
# gcloud = Google::Cloud.new
|
146
|
+
# vision = gcloud.vision
|
147
|
+
# image = vision.image "path/to/landmark.jpg"
|
148
|
+
#
|
149
|
+
# annotation = vision.annotate image, landmarks: 1
|
150
|
+
# landmark = annotation.landmark
|
151
|
+
#
|
152
|
+
def landmark
|
153
|
+
landmarks.first
|
154
|
+
end
|
155
|
+
|
156
|
+
##
|
157
|
+
# Whether there is at least one result from landmark detection.
|
158
|
+
# detection.
|
159
|
+
#
|
160
|
+
# @return [Boolean]
|
161
|
+
#
|
162
|
+
# @example
|
163
|
+
# require "google/cloud"
|
164
|
+
#
|
165
|
+
# gcloud = Google::Cloud.new
|
166
|
+
# vision = gcloud.vision
|
167
|
+
# image = vision.image "path/to/landmark.jpg"
|
168
|
+
#
|
169
|
+
# annotation = vision.annotate image, landmarks: 1
|
170
|
+
# annotation.landmark? #=> true
|
171
|
+
#
|
172
|
+
def landmark?
|
173
|
+
landmarks.count > 0
|
174
|
+
end
|
175
|
+
|
176
|
+
##
|
177
|
+
# The results of logo detection.
|
178
|
+
#
|
179
|
+
# @return [Array<Entity>]
|
180
|
+
#
|
181
|
+
# @example
|
182
|
+
# require "google/cloud"
|
183
|
+
#
|
184
|
+
# gcloud = Google::Cloud.new
|
185
|
+
# vision = gcloud.vision
|
186
|
+
# image = vision.image "path/to/logo.jpg"
|
187
|
+
#
|
188
|
+
# annotation = vision.annotate image, logos: 1
|
189
|
+
# annotation.logos.count #=> 1
|
190
|
+
# logo = annotation.logos.first
|
191
|
+
#
|
192
|
+
def logos
|
193
|
+
@logos ||= Array(@gapi.logo_annotations).map do |lg|
|
194
|
+
Entity.from_gapi lg
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
##
|
199
|
+
# The first logo result, if there is one.
|
200
|
+
#
|
201
|
+
# @return [Entity]
|
202
|
+
#
|
203
|
+
# @example
|
204
|
+
# require "google/cloud"
|
205
|
+
#
|
206
|
+
# gcloud = Google::Cloud.new
|
207
|
+
# vision = gcloud.vision
|
208
|
+
# image = vision.image "path/to/logo.jpg"
|
209
|
+
#
|
210
|
+
# annotation = vision.annotate image, logos: 1
|
211
|
+
# logo = annotation.logo
|
212
|
+
#
|
213
|
+
def logo
|
214
|
+
logos.first
|
215
|
+
end
|
216
|
+
|
217
|
+
##
|
218
|
+
# Whether there is at least one result from logo detection.
|
219
|
+
# detection.
|
220
|
+
#
|
221
|
+
# @return [Boolean]
|
222
|
+
#
|
223
|
+
# @example
|
224
|
+
# require "google/cloud"
|
225
|
+
#
|
226
|
+
# gcloud = Google::Cloud.new
|
227
|
+
# vision = gcloud.vision
|
228
|
+
# image = vision.image "path/to/logo.jpg"
|
229
|
+
#
|
230
|
+
# annotation = vision.annotate image, logos: 1
|
231
|
+
# annotation.logo? #=> true
|
232
|
+
#
|
233
|
+
def logo?
|
234
|
+
logos.count > 0
|
235
|
+
end
|
236
|
+
|
237
|
+
##
|
238
|
+
# The results of label detection.
|
239
|
+
#
|
240
|
+
# @return [Array<Entity>]
|
241
|
+
#
|
242
|
+
# @example
|
243
|
+
# require "google/cloud"
|
244
|
+
#
|
245
|
+
# gcloud = Google::Cloud.new
|
246
|
+
# vision = gcloud.vision
|
247
|
+
# image = vision.image "path/to/face.jpg"
|
248
|
+
#
|
249
|
+
# annotation = vision.annotate image, labels: 1
|
250
|
+
# annotation.labels.count #=> 1
|
251
|
+
# label = annotation.labels.first
|
252
|
+
#
|
253
|
+
def labels
|
254
|
+
@labels ||= Array(@gapi.label_annotations).map do |lb|
|
255
|
+
Entity.from_gapi lb
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
##
|
260
|
+
# The first label result, if there is one.
|
261
|
+
#
|
262
|
+
# @return [Entity]
|
263
|
+
#
|
264
|
+
# @example
|
265
|
+
# require "google/cloud"
|
266
|
+
#
|
267
|
+
# gcloud = Google::Cloud.new
|
268
|
+
# vision = gcloud.vision
|
269
|
+
# image = vision.image "path/to/face.jpg"
|
270
|
+
#
|
271
|
+
# annotation = vision.annotate image, labels: 1
|
272
|
+
# label = annotation.label
|
273
|
+
#
|
274
|
+
def label
|
275
|
+
labels.first
|
276
|
+
end
|
277
|
+
|
278
|
+
##
|
279
|
+
# Whether there is at least one result from label detection.
|
280
|
+
# detection.
|
281
|
+
#
|
282
|
+
# @return [Boolean]
|
283
|
+
#
|
284
|
+
# @example
|
285
|
+
# require "google/cloud"
|
286
|
+
#
|
287
|
+
# gcloud = Google::Cloud.new
|
288
|
+
# vision = gcloud.vision
|
289
|
+
# image = vision.image "path/to/face.jpg"
|
290
|
+
#
|
291
|
+
# annotation = vision.annotate image, labels: 1
|
292
|
+
# annotation.label? #=> true
|
293
|
+
#
|
294
|
+
def label?
|
295
|
+
labels.count > 0
|
296
|
+
end
|
297
|
+
|
298
|
+
##
|
299
|
+
# The results of text (OCR) detection.
|
300
|
+
#
|
301
|
+
# @return [Text]
|
302
|
+
#
|
303
|
+
# @example
|
304
|
+
# require "google/cloud"
|
305
|
+
#
|
306
|
+
# gcloud = Google::Cloud.new
|
307
|
+
# vision = gcloud.vision
|
308
|
+
# image = vision.image "path/to/text.png"
|
309
|
+
#
|
310
|
+
# annotation = vision.annotate image, text: true
|
311
|
+
# text = annotation.text
|
312
|
+
#
|
313
|
+
def text
|
314
|
+
@text ||= Text.from_gapi(@gapi.text_annotations)
|
315
|
+
end
|
316
|
+
|
317
|
+
##
|
318
|
+
# Whether there is a result from text (OCR) detection.
|
319
|
+
#
|
320
|
+
# @return [Boolean]
|
321
|
+
#
|
322
|
+
# @example
|
323
|
+
# require "google/cloud"
|
324
|
+
#
|
325
|
+
# gcloud = Google::Cloud.new
|
326
|
+
# vision = gcloud.vision
|
327
|
+
# image = vision.image "path/to/text.png"
|
328
|
+
#
|
329
|
+
# annotation = vision.annotate image, text: true
|
330
|
+
# annotation.text? #=> true
|
331
|
+
#
|
332
|
+
def text?
|
333
|
+
!text.nil?
|
334
|
+
end
|
335
|
+
|
336
|
+
##
|
337
|
+
# The results of safe_search detection.
|
338
|
+
#
|
339
|
+
# @return [SafeSearch]
|
340
|
+
#
|
341
|
+
# @example
|
342
|
+
# require "google/cloud"
|
343
|
+
#
|
344
|
+
# gcloud = Google::Cloud.new
|
345
|
+
# vision = gcloud.vision
|
346
|
+
# image = vision.image "path/to/face.jpg"
|
347
|
+
#
|
348
|
+
# annotation = vision.annotate image, safe_search: true
|
349
|
+
# safe_search = annotation.safe_search
|
350
|
+
#
|
351
|
+
def safe_search
|
352
|
+
return nil unless @gapi.safe_search_annotation
|
353
|
+
@safe_search ||= SafeSearch.from_gapi(@gapi.safe_search_annotation)
|
354
|
+
end
|
355
|
+
|
356
|
+
##
|
357
|
+
# Whether there is a result for safe_search detection.
|
358
|
+
# detection.
|
359
|
+
#
|
360
|
+
# @return [Boolean]
|
361
|
+
#
|
362
|
+
# @example
|
363
|
+
# require "google/cloud"
|
364
|
+
#
|
365
|
+
# gcloud = Google::Cloud.new
|
366
|
+
# vision = gcloud.vision
|
367
|
+
# image = vision.image "path/to/face.jpg"
|
368
|
+
#
|
369
|
+
# annotation = vision.annotate image, safe_search: true
|
370
|
+
# annotation.safe_search? #=> true
|
371
|
+
#
|
372
|
+
def safe_search?
|
373
|
+
!safe_search.nil?
|
374
|
+
end
|
375
|
+
|
376
|
+
##
|
377
|
+
# The results of properties detection.
|
378
|
+
#
|
379
|
+
# @return [Properties]
|
380
|
+
#
|
381
|
+
# @example
|
382
|
+
# require "google/cloud"
|
383
|
+
#
|
384
|
+
# gcloud = Google::Cloud.new
|
385
|
+
# vision = gcloud.vision
|
386
|
+
# image = vision.image "path/to/face.jpg"
|
387
|
+
#
|
388
|
+
# annotation = vision.annotate image, properties: true
|
389
|
+
# properties = annotation.properties
|
390
|
+
#
|
391
|
+
def properties
|
392
|
+
return nil unless @gapi.image_properties_annotation
|
393
|
+
@properties ||= Properties.from_gapi(
|
394
|
+
@gapi.image_properties_annotation)
|
395
|
+
end
|
396
|
+
|
397
|
+
##
|
398
|
+
# Whether there is a result for properties detection.
|
399
|
+
#
|
400
|
+
# @return [Boolean]
|
401
|
+
#
|
402
|
+
# @example
|
403
|
+
# require "google/cloud"
|
404
|
+
#
|
405
|
+
# gcloud = Google::Cloud.new
|
406
|
+
# vision = gcloud.vision
|
407
|
+
# image = vision.image "path/to/face.jpg"
|
408
|
+
#
|
409
|
+
# annotation = vision.annotate image, properties: true
|
410
|
+
# annotation.properties? #=> true
|
411
|
+
#
|
412
|
+
def properties?
|
413
|
+
!properties.nil?
|
414
|
+
end
|
415
|
+
|
416
|
+
##
|
417
|
+
# Deeply converts object to a hash. All keys will be symbolized.
|
418
|
+
#
|
419
|
+
# @return [Hash]
|
420
|
+
#
|
421
|
+
def to_h
|
422
|
+
{ faces: faces.map(&:to_h), landmarks: landmarks.map(&:to_h),
|
423
|
+
logos: logos.map(&:to_h), labels: labels.map(&:to_h),
|
424
|
+
text: text.map(&:to_h), safe_search: safe_search.to_h,
|
425
|
+
properties: properties.to_h }
|
426
|
+
end
|
427
|
+
|
428
|
+
# @private
|
429
|
+
def to_s
|
430
|
+
tmplt = "(faces: %i, landmarks: %i, logos: %i, labels: %i," \
|
431
|
+
" text: %s, safe_search: %s, properties: %s)"
|
432
|
+
format tmplt, faces.count, landmarks.count, logos.count, labels.count,
|
433
|
+
text?, safe_search?, properties?
|
434
|
+
end
|
435
|
+
|
436
|
+
# @private
|
437
|
+
def inspect
|
438
|
+
"#<#{self.class.name} #{self}>"
|
439
|
+
end
|
440
|
+
|
441
|
+
##
|
442
|
+
# @private New Annotation from a Google API Client object.
|
443
|
+
def self.from_gapi gapi
|
444
|
+
new.tap { |a| a.instance_variable_set :@gapi, gapi }
|
445
|
+
end
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
449
|
+
end
|