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,222 @@
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
+ class Annotation
20
+ ##
21
+ # # Properties
22
+ #
23
+ # A set of properties about an image, such as the image's dominant
24
+ # colors.
25
+ #
26
+ # See {Google::Cloud::Vision::Image#properties}.
27
+ #
28
+ # @example
29
+ # require "google/cloud"
30
+ #
31
+ # gcloud = Google::Cloud.new
32
+ # vision = gcloud.vision
33
+ #
34
+ # image = vision.image "path/to/logo.jpg"
35
+ #
36
+ # properties = image.properties
37
+ # properties.colors.count #=> 10
38
+ #
39
+ class Properties
40
+ ##
41
+ # @private The ImageProperties Google API Client object.
42
+ attr_accessor :gapi
43
+
44
+ ##
45
+ # @private Creates a new Properties instance.
46
+ def initialize
47
+ @gapi = {}
48
+ end
49
+
50
+ ##
51
+ # The image's dominant colors, including their corresponding scores.
52
+ #
53
+ # @return [Array<Color>] An array of the image's dominant colors.
54
+ #
55
+ def colors
56
+ return [] unless @gapi.dominant_colors
57
+ @colors ||= Array(@gapi.dominant_colors.colors).map do |c|
58
+ Color.from_gapi c
59
+ end
60
+ end
61
+
62
+ ##
63
+ # Returns the object's property values as an array.
64
+ #
65
+ # @return [Array]
66
+ #
67
+ def to_a
68
+ colors.map(&:rgb)
69
+ end
70
+
71
+ ##
72
+ # Deeply converts object to a hash. All keys will be symbolized.
73
+ #
74
+ # @return [Hash]
75
+ #
76
+ def to_h
77
+ { colors: colors.map(&:to_h) }
78
+ end
79
+
80
+ # @private
81
+ def to_s
82
+ "(colors: #{colors.count})"
83
+ end
84
+
85
+ # @private
86
+ def inspect
87
+ "#<Properties #{self}>"
88
+ end
89
+
90
+ ##
91
+ # @private New Annotation::Properties from a Google API Client object.
92
+ def self.from_gapi gapi
93
+ new.tap { |f| f.instance_variable_set :@gapi, gapi }
94
+ end
95
+
96
+ ##
97
+ # # Color
98
+ #
99
+ # Color information consisting of RGB channels, score, and fraction of
100
+ # image the color occupies in the image.
101
+ #
102
+ # @example
103
+ # require "google/cloud"
104
+ #
105
+ # gcloud = Google::Cloud.new
106
+ # vision = gcloud.vision
107
+ #
108
+ # image = vision.image "path/to/logo.jpg"
109
+ # properties = image.properties
110
+ #
111
+ # color = properties.colors.first
112
+ # color.red #=> 247.0
113
+ # color.green #=> 236.0
114
+ # color.blue #=> 20.0
115
+ # color.rgb #=> "f7ec14"
116
+ # color.alpha #=> 1.0
117
+ # color.score #=> 0.20301804
118
+ # color.pixel_fraction #=> 0.0072649573
119
+ #
120
+ class Color
121
+ ##
122
+ # @private The ColorInfo Google API Client object.
123
+ attr_accessor :gapi
124
+
125
+ ##
126
+ # @private Creates a new Color instance.
127
+ def initialize
128
+ @gapi = {}
129
+ end
130
+
131
+ ##
132
+ # The amount of red in the color.
133
+ #
134
+ # @return [Float] A value in the interval [0, 255].
135
+ #
136
+ def red
137
+ @gapi.color.red
138
+ end
139
+
140
+ ##
141
+ # The amount of green in the color.
142
+ #
143
+ # @return [Float] A value in the interval [0, 255].
144
+ #
145
+ def green
146
+ @gapi.color.green
147
+ end
148
+
149
+ ##
150
+ # The amount of blue in the color.
151
+ #
152
+ # @return [Float] A value in the interval [0, 255].
153
+ #
154
+ def blue
155
+ @gapi.color.blue
156
+ end
157
+
158
+ ##
159
+ # The amount this color that should be applied to the pixel. A value
160
+ # of 1.0 corresponds to a solid color, whereas a value of 0.0
161
+ # corresponds to a completely transparent color.
162
+ #
163
+ # @return [Float] A value in the range [0, 1].
164
+ #
165
+ def alpha
166
+ @gapi.color.alpha || 1.0
167
+ end
168
+
169
+ def rgb
170
+ red.to_i.to_s(16).rjust(2, "0") +
171
+ green.to_i.to_s(16).rjust(2, "0") +
172
+ blue.to_i.to_s(16).rjust(2, "0")
173
+ end
174
+
175
+ ##
176
+ # Image-specific score for this color.
177
+ #
178
+ # @return [Float] A value in the range [0, 1].
179
+ #
180
+ def score
181
+ @gapi.score
182
+ end
183
+
184
+ ##
185
+ # Stores the fraction of pixels the color occupies in the image.
186
+ #
187
+ # @return [Float] A value in the range [0, 1].
188
+ #
189
+ def pixel_fraction
190
+ @gapi.pixel_fraction
191
+ end
192
+
193
+ ##
194
+ # Converts object to a hash. All keys will be symbolized.
195
+ #
196
+ # @return [Hash]
197
+ #
198
+ def to_h
199
+ { red: red, green: green, blue: blue, alpha: alpha, rgb: rgb,
200
+ score: score, pixel_fraction: pixel_fraction }
201
+ end
202
+
203
+ def to_s
204
+ "(colors: #{rgb})"
205
+ end
206
+
207
+ def inspect
208
+ "#<Color #{self}>"
209
+ end
210
+
211
+ ##
212
+ # @private New Annotation::Properties from a Google API Client
213
+ # object.
214
+ def self.from_gapi gapi
215
+ new.tap { |f| f.instance_variable_set :@gapi, gapi }
216
+ end
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end
@@ -0,0 +1,154 @@
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/vertex"
17
+
18
+ module Google
19
+ module Cloud
20
+ module Vision
21
+ class Annotation
22
+ ##
23
+ # # SafeSearch
24
+ #
25
+ # A set of features pertaining to the image, computed by various
26
+ # computer vision methods over safe-search verticals (for example,
27
+ # adult, spoof, medical, violence).
28
+ #
29
+ # @example
30
+ # require "google/cloud"
31
+ #
32
+ # gcloud = Google::Cloud.new
33
+ # vision = gcloud.vision
34
+ #
35
+ # image = vision.image "path/to/face.jpg"
36
+ #
37
+ # safe_search = image.safe_search
38
+ # safe_search.spoof? #=> false
39
+ # safe_search.spoof #=> "VERY_UNLIKELY"
40
+ #
41
+ class SafeSearch
42
+ POSITIVE_RATINGS = %w(POSSIBLE LIKELY VERY_LIKELY)
43
+
44
+ ##
45
+ # @private The SafeSearchAnnotation Google API Client object.
46
+ attr_accessor :gapi
47
+
48
+ ##
49
+ # @private Creates a new SafeSearch instance.
50
+ def initialize
51
+ @gapi = {}
52
+ end
53
+
54
+ ##
55
+ # Adult likelihood rating. Possible values are `VERY_UNLIKELY`,
56
+ # `UNLIKELY`, `POSSIBLE`, `LIKELY`, and `VERY_LIKELY`.
57
+ def adult
58
+ @gapi.adult
59
+ end
60
+
61
+ ##
62
+ # Adult likelihood. Returns `true` if {#adult} is `POSSIBLE`,
63
+ # `LIKELY`, or `VERY_LIKELY`.
64
+ #
65
+ # @return [Boolean]
66
+ #
67
+ def adult?
68
+ POSITIVE_RATINGS.include? adult
69
+ end
70
+
71
+ ##
72
+ # Spoof likelihood rating. Possible values are `VERY_UNLIKELY`,
73
+ # `UNLIKELY`, `POSSIBLE`, `LIKELY`, and `VERY_LIKELY`.
74
+ def spoof
75
+ @gapi.spoof
76
+ end
77
+
78
+ ##
79
+ # Spoof likelihood. Returns `true` if {#spoof} is `POSSIBLE`,
80
+ # `LIKELY`, or `VERY_LIKELY`.
81
+ #
82
+ # @return [Boolean]
83
+ #
84
+ def spoof?
85
+ POSITIVE_RATINGS.include? spoof
86
+ end
87
+
88
+ ##
89
+ # Medical likelihood rating. Possible values are `VERY_UNLIKELY`,
90
+ # `UNLIKELY`, `POSSIBLE`, `LIKELY`, and `VERY_LIKELY`.
91
+ def medical
92
+ @gapi.medical
93
+ end
94
+
95
+ ##
96
+ # Medical likelihood. Returns `true` if {#medical} is `POSSIBLE`,
97
+ # `LIKELY`, or `VERY_LIKELY`.
98
+ #
99
+ # @return [Boolean]
100
+ #
101
+ def medical?
102
+ POSITIVE_RATINGS.include? medical
103
+ end
104
+
105
+ ##
106
+ # Violence likelihood rating. Possible values are `VERY_UNLIKELY`,
107
+ # `UNLIKELY`, `POSSIBLE`, `LIKELY`, and `VERY_LIKELY`.
108
+ def violence
109
+ @gapi.violence
110
+ end
111
+
112
+ ##
113
+ # Violence likelihood. Returns `true` if {#violence} is `POSSIBLE`,
114
+ # `LIKELY`, or `VERY_LIKELY`.
115
+ #
116
+ # @return [Boolean]
117
+ #
118
+ def violence?
119
+ POSITIVE_RATINGS.include? violence
120
+ end
121
+
122
+ ##
123
+ # Converts object to a hash. All keys will be symbolized.
124
+ #
125
+ # @return [Hash]
126
+ #
127
+ def to_h
128
+ { adult: adult?, spoof: spoof?, medical: medical?,
129
+ violence: violence? }
130
+ end
131
+
132
+ # @private
133
+ def to_s
134
+ tmplt = "(adult?: %s, spoof?: %s, medical?: %s, " \
135
+ "violence?: %s)"
136
+ format tmplt, adult?.inspect, spoof?.inspect, medical?.inspect,
137
+ violence?.inspect
138
+ end
139
+
140
+ # @private
141
+ def inspect
142
+ "#<SafeSearch #{self}>"
143
+ end
144
+
145
+ ##
146
+ # @private New Annotation::SafeSearch from a Google API Client object.
147
+ def self.from_gapi gapi
148
+ new.tap { |f| f.instance_variable_set :@gapi, gapi }
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,222 @@
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/vertex"
17
+
18
+ module Google
19
+ module Cloud
20
+ module Vision
21
+ class Annotation
22
+ ##
23
+ # # Text
24
+ #
25
+ # The result of text, or optical character recognition (OCR), detection.
26
+ #
27
+ # @example
28
+ # require "google/cloud"
29
+ #
30
+ # gcloud = Google::Cloud.new
31
+ # vision = gcloud.vision
32
+ #
33
+ # image = vision.image "path/to/text.png"
34
+ #
35
+ # text = image.text
36
+ # text.locale #=> "en"
37
+ # text.words.count #=> 28
38
+ # text.text
39
+ # #=> "Google Cloud Client for Ruby an idiomatic, intuitive... "
40
+ #
41
+ class Text
42
+ ##
43
+ # @private The EntityAnnotation Google API Client object.
44
+ attr_accessor :gapi
45
+
46
+ ##
47
+ # @private Creates a new Text instance.
48
+ def initialize
49
+ @gapi = {}
50
+ @words = []
51
+ end
52
+
53
+ ##
54
+ # The text detected in an image.
55
+ #
56
+ # @return [String] The entire text including newline characters.
57
+ #
58
+ def text
59
+ @gapi.description
60
+ end
61
+
62
+ ##
63
+ # The language code detected for `text`.
64
+ #
65
+ # @return [String] The [ISO
66
+ # 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
67
+ # language code.
68
+ #
69
+ def locale
70
+ @gapi.locale
71
+ end
72
+
73
+ ##
74
+ # The bounds for the detected text in the image.
75
+ #
76
+ # @return [Array<Vertex>]
77
+ #
78
+ def bounds
79
+ return [] unless @gapi.bounding_poly
80
+ @bounds ||= Array(@gapi.bounding_poly.vertices).map do |v|
81
+ Vertex.from_gapi v
82
+ end
83
+ end
84
+
85
+ ##
86
+ # Each word in the detected text, with the bounds for each word.
87
+ #
88
+ # @return [Array<Word>]
89
+ #
90
+ def words
91
+ @words
92
+ end
93
+
94
+ ##
95
+ # Deeply converts object to a hash. All keys will be symbolized.
96
+ #
97
+ # @return [Hash]
98
+ #
99
+ def to_h
100
+ { text: text, locale: locale, bounds: bounds.map(&:to_h),
101
+ words: words.map(&:to_h) }
102
+ end
103
+
104
+ # @private
105
+ def to_s
106
+ to_str
107
+ end
108
+
109
+ # @private
110
+ def to_str
111
+ text
112
+ end
113
+
114
+ # @private
115
+ def inspect
116
+ format "#<Text text: %s, locale: %s, bounds: %i, words: %i>",
117
+ text.inspect, locale.inspect, bounds.count, words.count
118
+ end
119
+
120
+ ##
121
+ # @private New Annotation::Text from an array of Google API Client
122
+ # objects.
123
+ def self.from_gapi gapi_list
124
+ text, *words = Array gapi_list
125
+ return nil if text.nil?
126
+ new.tap do |t|
127
+ t.instance_variable_set :@gapi, text
128
+ t.instance_variable_set :@words,
129
+ words.map { |w| Word.from_gapi w }
130
+ end
131
+ end
132
+
133
+ ##
134
+ # # Word
135
+ #
136
+ # A word within a detected text (OCR). See {Text}.
137
+ #
138
+ # @example
139
+ # require "google/cloud"
140
+ #
141
+ # gcloud = Google::Cloud.new
142
+ # vision = gcloud.vision
143
+ #
144
+ # image = vision.image "path/to/text.png"
145
+ # text = image.text
146
+ #
147
+ # words = text.words
148
+ # words.count #=> 28
149
+ #
150
+ # word = words.first
151
+ # word.text #=> "Google"
152
+ # word.bounds.count #=> 4
153
+ # word.bounds.first #=> #<Vertex (x: 13, y: 8)>
154
+ #
155
+ class Word
156
+ ##
157
+ # @private The EntityAnnotation Google API Client object.
158
+ attr_accessor :gapi
159
+
160
+ ##
161
+ # @private Creates a new Word instance.
162
+ def initialize
163
+ @gapi = {}
164
+ end
165
+
166
+ ##
167
+ # The text of the word.
168
+ #
169
+ # @return [String]
170
+ #
171
+ def text
172
+ @gapi.description
173
+ end
174
+
175
+ ##
176
+ # The bounds of the word within the detected text.
177
+ #
178
+ # @return [Array<Vertex>]
179
+ #
180
+ def bounds
181
+ return [] unless @gapi.bounding_poly
182
+ @bounds ||= Array(@gapi.bounding_poly.vertices).map do |v|
183
+ Vertex.from_gapi v
184
+ end
185
+ end
186
+
187
+ ##
188
+ # Deeply converts object to a hash. All keys will be symbolized.
189
+ #
190
+ # @return [Hash]
191
+ #
192
+ def to_h
193
+ { text: text, bounds: bounds.map(&:to_h) }
194
+ end
195
+
196
+ # @private
197
+ def to_s
198
+ to_str
199
+ end
200
+
201
+ # @private
202
+ def to_str
203
+ text
204
+ end
205
+
206
+ # @private
207
+ def inspect
208
+ format "#<Word text: %s, bounds: %i>", text.inspect, bounds.count
209
+ end
210
+
211
+ ##
212
+ # @private New Annotation::Text::Word from a Google API Client
213
+ # object.
214
+ def self.from_gapi gapi
215
+ new.tap { |w| w.instance_variable_set :@gapi, gapi }
216
+ end
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end