google-cloud-vision 0.22.1 → 0.23.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 +4 -4
- data/lib/google/cloud/vision.rb +133 -6
- data/lib/google/cloud/vision/annotate.rb +55 -24
- data/lib/google/cloud/vision/annotation.rb +93 -11
- data/lib/google/cloud/vision/annotation/crop_hint.rb +126 -0
- data/lib/google/cloud/vision/annotation/text.rb +789 -11
- data/lib/google/cloud/vision/annotation/web.rb +420 -0
- data/lib/google/cloud/vision/image.rb +153 -17
- data/lib/google/cloud/vision/project.rb +29 -8
- data/lib/google/cloud/vision/v1/doc/google/cloud/vision/v1/image_annotator.rb +148 -81
- data/lib/google/cloud/vision/v1/doc/google/cloud/vision/v1/text_annotation.rb +231 -0
- data/lib/google/cloud/vision/v1/doc/google/cloud/vision/v1/web_detection.rb +73 -0
- data/lib/google/cloud/vision/v1/image_annotator_client.rb +4 -4
- data/lib/google/cloud/vision/v1/image_annotator_pb.rb +24 -0
- data/lib/google/cloud/vision/v1/image_annotator_services_pb.rb +3 -3
- data/lib/google/cloud/vision/v1/text_annotation_pb.rb +88 -0
- data/lib/google/cloud/vision/v1/web_detection_pb.rb +40 -0
- data/lib/google/cloud/vision/version.rb +1 -1
- metadata +8 -2
@@ -0,0 +1,126 @@
|
|
1
|
+
# Copyright 2017 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
|
+
# # CropHint
|
24
|
+
#
|
25
|
+
# A single crop hint that is used to generate new crops when serving
|
26
|
+
# images.
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# require "google/cloud/vision"
|
30
|
+
#
|
31
|
+
# vision = Google::Cloud::Vision.new
|
32
|
+
#
|
33
|
+
# image = vision.image "path/to/face.jpg"
|
34
|
+
#
|
35
|
+
# crop_hints = image.crop_hints
|
36
|
+
# crop_hints.count #=> 1
|
37
|
+
# crop_hint = crop_hints.first
|
38
|
+
#
|
39
|
+
# crop_hint.bounds.count #=> 4
|
40
|
+
# crop_hint.bounds[0].x #=> 1
|
41
|
+
# crop_hint.bounds[0].y #=> 0
|
42
|
+
# crop_hint.bounds[1].x #=> 511
|
43
|
+
# crop_hint.bounds[1].y #=> 0
|
44
|
+
# crop_hint.bounds[2].x #=> 511
|
45
|
+
# crop_hint.bounds[2].y #=> 383
|
46
|
+
# crop_hint.bounds[3].x #=> 0
|
47
|
+
# crop_hint.bounds[3].y #=> 383
|
48
|
+
#
|
49
|
+
# crop_hint.confidence #=> 1.0
|
50
|
+
# crop_hint.importance_fraction #=> 1.0399999618530273
|
51
|
+
#
|
52
|
+
class CropHint
|
53
|
+
##
|
54
|
+
# @private The Google::Cloud::Vision::V1::CropHint GRPC object.
|
55
|
+
attr_accessor :grpc
|
56
|
+
|
57
|
+
##
|
58
|
+
# @private Creates a new Entity instance.
|
59
|
+
def initialize
|
60
|
+
@grpc = nil
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# The bounding polygon for the crop region. The coordinates of the
|
65
|
+
# bounding box are in the original image's scale.
|
66
|
+
#
|
67
|
+
# @return [Array<Vertex>] An array of vertices.
|
68
|
+
#
|
69
|
+
def bounds
|
70
|
+
return [] unless @grpc.bounding_poly
|
71
|
+
@bounds ||= Array(@grpc.bounding_poly.vertices).map do |v|
|
72
|
+
Vertex.from_grpc v
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# The confidence of this being a salient region.
|
78
|
+
#
|
79
|
+
# @return [Float] A value in the range [0, 1].
|
80
|
+
#
|
81
|
+
def confidence
|
82
|
+
@grpc.confidence
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# The fraction of importance of this salient region with respect to
|
87
|
+
# the original image.
|
88
|
+
#
|
89
|
+
# @return [Float]
|
90
|
+
#
|
91
|
+
def importance_fraction
|
92
|
+
@grpc.importance_fraction
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Deeply converts object to a hash. All keys will be symbolized.
|
97
|
+
#
|
98
|
+
# @return [Hash]
|
99
|
+
#
|
100
|
+
def to_h
|
101
|
+
{ bounds: bounds.map(&:to_h), confidence: confidence,
|
102
|
+
importance_fraction: importance_fraction }
|
103
|
+
end
|
104
|
+
|
105
|
+
# @private
|
106
|
+
def to_s
|
107
|
+
tmplt = "bounds: %i, confidence: %s, importance_fraction: %s"
|
108
|
+
format tmplt, bounds.count, confidence.inspect,
|
109
|
+
importance_fraction.inspect
|
110
|
+
end
|
111
|
+
|
112
|
+
# @private
|
113
|
+
def inspect
|
114
|
+
"#<#{self.class.name} #{self}>"
|
115
|
+
end
|
116
|
+
|
117
|
+
##
|
118
|
+
# @private New Annotation::Entity from a GRPC object.
|
119
|
+
def self.from_grpc grpc
|
120
|
+
new.tap { |f| f.instance_variable_set :@grpc, grpc }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -22,7 +22,11 @@ module Google
|
|
22
22
|
##
|
23
23
|
# # Text
|
24
24
|
#
|
25
|
-
# The
|
25
|
+
# The results from either the `TEXT_DETECTION` feature (OCR for shorter
|
26
|
+
# documents with sparse text) or the `DOCUMENT_TEXT_DETECTION` feature
|
27
|
+
# (OCR for longer documents with dense text). Optional. Contains
|
28
|
+
# structured representations of OCR extracted text, as well as
|
29
|
+
# the entire UTF-8 text as a string.
|
26
30
|
#
|
27
31
|
# @example
|
28
32
|
# require "google/cloud/vision"
|
@@ -32,11 +36,20 @@ module Google
|
|
32
36
|
# image = vision.image "path/to/text.png"
|
33
37
|
#
|
34
38
|
# text = image.text
|
35
|
-
#
|
36
|
-
# text.words.count #=> 28
|
39
|
+
#
|
37
40
|
# text.text
|
38
41
|
# # "Google Cloud Client for Ruby an idiomatic, intuitive... "
|
39
42
|
#
|
43
|
+
# text.words[0].text #=> "Google"
|
44
|
+
# text.words[0].bounds.count #=> 4
|
45
|
+
# vertex = text.words[0].bounds.first
|
46
|
+
# vertex.x #=> 13
|
47
|
+
# vertex.y #=> 8
|
48
|
+
#
|
49
|
+
# # Use `pages` to access a full structural representation
|
50
|
+
# text.pages[0].blocks[0].paragraphs[0].words[0].symbols[0].text
|
51
|
+
# #=> "G"
|
52
|
+
#
|
40
53
|
class Text
|
41
54
|
##
|
42
55
|
# @private The EntityAnnotation GRPC object.
|
@@ -90,6 +103,20 @@ module Google
|
|
90
103
|
@words
|
91
104
|
end
|
92
105
|
|
106
|
+
##
|
107
|
+
# Each page in the detected text, with the metadata for each page.
|
108
|
+
# Contains a structured representation of OCR extracted text.
|
109
|
+
# The hierarchy of an OCR extracted text structure is like this:
|
110
|
+
# Page -> Block -> Paragraph -> Word -> Symbol
|
111
|
+
# Each structural component, starting from Page, may further have its
|
112
|
+
# own properties. Properties describe detected languages, breaks etc..
|
113
|
+
#
|
114
|
+
# @return [Array<Page>]
|
115
|
+
#
|
116
|
+
def pages
|
117
|
+
@pages
|
118
|
+
end
|
119
|
+
|
93
120
|
##
|
94
121
|
# Deeply converts object to a hash. All keys will be symbolized.
|
95
122
|
#
|
@@ -97,7 +124,7 @@ module Google
|
|
97
124
|
#
|
98
125
|
def to_h
|
99
126
|
{ text: text, locale: locale, bounds: bounds.map(&:to_h),
|
100
|
-
words: words.map(&:to_h) }
|
127
|
+
words: words.map(&:to_h), pages: pages.map(&:to_h) }
|
101
128
|
end
|
102
129
|
|
103
130
|
# @private
|
@@ -112,27 +139,35 @@ module Google
|
|
112
139
|
|
113
140
|
# @private
|
114
141
|
def inspect
|
115
|
-
format "#<Text text: %s, locale: %s, bounds: %i, words: %i
|
116
|
-
text.inspect, locale.inspect, bounds.count,
|
142
|
+
format "#<Text text: %s, locale: %s, bounds: %i, words: %i," \
|
143
|
+
" pages: %i>", text.inspect, locale.inspect, bounds.count,
|
144
|
+
words.count, pages.count
|
117
145
|
end
|
118
146
|
|
119
147
|
##
|
120
|
-
# @private
|
121
|
-
#
|
122
|
-
def self.from_grpc
|
123
|
-
text, *words = Array
|
148
|
+
# @private Create a new Annotation::Text by merging two GRPC models of
|
149
|
+
# text representation.
|
150
|
+
def self.from_grpc grpc_text_annotations, grpc_full_text_annotation
|
151
|
+
text, *words = Array grpc_text_annotations
|
124
152
|
return nil if text.nil?
|
153
|
+
|
154
|
+
# Since text is taken from grpc_text_annotations, do not use text
|
155
|
+
# from grpc_full_text_annotation in this merged model.
|
156
|
+
# Instead, just take the pages.
|
157
|
+
pages = grpc_full_text_annotation.pages
|
125
158
|
new.tap do |t|
|
126
159
|
t.instance_variable_set :@grpc, text
|
127
160
|
t.instance_variable_set :@words,
|
128
161
|
words.map { |w| Word.from_grpc w }
|
162
|
+
t.instance_variable_set :@pages,
|
163
|
+
pages.map { |p| Page.from_grpc p }
|
129
164
|
end
|
130
165
|
end
|
131
166
|
|
132
167
|
##
|
133
168
|
# # Word
|
134
169
|
#
|
135
|
-
# A word within a detected text (OCR). See {Text}.
|
170
|
+
# A word within a detected text (OCR). See {Text#words}.
|
136
171
|
#
|
137
172
|
# @example
|
138
173
|
# require "google/cloud/vision"
|
@@ -215,6 +250,749 @@ module Google
|
|
215
250
|
new.tap { |w| w.instance_variable_set :@grpc, grpc }
|
216
251
|
end
|
217
252
|
end
|
253
|
+
|
254
|
+
##
|
255
|
+
# # Page
|
256
|
+
#
|
257
|
+
# A page within a detected text (OCR). See {Text#pages}.
|
258
|
+
#
|
259
|
+
# @example
|
260
|
+
# require "google/cloud/vision"
|
261
|
+
#
|
262
|
+
# vision = Google::Cloud::Vision.new
|
263
|
+
#
|
264
|
+
# image = vision.image "path/to/text.png"
|
265
|
+
#
|
266
|
+
# text = image.text
|
267
|
+
#
|
268
|
+
# page = text.pages.first
|
269
|
+
#
|
270
|
+
# page.languages.first.code #=> "en"
|
271
|
+
# page.wont_be :prefix_break?
|
272
|
+
# page.width #=> 400
|
273
|
+
# page.height #=> 80
|
274
|
+
# page.blocks.count #=> 1
|
275
|
+
#
|
276
|
+
class Page
|
277
|
+
##
|
278
|
+
# @private The EntityAnnotation GRPC object.
|
279
|
+
attr_accessor :grpc
|
280
|
+
|
281
|
+
##
|
282
|
+
# @private Creates a new Page instance.
|
283
|
+
def initialize
|
284
|
+
@grpc = nil
|
285
|
+
end
|
286
|
+
|
287
|
+
##
|
288
|
+
# A list of detected languages together with confidence.
|
289
|
+
#
|
290
|
+
# @return [Array<Language>]
|
291
|
+
#
|
292
|
+
def languages
|
293
|
+
@languages ||= Array(@grpc.property.detected_languages).map do |l|
|
294
|
+
Language.from_grpc l
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
##
|
299
|
+
# The type of a detected break at the start or end of the page.
|
300
|
+
#
|
301
|
+
# @return [::Symbol]
|
302
|
+
#
|
303
|
+
def break_type
|
304
|
+
@grpc.property.detected_break &&
|
305
|
+
@grpc.property.detected_break.type.to_sym
|
306
|
+
end
|
307
|
+
|
308
|
+
##
|
309
|
+
# True if a detected break prepends the page.
|
310
|
+
#
|
311
|
+
# @return [Boolean]
|
312
|
+
#
|
313
|
+
def prefix_break?
|
314
|
+
@grpc.property.detected_break &&
|
315
|
+
@grpc.property.detected_break.is_prefix
|
316
|
+
end
|
317
|
+
|
318
|
+
##
|
319
|
+
# Page width in pixels.
|
320
|
+
#
|
321
|
+
# @return [Integer]
|
322
|
+
#
|
323
|
+
def width
|
324
|
+
@grpc.width
|
325
|
+
end
|
326
|
+
|
327
|
+
##
|
328
|
+
# Page height in pixels.
|
329
|
+
#
|
330
|
+
# @return [Integer]
|
331
|
+
#
|
332
|
+
def height
|
333
|
+
@grpc.height
|
334
|
+
end
|
335
|
+
|
336
|
+
##
|
337
|
+
# List of blocks of text, images etc on this page.
|
338
|
+
#
|
339
|
+
# @return [Array<Block>]
|
340
|
+
#
|
341
|
+
def blocks
|
342
|
+
@blocks ||= Array(@grpc.blocks).map do |b|
|
343
|
+
Block.from_grpc b
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
##
|
348
|
+
# Deeply converts object to a hash. All keys will be symbolized.
|
349
|
+
#
|
350
|
+
# @return [Hash]
|
351
|
+
#
|
352
|
+
def to_h
|
353
|
+
{ languages: languages.map(&:to_h), break_type: break_type,
|
354
|
+
prefix_break: prefix_break?, width: width, height: height,
|
355
|
+
blocks: blocks.map(&:to_h) }
|
356
|
+
end
|
357
|
+
|
358
|
+
# @private
|
359
|
+
def to_s
|
360
|
+
tmplt = "languages: %s, break_type: %s, prefix_break: %s," \
|
361
|
+
" width: %s, height: %s, blocks: %i"
|
362
|
+
format tmplt, languages.inspect, break_type, prefix_break?, width,
|
363
|
+
height, blocks.count
|
364
|
+
end
|
365
|
+
|
366
|
+
# @private
|
367
|
+
def inspect
|
368
|
+
"#<#{self.class.name} #{self}>"
|
369
|
+
end
|
370
|
+
|
371
|
+
##
|
372
|
+
# @private New Annotation::Text::Page from a GRPC
|
373
|
+
# object.
|
374
|
+
def self.from_grpc grpc
|
375
|
+
new.tap { |w| w.instance_variable_set :@grpc, grpc }
|
376
|
+
end
|
377
|
+
|
378
|
+
##
|
379
|
+
# # Block
|
380
|
+
#
|
381
|
+
# A logical element on the page. See {Page}.
|
382
|
+
#
|
383
|
+
# @example
|
384
|
+
# require "google/cloud/vision"
|
385
|
+
#
|
386
|
+
# vision = Google::Cloud::Vision.new
|
387
|
+
#
|
388
|
+
# image = vision.image "path/to/text.png"
|
389
|
+
# text = image.text
|
390
|
+
#
|
391
|
+
# block = text.pages[0].blocks.first
|
392
|
+
#
|
393
|
+
# block.languages.first.code #=> "en"
|
394
|
+
# block.bounds.count #=> 4
|
395
|
+
# block.paragraphs.count #=> 1
|
396
|
+
#
|
397
|
+
class Block
|
398
|
+
##
|
399
|
+
# @private The EntityAnnotation GRPC object.
|
400
|
+
attr_accessor :grpc
|
401
|
+
|
402
|
+
##
|
403
|
+
# @private Creates a new Block instance.
|
404
|
+
def initialize
|
405
|
+
@grpc = nil
|
406
|
+
end
|
407
|
+
|
408
|
+
##
|
409
|
+
# A list of detected languages together with confidence.
|
410
|
+
#
|
411
|
+
# @return [Array<Language>]
|
412
|
+
#
|
413
|
+
def languages
|
414
|
+
detected_languages = @grpc.property.detected_languages
|
415
|
+
@languages ||= Array(detected_languages).map do |l|
|
416
|
+
Language.from_grpc l
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
##
|
421
|
+
# The type of a detected break at the start or end of the page.
|
422
|
+
#
|
423
|
+
# @return [::Symbol]
|
424
|
+
#
|
425
|
+
def break_type
|
426
|
+
@grpc.property.detected_break &&
|
427
|
+
@grpc.property.detected_break.type.to_sym
|
428
|
+
end
|
429
|
+
|
430
|
+
##
|
431
|
+
# True if a detected break prepends the page.
|
432
|
+
#
|
433
|
+
# @return [Boolean]
|
434
|
+
#
|
435
|
+
def prefix_break?
|
436
|
+
@grpc.property.detected_break &&
|
437
|
+
@grpc.property.detected_break.is_prefix
|
438
|
+
end
|
439
|
+
|
440
|
+
##
|
441
|
+
# The bounding box for the block.
|
442
|
+
# The vertices are in the order of top-left, top-right,
|
443
|
+
# bottom-right, bottom-left. When a rotation of the bounding box
|
444
|
+
# is detected the rotation is represented as around the top-left
|
445
|
+
# corner as defined when the text is read in the 'natural'
|
446
|
+
# orientation.
|
447
|
+
# For example:
|
448
|
+
# * when the text is horizontal it might look like:
|
449
|
+
# 0----1
|
450
|
+
# | |
|
451
|
+
# 3----2
|
452
|
+
# * when rotated 180 degrees around the top-left corner it
|
453
|
+
# becomes:
|
454
|
+
# 2----3
|
455
|
+
# | |
|
456
|
+
# 1----0
|
457
|
+
# and the vertice order will still be (0, 1, 2, 3).
|
458
|
+
#
|
459
|
+
# @return [Array<Vertex>]
|
460
|
+
#
|
461
|
+
def bounds
|
462
|
+
return [] unless @grpc.bounding_box
|
463
|
+
@bounds ||= Array(@grpc.bounding_box.vertices).map do |v|
|
464
|
+
Vertex.from_grpc v
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
##
|
469
|
+
# List of paragraphs in this block (if this block is of type
|
470
|
+
# text).
|
471
|
+
#
|
472
|
+
# @return [Array<Paragraph>]
|
473
|
+
#
|
474
|
+
def paragraphs
|
475
|
+
@paragraphs ||= Array(@grpc.paragraphs).map do |b|
|
476
|
+
Paragraph.from_grpc b
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
##
|
481
|
+
# Detected block type (text, image etc) for the block.
|
482
|
+
#
|
483
|
+
# @return [::Symbol]
|
484
|
+
#
|
485
|
+
def block_type
|
486
|
+
@grpc.block_type.to_sym
|
487
|
+
end
|
488
|
+
|
489
|
+
##
|
490
|
+
# Deeply converts object to a hash. All keys will be symbolized.
|
491
|
+
#
|
492
|
+
# @return [Hash]
|
493
|
+
#
|
494
|
+
def to_h
|
495
|
+
{ languages: languages.map(&:to_h), break_type: break_type,
|
496
|
+
prefix_break: prefix_break?, bounds: bounds.map(&:to_h),
|
497
|
+
paragraphs: paragraphs.map(&:to_h), block_type: block_type }
|
498
|
+
end
|
499
|
+
|
500
|
+
# @private
|
501
|
+
def to_s
|
502
|
+
tmplt = "languages: %s, break_type: %s, prefix_break: %s," \
|
503
|
+
" bounds: %i, paragraphs: %i, block_type: %s"
|
504
|
+
format tmplt, languages.inspect, break_type, prefix_break?,
|
505
|
+
bounds.count, paragraphs.count, block_type
|
506
|
+
end
|
507
|
+
|
508
|
+
# @private
|
509
|
+
def inspect
|
510
|
+
"#<#{self.class.name} #{self}>"
|
511
|
+
end
|
512
|
+
|
513
|
+
##
|
514
|
+
# @private New Annotation::Text::Page::Block from a GRPC
|
515
|
+
# object.
|
516
|
+
def self.from_grpc grpc
|
517
|
+
new.tap { |w| w.instance_variable_set :@grpc, grpc }
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
521
|
+
##
|
522
|
+
# # Paragraph
|
523
|
+
#
|
524
|
+
# Structural unit of text representing a number of words in certain
|
525
|
+
# order. See {Block}.
|
526
|
+
#
|
527
|
+
# @example
|
528
|
+
# require "google/cloud/vision"
|
529
|
+
#
|
530
|
+
# vision = Google::Cloud::Vision.new
|
531
|
+
#
|
532
|
+
# image = vision.image "path/to/text.png"
|
533
|
+
# text = image.text
|
534
|
+
#
|
535
|
+
# paragraph = text.pages[0].blocks[0].paragraphs.first
|
536
|
+
#
|
537
|
+
# paragraph.languages.first.code #=> "en"
|
538
|
+
# paragraph.bounds.count #=> 4
|
539
|
+
# paragraph.words.count #=> 10
|
540
|
+
#
|
541
|
+
class Paragraph
|
542
|
+
##
|
543
|
+
# @private The EntityAnnotation GRPC object.
|
544
|
+
attr_accessor :grpc
|
545
|
+
|
546
|
+
##
|
547
|
+
# @private Creates a new Paragraph instance.
|
548
|
+
def initialize
|
549
|
+
@grpc = nil
|
550
|
+
end
|
551
|
+
|
552
|
+
##
|
553
|
+
# A list of detected languages together with confidence.
|
554
|
+
#
|
555
|
+
# @return [Array<Language>]
|
556
|
+
#
|
557
|
+
def languages
|
558
|
+
detected_languages = @grpc.property.detected_languages
|
559
|
+
@languages ||= Array(detected_languages).map do |l|
|
560
|
+
Language.from_grpc l
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
##
|
565
|
+
# The type of a detected break at the start or end of the page.
|
566
|
+
#
|
567
|
+
# @return [::Symbol]
|
568
|
+
#
|
569
|
+
def break_type
|
570
|
+
@grpc.property.detected_break &&
|
571
|
+
@grpc.property.detected_break.type.to_sym
|
572
|
+
end
|
573
|
+
|
574
|
+
##
|
575
|
+
# True if a detected break prepends the page.
|
576
|
+
#
|
577
|
+
# @return [Boolean]
|
578
|
+
#
|
579
|
+
def prefix_break?
|
580
|
+
@grpc.property.detected_break &&
|
581
|
+
@grpc.property.detected_break.is_prefix
|
582
|
+
end
|
583
|
+
|
584
|
+
##
|
585
|
+
# The bounding box for the paragraph.
|
586
|
+
# The vertices are in the order of top-left, top-right,
|
587
|
+
# bottom-right, bottom-left. When a rotation of the bounding box
|
588
|
+
# is detected the rotation is represented as around the top-left
|
589
|
+
# corner as defined when the text is read in the 'natural'
|
590
|
+
# orientation.
|
591
|
+
# For example:
|
592
|
+
# * when the text is horizontal it might look like:
|
593
|
+
# 0----1
|
594
|
+
# | |
|
595
|
+
# 3----2
|
596
|
+
# * when rotated 180 degrees around the top-left corner it
|
597
|
+
# becomes:
|
598
|
+
# 2----3
|
599
|
+
# | |
|
600
|
+
# 1----0
|
601
|
+
# and the vertice order will still be (0, 1, 2, 3).
|
602
|
+
#
|
603
|
+
# @return [Array<Vertex>]
|
604
|
+
#
|
605
|
+
def bounds
|
606
|
+
return [] unless @grpc.bounding_box
|
607
|
+
@bounds ||= Array(@grpc.bounding_box.vertices).map do |v|
|
608
|
+
Vertex.from_grpc v
|
609
|
+
end
|
610
|
+
end
|
611
|
+
|
612
|
+
##
|
613
|
+
# List of words in this paragraph.
|
614
|
+
#
|
615
|
+
# @return [Array<Word>]
|
616
|
+
#
|
617
|
+
def words
|
618
|
+
@words ||= Array(@grpc.words).map do |b|
|
619
|
+
Word.from_grpc b
|
620
|
+
end
|
621
|
+
end
|
622
|
+
|
623
|
+
##
|
624
|
+
# Deeply converts object to a hash. All keys will be symbolized.
|
625
|
+
#
|
626
|
+
# @return [Hash]
|
627
|
+
#
|
628
|
+
def to_h
|
629
|
+
{ languages: languages.map(&:to_h), break_type: break_type,
|
630
|
+
prefix_break: prefix_break?, bounds: bounds.map(&:to_h),
|
631
|
+
words: words.map(&:to_h) }
|
632
|
+
end
|
633
|
+
|
634
|
+
# @private
|
635
|
+
def to_s
|
636
|
+
tmplt = "languages: %s, break_type: %s, prefix_break: %s," \
|
637
|
+
" bounds: %i, words: %i"
|
638
|
+
format tmplt, languages.inspect, break_type, prefix_break?,
|
639
|
+
bounds.count, words.count
|
640
|
+
end
|
641
|
+
|
642
|
+
# @private
|
643
|
+
def inspect
|
644
|
+
"#<#{self.class.name} #{self}>"
|
645
|
+
end
|
646
|
+
|
647
|
+
##
|
648
|
+
# @private New Annotation::Text::Page::Paragraph from a GRPC
|
649
|
+
# object.
|
650
|
+
def self.from_grpc grpc
|
651
|
+
new.tap { |w| w.instance_variable_set :@grpc, grpc }
|
652
|
+
end
|
653
|
+
end
|
654
|
+
|
655
|
+
##
|
656
|
+
# # Word
|
657
|
+
#
|
658
|
+
# A word representation. See {Paragraph}.
|
659
|
+
#
|
660
|
+
# @example
|
661
|
+
# require "google/cloud/vision"
|
662
|
+
#
|
663
|
+
# vision = Google::Cloud::Vision.new
|
664
|
+
#
|
665
|
+
# image = vision.image "path/to/text.png"
|
666
|
+
# text = image.text
|
667
|
+
#
|
668
|
+
# word = text.pages[0].blocks[0].paragraphs[0].words.first
|
669
|
+
#
|
670
|
+
# word.languages.first.code #=> "en"
|
671
|
+
# word.bounds.count #=> 4
|
672
|
+
# word.symbols.count #=> 6
|
673
|
+
#
|
674
|
+
class Word
|
675
|
+
##
|
676
|
+
# @private The EntityAnnotation GRPC object.
|
677
|
+
attr_accessor :grpc
|
678
|
+
|
679
|
+
##
|
680
|
+
# @private Creates a new Word instance.
|
681
|
+
def initialize
|
682
|
+
@grpc = nil
|
683
|
+
end
|
684
|
+
|
685
|
+
##
|
686
|
+
# A list of detected languages together with confidence.
|
687
|
+
#
|
688
|
+
# @return [Array<Language>]
|
689
|
+
#
|
690
|
+
def languages
|
691
|
+
detected_languages = @grpc.property.detected_languages
|
692
|
+
@languages ||= Array(detected_languages).map do |l|
|
693
|
+
Language.from_grpc l
|
694
|
+
end
|
695
|
+
end
|
696
|
+
|
697
|
+
##
|
698
|
+
# The type of a detected break at the start or end of the page.
|
699
|
+
#
|
700
|
+
# @return [::Symbol]
|
701
|
+
#
|
702
|
+
def break_type
|
703
|
+
@grpc.property.detected_break &&
|
704
|
+
@grpc.property.detected_break.type.to_sym
|
705
|
+
end
|
706
|
+
|
707
|
+
##
|
708
|
+
# True if a detected break prepends the page.
|
709
|
+
#
|
710
|
+
# @return [Boolean]
|
711
|
+
#
|
712
|
+
def prefix_break?
|
713
|
+
@grpc.property.detected_break &&
|
714
|
+
@grpc.property.detected_break.is_prefix
|
715
|
+
end
|
716
|
+
|
717
|
+
##
|
718
|
+
# The bounding box for the word.
|
719
|
+
# The vertices are in the order of top-left, top-right,
|
720
|
+
# bottom-right, bottom-left. When a rotation of the bounding box
|
721
|
+
# is detected the rotation is represented as around the top-left
|
722
|
+
# corner as defined when the text is read in the 'natural'
|
723
|
+
# orientation.
|
724
|
+
# For example:
|
725
|
+
# * when the text is horizontal it might look like:
|
726
|
+
# 0----1
|
727
|
+
# | |
|
728
|
+
# 3----2
|
729
|
+
# * when rotated 180 degrees around the top-left corner it
|
730
|
+
# becomes:
|
731
|
+
# 2----3
|
732
|
+
# | |
|
733
|
+
# 1----0
|
734
|
+
# and the vertice order will still be (0, 1, 2, 3).
|
735
|
+
#
|
736
|
+
# @return [Array<Vertex>]
|
737
|
+
#
|
738
|
+
def bounds
|
739
|
+
return [] unless @grpc.bounding_box
|
740
|
+
@bounds ||= Array(@grpc.bounding_box.vertices).map do |v|
|
741
|
+
Vertex.from_grpc v
|
742
|
+
end
|
743
|
+
end
|
744
|
+
|
745
|
+
##
|
746
|
+
# List of symbols in the word. The order of the symbols follows
|
747
|
+
# the natural reading order.
|
748
|
+
#
|
749
|
+
# @return [Array<Symbol>]
|
750
|
+
#
|
751
|
+
def symbols
|
752
|
+
@symbols ||= Array(@grpc.symbols).map do |b|
|
753
|
+
Symbol.from_grpc b
|
754
|
+
end
|
755
|
+
end
|
756
|
+
|
757
|
+
##
|
758
|
+
# Deeply converts object to a hash. All keys will be symbolized.
|
759
|
+
#
|
760
|
+
# @return [Hash]
|
761
|
+
#
|
762
|
+
def to_h
|
763
|
+
{ languages: languages.map(&:to_h), break_type: break_type,
|
764
|
+
prefix_break: prefix_break?, bounds: bounds.map(&:to_h),
|
765
|
+
symbols: symbols.map(&:to_h) }
|
766
|
+
end
|
767
|
+
|
768
|
+
# @private
|
769
|
+
def to_s
|
770
|
+
tmplt = "languages: %s, break_type: %s, prefix_break: %s," \
|
771
|
+
" bounds: %i, symbols: %i"
|
772
|
+
format tmplt, languages.inspect, break_type, prefix_break?,
|
773
|
+
bounds.count, symbols.count
|
774
|
+
end
|
775
|
+
|
776
|
+
# @private
|
777
|
+
def inspect
|
778
|
+
"#<#{self.class.name} #{self}>"
|
779
|
+
end
|
780
|
+
|
781
|
+
##
|
782
|
+
# @private New Annotation::Text::Page::Word from a GRPC
|
783
|
+
# object.
|
784
|
+
def self.from_grpc grpc
|
785
|
+
new.tap { |w| w.instance_variable_set :@grpc, grpc }
|
786
|
+
end
|
787
|
+
end
|
788
|
+
|
789
|
+
##
|
790
|
+
# # Symbol
|
791
|
+
#
|
792
|
+
# A word representation. See {Paragraph}.
|
793
|
+
#
|
794
|
+
# @example
|
795
|
+
# require "google/cloud/vision"
|
796
|
+
#
|
797
|
+
# vision = Google::Cloud::Vision.new
|
798
|
+
#
|
799
|
+
# image = vision.image "path/to/text.png"
|
800
|
+
# text = image.text
|
801
|
+
# page = text.pages.first
|
802
|
+
#
|
803
|
+
# symbol = page.blocks[0].paragraphs[0].words[0].symbols[0]
|
804
|
+
#
|
805
|
+
# symbol.languages.first.code #=> "en"
|
806
|
+
# symbol.bounds.count #=> 4
|
807
|
+
# symbol.text #=> "G"
|
808
|
+
#
|
809
|
+
class Symbol
|
810
|
+
##
|
811
|
+
# @private The EntityAnnotation GRPC object.
|
812
|
+
attr_accessor :grpc
|
813
|
+
|
814
|
+
##
|
815
|
+
# @private Creates a new Symbol instance.
|
816
|
+
def initialize
|
817
|
+
@grpc = nil
|
818
|
+
end
|
819
|
+
|
820
|
+
##
|
821
|
+
# A list of detected languages together with confidence.
|
822
|
+
#
|
823
|
+
# @return [Array<Language>]
|
824
|
+
#
|
825
|
+
def languages
|
826
|
+
detected_languages = @grpc.property.detected_languages
|
827
|
+
@languages ||= Array(detected_languages).map do |l|
|
828
|
+
Language.from_grpc l
|
829
|
+
end
|
830
|
+
end
|
831
|
+
|
832
|
+
##
|
833
|
+
# The type of a detected break at the start or end of the page.
|
834
|
+
#
|
835
|
+
# @return [::Symbol]
|
836
|
+
#
|
837
|
+
def break_type
|
838
|
+
@grpc.property.detected_break &&
|
839
|
+
@grpc.property.detected_break.type.to_sym
|
840
|
+
end
|
841
|
+
|
842
|
+
##
|
843
|
+
# True if a detected break prepends the page.
|
844
|
+
#
|
845
|
+
# @return [Boolean]
|
846
|
+
#
|
847
|
+
def prefix_break?
|
848
|
+
@grpc.property.detected_break &&
|
849
|
+
@grpc.property.detected_break.is_prefix
|
850
|
+
end
|
851
|
+
|
852
|
+
##
|
853
|
+
# The bounding box for the symbol.
|
854
|
+
# The vertices are in the order of top-left, top-right,
|
855
|
+
# bottom-right, bottom-left. When a rotation of the bounding box
|
856
|
+
# is detected the rotation is represented as around the top-left
|
857
|
+
# corner as defined when the text is read in the 'natural'
|
858
|
+
# orientation.
|
859
|
+
# For example:
|
860
|
+
# * when the text is horizontal it might look like:
|
861
|
+
# 0----1
|
862
|
+
# | |
|
863
|
+
# 3----2
|
864
|
+
# * when rotated 180 degrees around the top-left corner it
|
865
|
+
# becomes:
|
866
|
+
# 2----3
|
867
|
+
# | |
|
868
|
+
# 1----0
|
869
|
+
# and the vertice order will still be (0, 1, 2, 3).
|
870
|
+
#
|
871
|
+
# @return [Array<Vertex>]
|
872
|
+
#
|
873
|
+
def bounds
|
874
|
+
return [] unless @grpc.bounding_box
|
875
|
+
@bounds ||= Array(@grpc.bounding_box.vertices).map do |v|
|
876
|
+
Vertex.from_grpc v
|
877
|
+
end
|
878
|
+
end
|
879
|
+
|
880
|
+
##
|
881
|
+
# The actual UTF-8 representation of the symbol.
|
882
|
+
#
|
883
|
+
# @return [String]
|
884
|
+
#
|
885
|
+
def text
|
886
|
+
@grpc.text
|
887
|
+
end
|
888
|
+
|
889
|
+
##
|
890
|
+
# Deeply converts object to a hash. All keys will be symbolized.
|
891
|
+
#
|
892
|
+
# @return [Hash]
|
893
|
+
#
|
894
|
+
def to_h
|
895
|
+
{ languages: languages.map(&:to_h), break_type: break_type,
|
896
|
+
prefix_break: prefix_break?, bounds: bounds.map(&:to_h),
|
897
|
+
text: text }
|
898
|
+
end
|
899
|
+
|
900
|
+
# @private
|
901
|
+
def to_s
|
902
|
+
tmplt = "languages: %s, break_type: %s, prefix_break: %s," \
|
903
|
+
" bounds: %i, text: %s"
|
904
|
+
format tmplt, languages.inspect, break_type, prefix_break?,
|
905
|
+
bounds.count, text
|
906
|
+
end
|
907
|
+
|
908
|
+
# @private
|
909
|
+
def inspect
|
910
|
+
"#<#{self.class.name} #{self}>"
|
911
|
+
end
|
912
|
+
|
913
|
+
##
|
914
|
+
# @private New Annotation::Text::Page::Symbol from a GRPC
|
915
|
+
# object.
|
916
|
+
def self.from_grpc grpc
|
917
|
+
new.tap { |w| w.instance_variable_set :@grpc, grpc }
|
918
|
+
end
|
919
|
+
end
|
920
|
+
|
921
|
+
##
|
922
|
+
# # Language
|
923
|
+
#
|
924
|
+
# A language within a detected text (OCR). See {Text#pages}.
|
925
|
+
#
|
926
|
+
# @example
|
927
|
+
# require "google/cloud/vision"
|
928
|
+
#
|
929
|
+
# vision = Google::Cloud::Vision.new
|
930
|
+
#
|
931
|
+
# image = vision.image "path/to/text.png"
|
932
|
+
# text = image.text
|
933
|
+
# page = text.pages.first
|
934
|
+
#
|
935
|
+
# language = page.languages.first
|
936
|
+
# language.code #=> "en"
|
937
|
+
#
|
938
|
+
class Language
|
939
|
+
##
|
940
|
+
# @private The EntityAnnotation GRPC object.
|
941
|
+
attr_accessor :grpc
|
942
|
+
|
943
|
+
##
|
944
|
+
# @private Creates a new Language instance.
|
945
|
+
def initialize
|
946
|
+
@grpc = nil
|
947
|
+
end
|
948
|
+
|
949
|
+
##
|
950
|
+
# The language code detected for a structural component.
|
951
|
+
#
|
952
|
+
# @return [String] The [ISO
|
953
|
+
# 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
|
954
|
+
# language code.
|
955
|
+
#
|
956
|
+
def code
|
957
|
+
@grpc.language_code
|
958
|
+
end
|
959
|
+
|
960
|
+
##
|
961
|
+
# Confidence of detected language.
|
962
|
+
#
|
963
|
+
# @return [Float] A value in the range [0,1].
|
964
|
+
#
|
965
|
+
def confidence
|
966
|
+
@grpc.confidence
|
967
|
+
end
|
968
|
+
|
969
|
+
##
|
970
|
+
# Deeply converts object to a hash. All keys will be symbolized.
|
971
|
+
#
|
972
|
+
# @return [Hash]
|
973
|
+
#
|
974
|
+
def to_h
|
975
|
+
{ code: code, confidence: confidence }
|
976
|
+
end
|
977
|
+
|
978
|
+
# @private
|
979
|
+
def to_s
|
980
|
+
format "code: %s, confidence: %s", code, confidence
|
981
|
+
end
|
982
|
+
|
983
|
+
# @private
|
984
|
+
def inspect
|
985
|
+
"#<#{self.class.name} #{self}>"
|
986
|
+
end
|
987
|
+
|
988
|
+
##
|
989
|
+
# @private New Annotation::Text::Page::Language from a GRPC
|
990
|
+
# object.
|
991
|
+
def self.from_grpc grpc
|
992
|
+
new.tap { |w| w.instance_variable_set :@grpc, grpc }
|
993
|
+
end
|
994
|
+
end
|
995
|
+
end
|
218
996
|
end
|
219
997
|
end
|
220
998
|
end
|