1

These bounds are returned from the doctext.py DocText.py:

def draw_boxes(image, bounds, color):

    draw = ImageDraw.Draw(image)
    for bound in bounds:
    draw.polygon([
        bound.vertices[0].x, bound.vertices[0].y,
        bound.vertices[1].x, bound.vertices[1].y,
        bound.vertices[2].x, bound.vertices[2].y,
        bound.vertices[3].x, bound.vertices[3].y], None, color)
return image


def get_document_bounds(image_file, feature):

client = vision.ImageAnnotatorClient()

bounds = []

with io.open(image_file, 'rb') as image_file:
    content = image_file.read()

image = types.Image(content=content)

response = client.document_text_detection(image=image)
document = response.full_text_annotation

# Collect specified feature bounds by enumerating all document features
for page in document.pages:
    for block in page.blocks:
        for paragraph in block.paragraphs:
            for word in paragraph.words:
                for symbol in word.symbols:
                    if (feature == FeatureType.SYMBOL):
                        bounds.append(symbol.bounding_box)

                if (feature == FeatureType.WORD):
                    bounds.append(word.bounding_box)

            if (feature == FeatureType.PARA):
                bounds.append(paragraph.bounding_box)

        if (feature == FeatureType.BLOCK):
            bounds.append(block.bounding_box)

    if (feature == FeatureType.PAGE):
        bounds.append(block.bounding_box)

# The list `bounds` contains the coordinates of the bounding boxes.
return bounds


def render_doc_text(filein, fileout):
    image = Image.open(filein)
    bounds = get_document_bounds(filein, FeatureType.PAGE)
    draw_boxes(image, bounds, 'blue')
    bounds = get_document_bounds(filein, FeatureType.PARA)
    draw_boxes(image, bounds, 'red')
    bounds = get_document_bounds(filein, FeatureType.WORD)
    draw_boxes(image, bounds, 'yellow')

app.py using flask:

@app.route('/tagger')
def tagger():
    if (app.config["HEAD"] == len(app.config["FILES"])):
        return redirect(url_for('bye'))
    directory = app.config['IMAGES']
    image = app.config["FILES"][app.config["HEAD"]]
    labels = app.config["LABELS"]
    not_end = not(app.config["HEAD"] == len(app.config["FILES"]) - 1)
    opn = 'directory/'
    for f in os.listdir(opn):
        boundingpoly = doctext.render_doc_text(os.path.join(opn,f))
    print(boundingpoly)
    print(type(boundingpoly))
    print(not_end)
    return render_template('tagger.html', not_end=not_end, directory=directory, image=image, bounds=boundingpoly, labels=labels, head=app.config["HEAD"] + 1, len=len(app.config["FILES"]))

boundingpoly value

boundingpoly =
    [vertices {
      x: 15
      y: 5
    }
    vertices {
      x: 28
      y: 2
    }
    vertices {
      x: 37
      y: 49
    }
    vertices {
      x: 24
      y: 51
    }
    ]

when I pass bounds to html, I want to access this boundingpoly list in js for drawing rectangles using the canvas js in html

 <script>
    var bounds = {{bounds}}
    </script>

It is not working.

I want to read it as an object in js and access these object vertices and draw on canvas.

bounds.vertices.forEach(vertices => {
              ctx.beginPath();
              ctx.moveTo(vertices[0].x, vertices[0].y)
              for (var i = 1; i < vertices.length; i++) {
                ctx.lineTo(vertices[i].x, vertices[i].y);
              }
              ctx.closePath();
              ctx.fillStyle = "pink";
              ctx.strokeStyle = "pink";
              ctx.stroke();
              ctx.lineWidth="5";

when render template variable bounds it is passing as a list and is not able to read in javascript and even tried json dumps, it is displaying Object BoundingPoly is not Json serializable. How am I supposed to do it?

  • what tutorial? What do you get with this code ? what result do you need ? Put all information in question. – furas May 03 '19 at 04:39
  • first: put all information in question. especially link to documentation. People read question but don't have to read comments. Second: don't put all text in title. – furas May 03 '19 at 04:53
  • what do you get with `print(boundingpoly)` ? what do you get in HTML in `var bounds = {{bounds}}` ? What is expected result for `var bounds = {{bounds}}` ? Put examples in question. – furas May 03 '19 at 06:13
  • yes. I don't understand what you have in variables and why it gives error `Object BoundingPoly is not Json`. It seems you have some strange objects in `boundingpoly` which you should convert manually to expected list or dictionary before you use in JavaScript. – furas May 03 '19 at 07:18
  • now I see JavaScript code and it seems you need `var bounds = {'vertices':[[{'x': 15, 'y': 5}, {'x': 28, 'y': 2}, {'x': 37, 'y': 49}], [...], [...]]}` but your `boundingpoly` has different structure. – furas May 03 '19 at 07:23
  • do you mean `` or `list with classes` ? `` is normal list which you can conver to string `[ items ... ]` and it is also JavaScript list. You can also use other primitive types like list, dictionary, string, int, float - you can convert them to string manually or using module `json`. But you can't use other Python's classes in JavaScript. – furas May 03 '19 at 11:09
  • it is normal list so convert to string using `str(boundingpoly)` or `json.dumps(boundingpoly)` . But if your list has structure `["vertices": {"x": 15, "y": 5}, "vertices": {"x": 28, "y": 2} ...` then it may not works. I think JavaScript code expects `{'vertices':[[{'x': 15, 'y': 5}, {'x': 28, 'y': 2}, {'x': 37, 'y': 49}], [...], [...]]}` – furas May 03 '19 at 11:19
  • it obvious. You have to change it to correct format in Python's code before you send to template. You can do it in `tagger()` or even in `get_document_bounds()`. Currently you have one list but you have to group 4 points to separated lists. Or you have to change JavaScript code so it will works with your data - but it can be more difficult. – furas May 04 '19 at 11:36

1 Answers1

0

You have

var bounds = [
    { x: 15 y: 5} { x: 28 y: 2} { x: 37 y: 49} { x: 24 y: 51},
    { x: 106 y: 5} { x: 252 y: 3} { x: 252 y: 36} { x: 106 y: 38},
    { x: 16 y: 40} { x: 296 y: 41} { x: 296 y: 100} { x: 16 y: 99},
]    

but I think Javascript expects

var bounds = {'vertices': [
    [{'x': 15, 'y': 5}, {'x': 28, 'y': 2}, {'x': 37, 'y': 49}, {'x': 24, 'y': 51}],
    [{'x': 106, 'y': 5}, {'x': 252, 'y': 3}, {'x': 252, 'y': 36}, {'x': 106, 'y': 38}],
    [{...}, {...}, {...}, {...}],
]}

Using code from draw_boxes() it could be converted with

result = {'vertices':[]}

for bound in bounds:
    item = [
        {'x': bound.vertices[0].x, 'y': bound.vertices[0].y},
        {'x': bound.vertices[1].x, 'y': bound.vertices[1].y},
        {'x': bound.vertices[2].x, 'y': bound.vertices[2].y},
        {'x': bound.vertices[3].x, 'y': bound.vertices[3].y},
    ]
    result['vertices'].append(item)

print(result)    
furas
  • 134,197
  • 12
  • 106
  • 148