--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))