Первая версия webapp

This commit is contained in:
Vladislav Moiseev 2023-07-06 07:32:59 +04:00
parent 97463c6b35
commit 5da1ecb2e2
6 changed files with 180 additions and 57 deletions

21
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,21 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "webApp.py",
"FLASK_DEBUG": "1"
},
"args": ["run", "--no-debugger", "--no-reload"]
//"args": [ "5cc5570b-6ed9-3b33-9db4-bdb8ecb9f890", "test-data/lectionAudi/2021-03-12 13-51-19.JPG" ]
}
]
}

View File

@ -1,18 +1,18 @@
import cv2 as cv
import numpy as np
from main import img_size as size
img_size = (1280, 720) # Размер изображения для нормализации.
def image_transform(image: np.ndarray) -> np.ndarray:
'''
Трансформирует изображение нужным образом.
@param image: Исходная матрица с представлением изображения.
'''
image = cv.resize(image, (size[0], size[1]))
image = cv.resize(image, (img_size[0], img_size[1]))
return image[:, :, ::-1]
def get_image_as_array(image_name: str) -> np.ndarray:
def get_image_file_as_array(image_name: str) -> np.ndarray:
'''
Получает изображение из файла и нормализует его.
@param image_name: Путь до изображения.
@ -21,3 +21,13 @@ def get_image_as_array(image_name: str) -> np.ndarray:
image: np.ndarray # приведение типов
image = image_transform(image)
return image
def get_image_buf_as_array(buf) -> np.ndarray:
'''
Получает изображение из буфера и нормализует его.
@param image_name: Путь до изображения.
'''
image = cv.imdecode(buf, cv.IMREAD_COLOR)
image: np.ndarray # приведение типов
image = image_transform(image)
return image

48
main.py
View File

@ -2,6 +2,7 @@ import os
import sys
import cv2 as cv
import numpy as np
import requests
import imageWorking
@ -9,24 +10,22 @@ import neuralNetwork
import ontologyWorking
url = 'http://kb.athene.tech/api/1.0/ontology/'
img_path = 'data'
img_size = (1280, 720) # Размер изображения для нормализации.
def analyze_file(uid: str, image_path: str) -> None:
def analyze_base(ontology_uid: str, image: np.ndarray, queries: list[str]) -> tuple[2]:
'''
Анализирует файл и выводит результат в консоль.
@param uid: УИД онтологии.
@param url: Базовый URL сервиса.
Базовая функция анализа файла и вывода результатов обработки.
@param ontology_uid: УИД онтологии.
@param image: Изображение.
'''
if not ontologyWorking.is_ontology_exists(uid, url):
raise Exception(f'Онтология с uid {uid} не существует')
if not os.path.isfile(image_path):
raise Exception(f'Изображение {image_path} не существует')
if not ontologyWorking.is_ontology_exists(ontology_uid, url):
raise Exception(f'Онтология с uid {ontology_uid} не существует')
if image is None:
raise Exception(f'Изображение не указано')
model = neuralNetwork.load_model()
# Распознавание изображения.
results = model.predict(source=imageWorking.get_image_as_array(image_path))
results = model.predict(source=image)
# Создание аксиом онтологии на основе результатов распознавания.
object_properties = list()
@ -47,15 +46,33 @@ def analyze_file(uid: str, image_path: str) -> None:
'dataPropertyAssertions': data_properties
}
}
params = '&'.join([f'names={query}' for query in queries])
# Выполнение запроса.
response = requests.post(url + f'{ontology_uid}/query/multi?{params}', json=data).json()
return results, response
def analyze_file(ontology_uid: str, image_path: str) -> None:
'''
Анализирует файл и выводит результат в консоль.
@param ontology_uid: УИД онтологии.
@param image_path: Путь до изображения.
'''
if not os.path.isfile(image_path):
raise Exception(f'Изображение {image_path} не существует')
image = imageWorking.get_image_file_as_array(image_path)
queries = [ 'QueryGetNotEmpty', 'QueryGetCheck', 'QueryGetEmpty' ]
# Распознавание изображения.
results, response = analyze_base(ontology_uid, image, queries)
result = {
'QueryGetNotEmpty': '',
'QueryGetCheck': '',
'QueryGetEmpty': ''
}
params = '&'.join([f'names={query}' for query in result.keys()])
# Выполнение запроса.
response = requests.post(url + f'{uid}/query/multi?{params}', json=data).json()
if response['error']:
raise Exception(response['error'])
for query in response['response']:
@ -79,6 +96,7 @@ def analyze_file(uid: str, image_path: str) -> None:
cv.waitKey(0)
cv.destroyAllWindows()
# Точка входа в приложение.
if __name__ == '__main__':
if len(sys.argv) != 3:

View File

@ -1,52 +1,41 @@
absl-py==1.4.0
astunparse==1.6.3
cachetools==5.3.0
blinker==1.6.2
certifi==2023.5.7
charset-normalizer==3.1.0
flatbuffers==23.5.9
gast==0.4.0
google-auth==2.18.1
google-auth-oauthlib==1.0.0
google-pasta==0.2.0
grpcio==1.54.2
h5py==3.8.0
click==8.1.3
colorama==0.4.6
contourpy==1.1.0
cycler==0.11.0
filelock==3.12.2
Flask==2.3.2
fonttools==4.40.0
idna==3.4
jax==0.4.10
keras==2.12.0
libclang==16.0.0
Markdown==3.4.3
MarkupSafe==2.1.2
itsdangerous==2.1.2
Jinja2==3.1.2
kiwisolver==1.4.4
MarkupSafe==2.1.3
matplotlib==3.7.1
ml-dtypes==0.1.0
numpy==1.23.5
oauthlib==3.2.2
mpmath==1.3.0
networkx==3.1
numpy==1.25.0
opencv-python==4.7.0.72
opt-einsum==3.3.0
packaging==23.1
pandas==2.0.1
pandas==2.0.2
Pillow==9.5.0
protobuf==4.23.1
psutil==5.9.5
pyparsing==3.1.0
python-dateutil==2.8.2
pytz==2023.3
PyYAML==6.0
pyasn1==0.5.0
pyasn1-modules==0.3.0
requests==2.30.0
requests-oauthlib==1.3.1
rsa==4.9
scipy==1.10.1
requests==2.31.0
scipy==1.11.0
seaborn==0.12.2
six==1.16.0
tensorboard==2.12.3
tensorboard-data-server==0.7.0
tensorflow==2.12.0
tensorflow-estimator==2.12.0
tensorflow-intel==2.12.0
tensorflow-io-gcs-filesystem==0.31.0
termcolor==2.3.0
sympy==1.12
torch==2.0.1
torchvision==0.15.2
tqdm==4.65.0
typing_extensions==4.5.0
ultralytics==8.0.105
urllib3==1.26.15
Werkzeug==2.3.4
wrapt==1.14.1
typing_extensions==4.6.3
tzdata==2023.3
ultralytics==8.0.123
urllib3==2.0.3
Werkzeug==2.3.6

49
static/index.html Normal file
View File

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Анализ аудиторий</title>
</head>
<body>
<p>
Загрузите изображение в поле ниже, чтобы проверить, на фотография пустая
или заполненная аудитория.
</p>
<form id="uploadForm" action="analyze">
<div>
<label for="image">Нажмите, чтобы загрузить изображение</label>
<input type="file" name="image" id="image" />
</div>
<div>
<label for="ontology">Онтология предметной области</label>
<input type="file" name="ontology" id="ontology" />
</div>
<div>
<button type="submit">Отправить</button>
</div>
</form>
<img src="" alt="Результат" id="imgslot" />
<script>
document
.getElementById("uploadForm")
.addEventListener("submit", (event) => {
event.preventDefault();
const data = new FormData(event.target);
fetch("/analyze", { method: "POST", body: data })
.then((res) => res.json())
.then((data) => {
debugger;
if (data.image) {
document.getElementById("imgslot").src =
"data:image/jpg;base64," + data.image;
}
console.log(data);
});
});
</script>
</body>
</html>

36
webApp.py Normal file
View File

@ -0,0 +1,36 @@
import base64
import cv2 as cv
from flask import Flask, redirect, request
import numpy
from imageWorking import get_image_buf_as_array
from main import analyze_base
app = Flask(__name__, static_url_path = "/")
@app.route("/")
def main():
return redirect('index.html')
@app.route("/analyze", methods=["POST"])
def analyze():
if 'image' not in request.files or request.files['image'].filename == '':
return {
'success': False,
'error': 'Укажите изображение',
}
if 'ontology' in request.files and request.files['ontology'].filename != '':
return {
'success': False,
'error': 'Загрузка онтологии ещё не реализована',
}
img = request.files['image'].read();
img = numpy.fromstring(img, numpy.uint8)
img = get_image_buf_as_array(img)
queries = [ 'QueryGetNotEmpty', 'QueryGetCheck', 'QueryGetEmpty' ]
results, response = analyze_base('5cc5570b-6ed9-3b33-9db4-bdb8ecb9f890', img, queries)
imencoded = cv.imencode(".jpg", results[0].plot())[1]
return {
'success': True,
'data': response,
'image': base64.b64encode(imencoded).decode("utf-8"),
}