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.
@@ -0,0 +1,99 @@
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
+ module Google
17
+ module Cloud
18
+ module Vision
19
+ ##
20
+ # # Location
21
+ #
22
+ # A latitude/longitude pair with values conforming to the [WGS84
23
+ # standard](http://www.unoosa.org/pdf/icg/2012/template/WGS_84.pdf).
24
+ #
25
+ # @attr [Float] latitude The degrees latitude conforming to the [WGS84
26
+ # standard](http://www.unoosa.org/pdf/icg/2012/template/WGS_84.pdf).
27
+ # @attr [Float] longitude The degrees longitude conforming to the [WGS84
28
+ # standard](http://www.unoosa.org/pdf/icg/2012/template/WGS_84.pdf).
29
+ #
30
+ # @example
31
+ # require "google/cloud"
32
+ #
33
+ # gcloud = Google::Cloud.new
34
+ # vision = gcloud.vision
35
+ #
36
+ # image = vision.image "path/to/landmark.jpg"
37
+ # entity = image.landmark
38
+ #
39
+ # location = entity.locations.first
40
+ #
41
+ # location.latitude #=> 43.878264
42
+ # location.longitude #=> -103.45700740814209
43
+ #
44
+ class Location
45
+ attr_accessor :latitude, :longitude
46
+
47
+ ##
48
+ # @private Creates a new Location instance.
49
+ def initialize latitude, longitude
50
+ @latitude = latitude
51
+ @longitude = longitude
52
+ end
53
+
54
+ ##
55
+ # Returns the object's property values as an array.
56
+ #
57
+ # @return [Array]
58
+ #
59
+ def to_a
60
+ [latitude, longitude]
61
+ end
62
+
63
+ ##
64
+ # Converts object to a hash. All keys will be symbolized.
65
+ #
66
+ # @return [Hash]
67
+ #
68
+ def to_h
69
+ { latitude: latitude, longitude: longitude }
70
+ end
71
+
72
+ # @private
73
+ def to_s
74
+ "(latitude: #{latitude.inspect}, longitude: #{longitude.inspect})"
75
+ end
76
+
77
+ # @private
78
+ def inspect
79
+ "#<#{self.class.name} #{self}>"
80
+ end
81
+
82
+ ##
83
+ # @private New Google API Client LatLng object.
84
+ def to_gapi
85
+ Google::Apis::VisionV1::LatLng.new(
86
+ latitude: latitude,
87
+ longitude: longitude
88
+ )
89
+ end
90
+
91
+ ##
92
+ # @private New Location from a Google API Client LatLng object.
93
+ def self.from_gapi gapi
94
+ new gapi.latitude, gapi.longitude
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,284 @@
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/errors"
17
+ require "google/cloud/core/gce"
18
+ require "google/cloud/vision/service"
19
+ require "google/cloud/vision/credentials"
20
+ require "google/cloud/vision/annotate"
21
+ require "google/cloud/vision/image"
22
+ require "google/cloud/vision/annotation"
23
+
24
+ module Google
25
+ module Cloud
26
+ module Vision
27
+ ##
28
+ # # Project
29
+ #
30
+ # Google Cloud Vision allows easy integration of vision detection features
31
+ # within developer applications, including image labeling, face and
32
+ # landmark detection, optical character recognition (OCR), and tagging of
33
+ # explicit content.
34
+ #
35
+ # @example
36
+ # require "google/cloud"
37
+ #
38
+ # gcloud = Google::Cloud.new
39
+ # vision = gcloud.vision
40
+ #
41
+ # image = vision.image "path/to/landmark.jpg"
42
+ #
43
+ # annotation = vision.annotate image, labels: true
44
+ #
45
+ # annotation.labels.map &:description
46
+ # #=> ["stone carving", "ancient history", "statue", "sculpture",
47
+ # #=> "monument", "landmark"]
48
+ #
49
+ # See Google::Cloud#vision
50
+ class Project
51
+ ##
52
+ # @private The Service object.
53
+ attr_accessor :service
54
+
55
+ ##
56
+ # @private Creates a new Project instance.
57
+ def initialize service
58
+ @service = service
59
+ end
60
+
61
+ # The Vision project connected to.
62
+ #
63
+ # @example
64
+ # require "google/cloud"
65
+ #
66
+ # gcloud = Google::Cloud.new "my-todo-project",
67
+ # "/path/to/keyfile.json"
68
+ # vision = gcloud.vision
69
+ #
70
+ # vision.project #=> "my-todo-project"
71
+ #
72
+ def project
73
+ service.project
74
+ end
75
+
76
+ ##
77
+ # @private Default project.
78
+ def self.default_project
79
+ ENV["VISION_PROJECT"] ||
80
+ ENV["GOOGLE_CLOUD_PROJECT"] ||
81
+ ENV["GCLOUD_PROJECT"] ||
82
+ Google::Cloud::Core::GCE.project_id
83
+ end
84
+
85
+ ##
86
+ # Returns a new image from the given source.
87
+ #
88
+ # Cloud Vision sets upper limits on file size as well as on the total
89
+ # combined size of all images in a request. Reducing your file size can
90
+ # significantly improve throughput; however, be careful not to reduce
91
+ # image quality in the process. See [Best Practices - Image
92
+ # Sizing](https://cloud.google.com/vision/docs/image-best-practices#image_sizing)
93
+ # for current file size limits.
94
+ #
95
+ # Note that an object in Google Cloud Storage is a single entity;
96
+ # permissions affect only that object. "Directory permissions" do not
97
+ # exist (though default bucket permissions do exist). Make sure the code
98
+ # which performs your request has access to that image.
99
+ #
100
+ # @see https://cloud.google.com/vision/docs/image-best-practices Best
101
+ # Practices
102
+ #
103
+ # @param [String, IO, StringIO, Tempfile, Google::Cloud::Storage::File]
104
+ # source A string file path or Cloud Storage URI of the form
105
+ # `"gs://bucketname/path/to/image_filename"`; or a File, IO, StringIO,
106
+ # or Tempfile instance; or an instance of
107
+ # Google::Cloud::Storage::File.
108
+ #
109
+ # @return [Image] An image for the Vision service.
110
+ #
111
+ # @example With a Google Cloud Storage URI:
112
+ # require "google/cloud"
113
+ #
114
+ # gcloud = Google::Cloud.new
115
+ # vision = gcloud.vision
116
+ #
117
+ # image = vision.image "gs://bucket-name/path_to_image_object"
118
+ #
119
+ # @example With a local file path:
120
+ # require "google/cloud"
121
+ #
122
+ # gcloud = Google::Cloud.new
123
+ # vision = gcloud.vision
124
+ #
125
+ # image = vision.image "path/to/landmark.jpg"
126
+ #
127
+ def image source
128
+ return source if source.is_a? Image
129
+ Image.from_source source, self
130
+ end
131
+
132
+ ##
133
+ # Performs detection of Cloud Vision
134
+ # [features](https://cloud.google.com/vision/reference/rest/v1/images/annotate#Feature)
135
+ # on the given image(s). If no options for features are provided,
136
+ # **all** image detection features will be performed, with a default of
137
+ # `100` results for faces, landmarks, logos, and labels. If any feature
138
+ # option is provided, only the specified feature detections will be
139
+ # performed. Please review
140
+ # [Pricing](https://cloud.google.com/vision/docs/pricing) before use, as
141
+ # a separate charge is incurred for each feature performed on an image.
142
+ #
143
+ # Cloud Vision sets upper limits on file size as well as on the total
144
+ # combined size of all images in a request. Reducing your file size can
145
+ # significantly improve throughput; however, be careful not to reduce
146
+ # image quality in the process. See [Best Practices - Image
147
+ # Sizing](https://cloud.google.com/vision/docs/image-best-practices#image_sizing)
148
+ # for current file size limits.
149
+ #
150
+ # @see https://cloud.google.com/vision/docs/requests-and-responses Cloud
151
+ # Vision API Requests and Responses
152
+ # @see https://cloud.google.com/vision/reference/rest/v1/images/annotate#AnnotateImageRequest
153
+ # AnnotateImageRequest
154
+ # @see https://cloud.google.com/vision/docs/pricing Cloud Vision Pricing
155
+ #
156
+ # @param [Image, Object] images The image or images to annotate. This
157
+ # can be an {Image} instance, or any other type that converts to an
158
+ # {Image}. See {#image} for details.
159
+ # @param [Boolean, Integer] faces Whether to perform the facial
160
+ # detection feature. The maximum number of results is configured in
161
+ # {Google::Cloud::Vision.default_max_faces}, or may be provided here.
162
+ # Optional.
163
+ # @param [Boolean, Integer] landmarks Whether to perform the landmark
164
+ # detection feature. The maximum number of results is configured in
165
+ # {Google::Cloud::Vision.default_max_landmarks}, or may be provided
166
+ # here. Optional.
167
+ # @param [Boolean, Integer] logos Whether to perform the logo detection
168
+ # feature. The maximum number of results is configured in
169
+ # {Google::Cloud::Vision.default_max_logos}, or may be provided here.
170
+ # Optional.
171
+ # @param [Boolean, Integer] labels Whether to perform the label
172
+ # detection feature. The maximum number of results is configured in
173
+ # {Google::Cloud::Vision.default_max_labels}, or may be provided here.
174
+ # Optional.
175
+ # @param [Boolean] text Whether to perform the text (OCR) feature.
176
+ # Optional.
177
+ # @param [Boolean] safe_search Whether to perform the safe search
178
+ # feature. Optional.
179
+ # @param [Boolean] properties Whether to perform the image properties
180
+ # feature (currently, the image's dominant colors.) Optional.
181
+ #
182
+ # @yield [annotate] A block for requests that involve multiple feature
183
+ # configurations. See {Annotate#annotate}.
184
+ # @yieldparam [Annotate] annotate the Annotate object
185
+ #
186
+ # @return [Annotation, Array<Annotation>] The results for all image
187
+ # detections, returned as a single {Annotation} instance for one
188
+ # image, or as an array of {Annotation} instances, one per image, for
189
+ # multiple images.
190
+ #
191
+ # @example With a single image:
192
+ # require "google/cloud"
193
+ #
194
+ # gcloud = Google::Cloud.new
195
+ # vision = gcloud.vision
196
+ #
197
+ # image = vision.image "path/to/landmark.jpg"
198
+ #
199
+ # annotation = vision.annotate image, labels: true
200
+ #
201
+ # annotation.labels.map &:description
202
+ # #=> ["stone carving", "ancient history", "statue", "sculpture",
203
+ # #=> "monument", "landmark"]
204
+ #
205
+ # @example With multiple images:
206
+ # require "google/cloud"
207
+ #
208
+ # gcloud = Google::Cloud.new
209
+ # vision = gcloud.vision
210
+ #
211
+ # face_img = vision.image "path/to/face.jpg"
212
+ # landmark_img = vision.image "path/to/landmark.jpg"
213
+ #
214
+ # annotations = vision.annotate face_img, landmark_img, labels: true
215
+ #
216
+ # annotations[0].labels.count #=> 4
217
+ # annotations[1].labels.count #=> 6
218
+ #
219
+ # @example With multiple images and configurations passed in a block:
220
+ # require "google/cloud"
221
+ #
222
+ # gcloud = Google::Cloud.new
223
+ # vision = gcloud.vision
224
+ #
225
+ # face_img = vision.image "path/to/face.jpg"
226
+ # landmark_img = vision.image "path/to/landmark.jpg"
227
+ # text_image = vision.image "path/to/text.png"
228
+ #
229
+ # annotations = vision.annotate do |annotate|
230
+ # annotate.annotate face_img, faces: true, labels: true
231
+ # annotate.annotate landmark_img, landmarks: true
232
+ # annotate.annotate text_image, text: true
233
+ # end
234
+ #
235
+ # annotations[0].faces.count #=> 1
236
+ # annotations[0].labels.count #=> 4
237
+ # annotations[1].landmarks.count #=> 1
238
+ # annotations[2].text.words.count #=> 28
239
+ #
240
+ # @example Maximum result values can also be provided:
241
+ # require "google/cloud"
242
+ #
243
+ # gcloud = Google::Cloud.new
244
+ # vision = gcloud.vision
245
+ #
246
+ # image = vision.image "path/to/landmark.jpg"
247
+ #
248
+ # annotation = vision.annotate image, labels: 3
249
+ #
250
+ # annotation.labels.map &:description
251
+ # #=> ["stone carving", "ancient history", "statue"]
252
+ #
253
+ def annotate *images, faces: false, landmarks: false, logos: false,
254
+ labels: false, text: false, safe_search: false,
255
+ properties: false
256
+ a = Annotate.new self
257
+ a.annotate(*images, faces: faces, landmarks: landmarks, logos: logos,
258
+ labels: labels, text: text,
259
+ safe_search: safe_search, properties: properties)
260
+
261
+ yield a if block_given?
262
+
263
+ gapi = service.annotate a.requests
264
+ annotations = Array(gapi.responses).map do |g|
265
+ fail Error.from_error(g.error) if g.error
266
+ Annotation.from_gapi g
267
+ end
268
+ return annotations.first if annotations.count == 1
269
+ annotations
270
+ end
271
+ alias_method :mark, :annotate
272
+ alias_method :detect, :annotate
273
+
274
+ protected
275
+
276
+ ##
277
+ # Raise an error unless an active connection is available.
278
+ def ensure_service!
279
+ fail "Must have active connection" unless service
280
+ end
281
+ end
282
+ end
283
+ end
284
+ end
@@ -0,0 +1,75 @@
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/errors"
17
+ require "google/cloud/vision/version"
18
+ require "google/apis/vision_v1"
19
+
20
+ module Google
21
+ module Cloud
22
+ module Vision
23
+ ##
24
+ # @private
25
+ # Represents the service to Vision, exposing the API calls.
26
+ class Service
27
+ ##
28
+ # Alias to the Google Client API module
29
+ API = Google::Apis::VisionV1
30
+
31
+ attr_accessor :project
32
+ attr_accessor :credentials
33
+
34
+ ##
35
+ # Creates a new Service instance.
36
+ def initialize project, credentials, retries: nil, timeout: nil
37
+ @project = project
38
+ @credentials = credentials
39
+ @service = API::VisionService.new
40
+ @service.client_options.application_name = "google-cloud-vision"
41
+ @service.client_options.application_version = \
42
+ Google::Cloud::Vision::VERSION
43
+ @service.request_options.retries = retries || 3
44
+ @service.request_options.timeout_sec = timeout if timeout
45
+ @service.authorization = @credentials.client
46
+ end
47
+
48
+ def service
49
+ return mocked_service if mocked_service
50
+ @service
51
+ end
52
+ attr_accessor :mocked_service
53
+
54
+ ##
55
+ # Returns API::BatchAnnotateImagesResponse
56
+ def annotate requests
57
+ request = API::BatchAnnotateImagesRequest.new(requests: requests)
58
+ execute { service.annotate_image request }
59
+ end
60
+
61
+ def inspect
62
+ "#{self.class}(#{@project})"
63
+ end
64
+
65
+ protected
66
+
67
+ def execute
68
+ yield
69
+ rescue Google::Apis::Error => e
70
+ raise Google::Cloud::Error.from_error(e)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end