Внешние программы¶
Программа MeterVision достигает максимальной эффективности в сочетание с другими программами, которые способны обрабатывать результаты распознавания машинного зрения. Например, такой программой может быть METLAB или программа пользователя
Для этих целей предусмотрены возможности отправлять результаты распознавания из данной программы во внешние двумя
способами (файлы в output и сервер socket; включение режимов — в Результаты распознавания).
Также из внешних программ можно управлять некоторыми функциями программы MeterVision двумя способами:
Через текстовый файл
input/command.txtв Каталог программы.По socket (если включено «Передавать результаты по socket» в Настройки) — тем же синтаксисом команд, каждая команда на отдельной строке; сервер отвечает
OK/ERROR: ...(или результатами на командуget).
В файл или по socket можно передать сразу несколько команд: каждая команда на отдельной строке. Порядок выполнения — от первой строки к последней.
Возможны следующие команды:
Закрыть программу MeterVision
exit
Сохранить Скриншот
В папку по умолчанию (output/screenshots/ в Каталог программы) с названием файла по умолчанию (дата и время создания)
screenshot
В папку по умолчанию с другим названием
screenshot my_name.png
В указанную папку с другим названием
screenshot path/to/my/dir/my_name.png
Открыть файл настроек зон
open path/to/my/dir/settings.mv
Зафиксировать фон (только для стрелочных методов)
fix_background n
Где n - номер целевой зоны
Снять фиксацию фона (только для стрелочных методов)
unfix_background n
Где n - номер целевой зоны
Зафиксировать центр (только для стрелочных методов)
fix_center n
Где n - номер целевой зоны
Снять фиксацию центра (только для стрелочных методов)
unfix_center n
Где n - номер целевой зоны
Забыть статистику зоны (только для стрелочных методов)
forget_stats n
Где n - номер целевой зоны
Забыть фон (только для стрелочных методов)
forget_background n
Где n - номер целевой зоны
Переключиться на другую шкалу (только для стрелочных методов)
scale n m
Где n - номер целевой зоны, m - номер шкалы, на которую нужно переключиться
Переключить режим отображения результата (только для стрелочных методов)
Результат — показания по шкале
result_mode n scale
Результат — угол наклона стрелки (в градусах)
result_mode n angle
Где n - номер целевой зоны
Пример файла input/command.txt¶
screenshot my_name.png
unfix_background 1
fix_center 1
scale 1 3
result_mode 1 angle
Передача команд и результатов по socket¶
При включённом режиме socket (см. Результаты распознавания) внешняя программа подключается к host/port из
input/socket_config.txt и отправляет текстовые строки с переводом строки в конце.
Разделитель команд и ответов — перевод строки. За одно подключение можно отправить несколько команд;
на каждую команду сервер отвечает одной строкой (для get — строка с результатами вида
{1: '24.10', 2: 'AC'}, для остальных — OK или ERROR: ...).
getилиresults— получить текущие результаты распознавания (один ответ на запрос; на одном соединении команду можно повторять сколько угодно раз).Любая команда из списка выше — выполнить действие; ответ
OKилиERROR: ....
Пример последовательности команд:
get
fix_center 1
scale 1 2
Пример получения результатов (файл examples/socket_results_example.py).
На одном соединении можно многократно вызывать get_results():
import socket
import time
class MeterVisionClient:
def __init__(self, host='localhost', port=65432):
self.host = host
self.port = port
self.sock = None
self._buffer = ''
def connect(self):
"""Подключиться к серверу MeterVision."""
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((self.host, self.port))
self._buffer = ''
print(f"Подключено к серверу {self.host}:{self.port}")
def get_results(self):
"""
Запросить текущие результаты. Можно вызывать многократно
на одном соединении. Возвращает строку вида "{1: '24.10', 2: 'AC'}".
"""
if self.sock is None:
raise RuntimeError('Сначала вызовите connect()')
self.sock.sendall(b'get\n')
while '\n' not in self._buffer:
chunk = self.sock.recv(4096)
if not chunk:
raise ConnectionError('Сервер закрыл соединение')
self._buffer += chunk.decode('utf-8')
line, self._buffer = self._buffer.split('\n', 1)
return line
def close(self):
"""Закрыть соединение."""
if self.sock is not None:
self.sock.close()
self.sock = None
print('Соединение закрыто')
if __name__ == "__main__":
client = MeterVisionClient()
try:
client.connect()
for i in range(5):
results = client.get_results()
print(f"[{i + 1}] Получено:", results)
time.sleep(1)
except ConnectionRefusedError as e:
print(e)
except KeyboardInterrupt:
print('Соединение прервано')
finally:
client.close()
Пример отправки команд (файл examples/socket_commands_example.py):
import socket
def send_commands(commands, host='localhost', port=65432):
"""
Отправляет список команд и печатает ответы сервера.
Args:
commands: список строк-команд без завершающего \\n
host, port: адрес сервера MeterVision
"""
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client_socket.connect((host, port))
print(f"Подключено к серверу {host}:{port}")
except ConnectionRefusedError as e:
print(e)
return
try:
payload = ''.join(cmd.strip() + '\n' for cmd in commands if cmd.strip())
client_socket.sendall(payload.encode('utf-8'))
buffer = ''
replies_expected = sum(1 for cmd in commands if cmd.strip())
replies_got = 0
while replies_got < replies_expected:
data = client_socket.recv(4096)
if not data:
break
buffer += data.decode('utf-8')
while '\n' in buffer:
line, buffer = buffer.split('\n', 1)
print("Ответ:", line)
replies_got += 1
if replies_got >= replies_expected:
break
except KeyboardInterrupt:
print('Соединение прервано')
finally:
client_socket.close()
if __name__ == "__main__":
# Пример: запросить результаты и выполнить команды для стрелочной зоны
send_commands([
'get',
'fix_center 1',
'result_mode 1 scale',
])
Примечание
Эти примеры также находятся в examples/socket_results_example.py и
examples/socket_commands_example.py относительно директории установки программы.