Solution 1 :

Create a list of dictionaries of the data you need and return that. Then you can loop over the data and build your table.

results = []
for i in range(topK):
    result = ('t%s - %.2f'%(classes[ind[i].asscalar()], nd.softmax(pred)[0][ind[i]].asscalar()*100))
    datadict = {
         'header': yourheadername,
         'data': yourdatahere
    }
        
    results.append(datadict)

return results


<table border=1>
{% for result in results%}
    <tr>
      <th>
        {{result.header}}
      </th>
    </tr>
    <tr>
      <td>
        {{result.data}}
      </td> 
    </tr>
{% endfor %}

    </table>

Solution 2 :

If you’re working in a terminal or in a Jupyter notebook, plt.show() does what you want. For a web page, not so much.

You have a good start otherwise, based it seems on getting an uploaded image to display. So your challenge will be to either save the matplotlib image to disk before you generate the page, or to defer generating the image until it’s requested by way of the <img src=..., then somehow return the image bits from cv_acp_TSN_PIC_display_image instead of a path to the saved file.

To do the former, plt.savefig('uploads/image.png') might be what you need, with the caveat that a fixed filename will break things badly as soon as you have multiple users hitting the app.

To do the latter, see this question and its answer.

Problem :

I am trying to print basically a table to display data from a function I have called on flask on a webpage. I looked over Jinga templates and that is what I attempted to use, however to no avail.

My code is attached below. result from my cv_acp file is what I am trying to display in a table form.

Currently, my TSN_PIC returns result as follows:

The input video frame is classified to be PlayingCello – 99.33
PlayingGuitar – 0.28 PlayingPiano – 0.16 BoxingSpeedBag – 0.10
StillRings – 0.06

But I want to be able to display this on a web page using flask in a table format

My code is as follows:

cv_acp

def TSN_PIC(img):
    img = image.imread(img)
 
    fig, ax = plt.subplots(figsize=(18, 18))
    ax.imshow(img.asnumpy())

    transform_fn = transforms.Compose([
    video.VideoCenterCrop(size=224),
    video.VideoToTensor(),
    video.VideoNormalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])
    img_list = transform_fn([img.asnumpy()])
    net = get_model('vgg16_ucf101', nclass=101, pretrained=True)
    pred = net(nd.array(img_list[0]).expand_dims(axis=0))
    classes = net.classes
    topK = 5
    ind = nd.topk(pred, k=topK)[0].astype('int')
    print('The input video frame is classified to be')
    for i in range(topK):
        result = ('t%s - %.2f'%(classes[ind[i].asscalar()], nd.softmax(pred)[0][ind[i]].asscalar()*100))
        print((result)) 
    return plt.show()

app.py

@app.route("/cv/action_prediction/TSN_PIC", methods=['POST'])
def cv_acp_TSN_PIC_upload_image():
    if 'file' not in request.files:
        flash('No file part')
        return redirect(request.url)
    file = request.files['file']
    if file.filename == '':
        flash('No image selected for uploading')
        return redirect(request.url)
    if file and allowed_file(file.filename):
        filename = secure_filename(file.filename)
        print(app.config)
        path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
        print(path)
        file.save(path)
        #print(file.config)
        result = cv_acp.TSN_PIC(path)
       # print (results)
        #print('upload_image filename: ' + filename)
        flash('Image successfully uploaded and displayed below')
        return render_template('cv_acp_TSN_PIC.html', filename=filename, result=result)
    else:
        flash('Allowed image types are -> png, jpg, jpeg, gif')
        return redirect(request.url)


@app.route('/cv/action_prediction/TSN_PIC/display/<filename>')
def cv_acp_TSN_PIC_display_image(filename):
    #print('display_image filename: ' + filename)
    #return MASK_RCNN('static', filename='uploads/' + filename)
    return redirect(url_for('static', filename='uploads/' + filename), code=301)

if __name__ == "__main__":
#app.run()
app.run()

cv_acp_TSN_PIC.html

<div id="content" class="p-4 p-md-5 pt-5">

        <h2 class="mb-4">TSN PIC</h2>
        <!Doctype html>
<title>Python Flask File Upload Example</title>
<h2>Select a file to upload</h2>
<p>
    {% with messages = get_flashed_messages() %}
      {% if messages %}
        <ul>
        {% for message in messages %}
          <li>{{ message }}</li>
        {% endfor %}
        </ul>
      {% endif %}
    {% endwith %}
</p>
{% if filename %}
    <div>
        <img src="{{ url_for('cv_acp_TSN_PIC_display_image', filename=filename) }}">
        {% block content %}
    <div class="container">
        <p>{{results}}</p>
    </div>
{% endblock %}
    </div>
    

    
{% endif %}
<form method="post" action="/cv/action_prediction/TSN_PIC" enctype="multipart/form-data">
    <dl>
        <p>
            <input type="file" name="file" autocomplete="off" required>
        </p>
    </dl>
    <p>
        <input type="submit" value="Submit">
    </p>
</form>
      </div>

Comments

Comment posted by Blob

Okay so I tried this approach. The dictionary in my ml file returns values all good, but it is still not returning anything or displaying anything on the webapp. So for my app.py file, what I am doing is setting my ml function into a variable ‘result’ and then doing return render_template(‘upload.html’, filename=filename, result=result). Inspecting the webapp returns all clear so I am guessing it is something to do with what I am doing in my app.py.

Comment posted by Blob

Hi Dave! This is something which I do caught and did replace with plt.savefig. What I am worried more is that this ml function is supposed to return some predictions in text and I am unable to show that on webapp. Although you rightly caught my attention at, “…with the caveat that a fixed filename will break things badly as soon as you have multiple users hitting the app.”- I really have to find a way to fix this now, did not think of this as such before.

Comment posted by Dave W. Smith

If prediction returns text, pass that to the template. If you’ve saved the image to a unique filename, you can pass that name, too, and stuff it into the

By