Compare commits

..

2 Commits

7 changed files with 108 additions and 29 deletions

View File

@ -11,7 +11,7 @@
<option name="IS_MODULE_SDK" value="true" /> <option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" /> <option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" /> <option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/main.py" /> <option name="SCRIPT_NAME" value="$PROJECT_DIR$/src/main.py" />
<option name="PARAMETERS" value="5cc5570b-6ed9-3b33-9db4-bdb8ecb9f890 &quot;test-data/lectionAudi/2021-03-12 13-51-07.JPG&quot;" /> <option name="PARAMETERS" value="5cc5570b-6ed9-3b33-9db4-bdb8ecb9f890 &quot;test-data/lectionAudi/2021-03-12 13-51-07.JPG&quot;" />
<option name="SHOW_COMMAND_LINE" value="false" /> <option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" /> <option name="EMULATE_TERMINAL" value="false" />

View File

@ -11,7 +11,7 @@
<option name="IS_MODULE_SDK" value="true" /> <option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" /> <option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" /> <option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/main.py" /> <option name="SCRIPT_NAME" value="$PROJECT_DIR$/src/main.py" />
<option name="PARAMETERS" value="5cc5570b-6ed9-3b33-9db4-bdb8ecb9f890 &quot;test-data/lectionAudi/2021-03-12 13-49-32.JPG&quot;" /> <option name="PARAMETERS" value="5cc5570b-6ed9-3b33-9db4-bdb8ecb9f890 &quot;test-data/lectionAudi/2021-03-12 13-49-32.JPG&quot;" />
<option name="SHOW_COMMAND_LINE" value="false" /> <option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" /> <option name="EMULATE_TERMINAL" value="false" />

View File

@ -11,7 +11,7 @@
<option name="IS_MODULE_SDK" value="true" /> <option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" /> <option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" /> <option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/main.py" /> <option name="SCRIPT_NAME" value="$PROJECT_DIR$/src/main.py" />
<option name="PARAMETERS" value="5cc5570b-6ed9-3b33-9db4-bdb8ecb9f890 &quot;test-data/lectionAudi/2021-03-12 13-48-31.JPG&quot;" /> <option name="PARAMETERS" value="5cc5570b-6ed9-3b33-9db4-bdb8ecb9f890 &quot;test-data/lectionAudi/2021-03-12 13-48-31.JPG&quot;" />
<option name="SHOW_COMMAND_LINE" value="false" /> <option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" /> <option name="EMULATE_TERMINAL" value="false" />

25
.run/webApp.run.xml Normal file
View File

@ -0,0 +1,25 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="webApp" type="PythonConfigurationType" factoryName="Python">
<module name="VideoAnalysis" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
<env name="FLASK_APP" value="src/webApp.py" />
<env name="FLASK_DEBUG" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="flask" />
<option name="PARAMETERS" value="run" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="true" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
</component>

View File

