--Sur la première page, chaque menu est affiché en fonction de CLASSES dans config.py.
――Vous pouvez comparer à la fois dans Télécharger l'image et l'image du visage.
—— Vous pouvez également cliquer sur l'image du visage pour la supprimer en une seule fois.


Pillow est utilisé pour redimensionner l'image.Bootstrap.Font Awesome. Cette fois, je l'utilise avec l'icône de la corbeille affichée en haut à droite de l'image du visage. presque tel quel. --CLASSES dans config.py est passé comme ʻitems dans ʻindex.html`.Bootstrap pour identifier chaque menu.image_viewer.py
@app.route('/')
def index():
"""Top Page."""
return render_template('index.html', items=CLASSES)
templates/index.html
<div class="container-fluid">
{% for item in items %}
<div class="row">
<div class="col">
{{ loop.index }} {{ item }}
</div>
<div class="col-11">
<a class="btn btn-primary" href="/download_and_face/{{ item }}" role="button">Télécharger l'image, l'image du visage</a>
<a class="btn btn-secondary" href="/predict/train/{{ item }}" role="button">Résultat de la prédiction de l'image d'entraînement</a>
<a class="btn btn-success" href="/predict/test/{{ item }}" role="button">Résultat de la prédiction de l'image de test</a>
</div>
</div>
<br />
{% endfor %}
</div>
DOWNLOAD_PATH, les images téléchargées par Google Custom Search etc. sont enregistrées.FACE_PATH, l'image de reconnaissance faciale utilisant Haar Cascade de ʻOpenCV` est sauvegardée.
--En outre, le nom de fichier est généré en fonction du nom de fichier de l'image téléchargée.--Recevoir ʻAbe Otsu etc. avec ʻitem.
--Créez une liste d'images téléchargées en utilisant DOWNLOAD_PATH ʻitem * .jpeg` comme clé. --Créez une liste d'images de visage en utilisant `FACE_PATH` ʻitem * .jpeg` comme clé.
image_viewer.py
@app.route('/download_and_face/<item>', methods=['GET', 'POST'])
def download_and_face(item):
"""Télécharger l'image, l'image du visage."""
download_list = glob.glob(os.path.join(DOWNLOAD_PATH, item, '*.jpeg'))
download_list = sorted([os.path.basename(filename) for filename in download_list])
face_list = glob.glob(os.path.join(FACE_PATH, item, '*.jpeg'))
face_list = sorted([os.path.basename(filename) for filename in face_list])
ligne est créé.image_viewer.py
rows = []
for download in download_list:
row = [download]
key = download.split('.')[0] + '-'
for face in face_list:
if face.startswith(key):
row.append(face)
rows.append(row)
return render_template('download_and_face.html', item=item, rows=rows)
size = 200. Cette taille est la taille verticale de l'image.
―― En faisant correspondre les tailles, il sera plus facile de comparer l'image téléchargée et l'image du visage.
--Dans l'image du visage, CSS et JS sont utilisés pour pouvoir être facilement spécifiés en cliquant.
«Ici, j'ai évoqué ce qui suit.
templates/download_and_face.html
<tbody>
{% for row in rows %}
<tr>
<td>
{{ loop.index }}
</td>
<td>
<figure class="figure">
<img src="/data/download/{{ item }}/{{ row[0] }}?size=200" />
<figcaption class="figure-caption">{{ row[0] }}</figcaption>
</figure>
</td>
<td>
{% for filename in row[1:] %}
<figure class="figure">
<label class="image-checkbox">
<img src="/data/face/{{ item }}/{{ filename }}?size=200" />
<input type="checkbox" name="filename" value="{{ filename }}" />
<i class="fa fa-trash-o d-none"></i>
</label>
<figcaption class="figure-caption">{{ filename }}</figcaption>
</figure>
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
static/download_and_face.css
.image-checkbox {
cursor: pointer;
border: 2px solid transparent;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
position: relative;
}
.image-checkbox input[type="checkbox"] {
display: none;
}
.image-checkbox-checked {
border-color: #d9534f;
}
.image-checkbox .fa {
color: #ffffff;
background-color: #d9534f;
font-size: 20px;
padding: 4px;
position: absolute;
right: 0;
top: 0;
}
.image-checkbox-checked .fa {
display: block !important;
}
--Au moment du premier affichage, l'état de la case à cocher est défini sur la classe.
static/download_and_face.js
// image gallery
// init the state from the input
$(".image-checkbox").each(function () {
if ($(this).find('input[type="checkbox"]').first().attr("checked")) {
$(this).addClass('image-checkbox-checked');
}
else {
$(this).removeClass('image-checkbox-checked');
}
});
// sync the state to the input
$(".image-checkbox").on("click", function (e) {
$(this).toggleClass('image-checkbox-checked');
var $checkbox = $(this).find('input[type="checkbox"]');
$checkbox.prop("checked",!$checkbox.prop("checked"))
e.preventDefault();
});
--Générer le chemin de l'image téléchargée et de l'image du visage.
image_viewer.py
@app.route('/data/<folder>/<item>/<filename>')
def get_image(folder, item, filename):
"""Échelle avec la taille de réponse de l'image."""
if folder not in ['download', 'face']:
abort(404)
filename = os.path.join(DATA_PATH, folder, item, filename)
--Utilisez Pillow pour charger l'image.
image_viewer.py
try:
image = Image.open(filename)
except Exception as err:
pprint.pprint(err)
abort(404)
--S'il y a une taille dans l'option URL, modifiez la taille de l'image.
―― Dans ce cas, l'image sera mise à l'échelle en fonction de la taille verticale.
―― En alignant la taille verticale avec l'image téléchargée et l'image du visage, il est plus facile de comparer visuellement.
image_viewer.py
if 'size' in request.args:
height = int(request.args.get('size'))
width = int(image.size[0] * height / image.size[1])
image = image.resize((width, height), Image.LANCZOS)
--Enfin, convertissez les données Pillow en données octets et créez une réponse avec ʻimage / jpeg`.
image_viewer.py
data = io.BytesIO()
image.save(data, 'jpeg', optimize=True, quality=95)
response = make_response()
response.data = data.getvalue()
response.mimetype = 'image/jpeg'
return response
--Le nom de fichier de l'image du visage à supprimer dans le formulaire est POSTé. --Vérifiez l'image du visage cible et supprimez-la avec ʻos.remove`. «Je pense qu'un mécanisme plus prudent est ici nécessaire, mais c'est un formulaire simple en supposant qu'il sera utilisé par des individus.
image_viewer.py
@app.route('/download_and_face/<item>', methods=['GET', 'POST'])
def download_and_face(item):
"""Télécharger l'image, l'image du visage."""
if request.method == 'POST' and request.form.get('action') == 'delete':
for filename in request.form.getlist('filename'):
filename = os.path.join(FACE_PATH, item, filename)
if os.path.isfile(filename):
os.remove(filename)
print('delete face image: {}'.format(filename))