| import os |
| import shutil |
| import uuid |
| import logging |
|
|
| from flask import Flask, redirect, url_for, request, flash, session |
| from flask import render_template |
| from flask import send_file |
|
|
| logger = logging.getLogger(__name__) |
| logging.basicConfig(level=logging.INFO) |
|
|
| UPLOAD_FOLDER = '/app/images' |
| OUT_FOLDER = '/app/anno' |
|
|
| app = Flask(__name__) |
| app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0 |
| app.config["SECRET_KEY"] = '#thaistartsfirst!' |
| app.config["IMAGES"] = UPLOAD_FOLDER |
| app.config["OUT"] = OUT_FOLDER |
| app.config["LABELS"] = [] |
| app.config["HEAD"] = 0 |
| app.config["SESSION_PERMANENT"] = False |
|
|
| |
| if not os.path.exists(UPLOAD_FOLDER): |
| os.makedirs(UPLOAD_FOLDER) |
| if not os.path.exists(OUT_FOLDER): |
| os.makedirs(OUT_FOLDER) |
|
|
|
|
| def get_anno_path(user_id): |
| return os.path.join(OUT_FOLDER, f'{user_id}.csv') |
|
|
|
|
| def get_images_directory(user_id): |
| return os.path.join(UPLOAD_FOLDER, f'{user_id}') |
|
|
|
|
| @app.route('/', methods=['GET', 'POST']) |
| def index(): |
| user_id = session.get('_id') |
| |
| if user_id is None: |
| user_id = uuid.uuid4() |
| session['_id'] = user_id |
| logger.info(user_id) |
| anno_path = get_anno_path(user_id) |
| with open(anno_path, 'w') as f: |
| f.write("image,id,name,xMin,xMax,yMin,yMax\n") |
|
|
| if request.method == 'POST': |
| if 'file' not in request.files: |
| flash('No files selected') |
| return redirect('/') |
| img_dir = get_images_directory(user_id) |
| try: |
| os.makedirs(img_dir) |
| except FileExistsError: |
| logger.info('user already has an active session') |
| files = request.files.getlist("file") |
| filenames = [] |
| for f in files: |
| f.save(os.path.join(img_dir, f.filename)) |
| filenames.append(f.filename) |
| app.config["FILES"] = filenames |
| |
| return redirect('/tagger', code=302) |
| else: |
| return render_template('index.html') |
|
|
|
|
| @app.route('/tagger') |
| def tagger(): |
| if (app.config["HEAD"] == len(app.config["FILES"])): |
| |
| app.config["HEAD"] = 0 |
| return redirect(url_for('final')) |
| user_id = session.get('_id') |
| img_dir = get_images_directory(user_id) |
| image = app.config["FILES"][app.config["HEAD"]] |
| labels = app.config["LABELS"] |
| not_end = not(app.config["HEAD"] == len(app.config["FILES"]) - 1) |
| return render_template('tagger.html', not_end=not_end, directory=img_dir, image=image, labels=labels, head=app.config["HEAD"] + 1, len=len(app.config["FILES"])) |
|
|
|
|
| @app.route('/next') |
| def next(): |
| image = app.config["FILES"][app.config["HEAD"]] |
| app.config["HEAD"] = app.config["HEAD"] + 1 |
| user_id = session.get("_id") |
| anno_path = get_anno_path(user_id) |
| with open(anno_path, 'a+') as f: |
| for label in app.config["LABELS"]: |
| f.write(image + "," + |
| label["id"] + "," + |
| label["name"] + "," + |
| str(round(float(label["xMin"]))) + "," + |
| str(round(float(label["xMax"]))) + "," + |
| str(round(float(label["yMin"]))) + "," + |
| str(round(float(label["yMax"]))) + "\n") |
| app.config["LABELS"] = [] |
| return redirect(url_for('tagger')) |
|
|
| @app.route("/final") |
| def final(): |
| return render_template('final.html') |
|
|
| @app.route('/add/<id>') |
| def add(id): |
| xMin = request.args.get("xMin") |
| xMax = request.args.get("xMax") |
| yMin = request.args.get("yMin") |
| yMax = request.args.get("yMax") |
| app.config["LABELS"].append({"id":id, "name":"", "xMin":xMin, "xMax":xMax, "yMin":yMin, "yMax":yMax}) |
| return redirect(url_for('tagger')) |
|
|
| @app.route('/remove/<id>') |
| def remove(id): |
| index = int(id) - 1 |
| del app.config["LABELS"][index] |
| for label in app.config["LABELS"][index:]: |
| label["id"] = str(int(label["id"]) - 1) |
| return redirect(url_for('tagger')) |
|
|
| @app.route('/label/<id>') |
| def label(id): |
| name = request.args.get("name") |
| app.config["LABELS"][int(id) - 1]["name"] = name |
| return redirect(url_for('tagger')) |
|
|
| @app.route('/image/<f>') |
| def images(f): |
| user_id = session.get('_id') |
| img_dir = get_images_directory(user_id) |
| img_path = os.path.join(img_dir, f'{f}') |
| return send_file(img_path) |
|
|
| @app.route('/download') |
| def download(): |
| user_id = session.get('_id') |
| anno_path = get_anno_path(user_id) |
| img_dir = get_images_directory(user_id) |
| shutil.copyfile(anno_path, f'{img_dir}/annotations_pascal_voc.csv') |
| shutil.make_archive('final', 'zip', img_dir) |
| return send_file('final.zip', |
| mimetype='text/csv', |
| download_name='final.zip', |
| as_attachment=True) |
|
|
| if __name__ == "__main__": |
| app.run(debug="True") |
|
|