@ -11,13 +11,39 @@ def is_ontology_exists(ontology_uid: str, url: str) -> bool:
@param ontology_uid: УИД онтологии. @param ontology_uid: УИД онтологии.
@param url: Базовый URL сервиса. @param url: Базовый URL сервиса.
''' '''
list_ontologies = requests.get(url).json()['response']['items'] list_ontologies = requests.get(url).json()
list_ontologies = list_ontologies['response']['items']
for onto in list_ontologies: for onto in list_ontologies:
if onto['uid'] == ontology_uid: if onto['uid'] == ontology_uid:
return True return True
return False return False
def upload_ontology(name: str, file_buf) -> str:
"""
Загружает файл.
:param name: Имя файла.
:param file_buf: Содержимое файла.
:return: УИД загруженной онтологии.
"""
files = {'file': file_buf}
response = requests.post(f'{url}?name={name}', files=files)
response = response.json()
return response['response']['uid']
def delete_ontology(ontology_uid: str) -> bool:
"""
Загружает файл.
:param name: Имя файла.
:param file_buf: Содержимое файла.
:return: УИД загруженной онтологии.
"""
response = requests.delete(url + ontology_uid)
response = response.json()
return False if response['error'] else True
def rename_entity(list_names: dict) -> dict: def rename_entity(list_names: dict) -> dict:
''' '''
Нормализация названий объектов. Нормализация названий объектов.
@ -52,16 +78,24 @@ def get_request_data(entities: dict, objects: np.ndarray, confs: np.ndarray, box
for entity_idx, entity in enumerate(entities): for entity_idx, entity in enumerate(entities):
if (entity_idx in objects): if (entity_idx in objects):
object_properties.append({'domain': entity, 'property': 'locatedIn', 'range': classroom}) object_properties.append(
{'domain': entity, 'property': 'locatedIn', 'range': classroom})
else: else:
object_properties.append({'domain': entity, 'property': 'notLocatedIn', 'range': classroom}) object_properties.append(
{'domain': entity, 'property': 'notLocatedIn', 'range': classroom})
for object_idx, object in enumerate(objects): for object_idx, object in enumerate(objects):
conf = confs[object_idx] conf = confs[object_idx]
box = boxes[object_idx] box = boxes[object_idx]
entity = entities[object.item()] entity = entities[object.item()]
data_properties.append({'domain': entity, 'property': 'hasArea', 'value': get_entity_square(float(box[2]), float(box[3]))}) data_properties.append(
data_properties.append({'domain': entity, 'property': 'hasConfidence', 'value': float(conf)}) {'domain': entity,
'property': 'hasArea',
'value': get_entity_square(float(box[2]), float(box[3]))})
data_properties.append(
{'domain': entity,
'property': 'hasConfidence',
'value': float(conf)})
return object_properties, data_properties return object_properties, data_properties
@ -88,6 +122,7 @@ def analyze(ontology_uid: str, object_properties: list, data_properties: list, q
params = '&'.join([f'names={query}' for query in queries]) params = '&'.join([f'names={query}' for query in queries])
# Выполнение запроса. # Выполнение запроса.
response = requests.post(url + f'{ontology_uid}/query/multi?{params}', json=data).json() response = requests.post(
url + f'{ontology_uid}/query/multi?{params}', json=data).json()
return response return response

View File

@ -4,13 +4,16 @@ from flask import Flask, redirect, request
import numpy import numpy
from imageWorking import get_image_buf_as_array from imageWorking import get_image_buf_as_array
from main import analyze_base from main import analyze_base
from ontologyWorking import delete_ontology, upload_ontology
app = Flask(__name__, static_folder="../static", static_url_path="/")
app = Flask(__name__, static_folder = "../static", static_url_path = "/")
@app.route("/") @app.route("/")
def main(): def main():
return redirect('index.html') return redirect('index.html')
@app.route("/analyze", methods=["POST"]) @app.route("/analyze", methods=["POST"])
def analyze(): def analyze():
# Первоначальные проверки. # Первоначальные проверки.
@ -19,20 +22,27 @@ def analyze():
'success': False, 'success': False,
'error': 'Укажите изображение', 'error': 'Укажите изображение',
} }
ontology_uid = '5cc5570b-6ed9-3b33-9db4-bdb8ecb9f890'
remove_ontology = False
if 'ontology' in request.files and request.files['ontology'].filename != '': if 'ontology' in request.files and request.files['ontology'].filename != '':
return { ontology_uid = upload_ontology(
'success': False, request.files['ontology'].filename, request.files['ontology'])
'error': 'Загрузка онтологии ещё не реализована', remove_ontology = True
}
# Подготовка исходного изображения. # Подготовка исходного изображения.
image_source = request.files['image'].read(); image_source = request.files['image'].read()
image_source = numpy.fromstring(image_source, numpy.uint8) image_source = numpy.fromstring(image_source, numpy.uint8)
image_source = get_image_buf_as_array(image_source) image_source = get_image_buf_as_array(image_source)
# Подготовка прочих данных и выполнение запроса. # Подготовка прочих данных и выполнение запроса.
queries = request.form['queries'].split(',') if request.form['queries'] is not None else [ ] queries = request.form['queries'].split(
results, response = analyze_base('5cc5570b-6ed9-3b33-9db4-bdb8ecb9f890', image_source, queries) ',') if request.form['queries'] is not None else []
results, response = analyze_base(ontology_uid, image_source, queries)
# Если требуется, чистим за собой.
if remove_ontology:
delete_ontology(ontology_uid)
# Подготовка изображения с ответом. # Подготовка изображения с ответом.
image_result = results[0].plot() image_result = results[0].plot()

View File

@ -26,19 +26,28 @@
<div class="card-body"> <div class="card-body">
<div class="row"> <div class="row">
<div class="col-lg"> <div class="col-lg">
<p class="alert alert-info">Загрузите изображение в поле ниже, чтобы проверить, на фотография пустая или заполненная аудитория.</p> <p class="alert alert-info">Загрузите изображение и, если требуется, собственную онтологию для анализа.</p>
<form id="uploadForm" action="analyze"> <form id="uploadForm" action="analyze">
<div> <div class="my-3">
<label for="image" class="form-label">Нажмите, чтобы загрузить изображение</label> <label for="image" class="form-label">Изображение для анализа</label>
<input type="file" class="form-control" name="image" id="image" /> <input type="file" class="form-control" name="image" id="image" />
</div> </div>
<div> <div class="my-3">
<label for="ontology" class="form-label">Онтология предметной области</label> <label for="ontology" class="form-label">Онтология предметной области</label>
<input type="file" class="form-control" name="ontology" id="ontology" /> <input type="file" class="form-control" name="ontology" id="ontology" aria-describedby="ontologyHelp" />
<div id="ontologyHelp" class="form-text">Для анализа заполненности аудиторий оставьте это поле пустым.</div>
</div> </div>
<div> <div class="my-3">
<label for="queries" class="form-label">Набор запросов для запуска</label> <label for="queries" class="form-label">Набор запросов для запуска</label>
<input type="text" class="form-control" name="queries" id="queries" value="QueryGetNotEmpty,QueryGetCheck,QueryGetEmpty" /> <input
type="text"
class="form-control"
name="queries"
id="queries"
aria-describedby="queriesHelp"
value="QueryGetNotEmpty,QueryGetCheck,QueryGetEmpty"
/>
<div id="queriesHelp" class="form-text">Для анализа заполненности аудиторий не изменяйте это поле.</div>
</div> </div>
<div class="my-3"> <div class="my-3">
<button type="submit" class="btn btn-primary">Отправить</button> <button type="submit" class="btn btn-primary">Отправить</button>