Как мы синхронизировали съемку для возрожденного проекта DPED
Команда регионального научно-образовательного центра «Искусственный интеллект и анализ больших данных» при НГТУ им. Р. Е. Алексеева продолжает рассказывать о работе по возрождению и улучшению DPED (Deep Photo Enhancement Dataset).
Мы решили задачи автоматизации, но столкнулись с еще одной проблемой: фото на планшете и камере снимались с некоторой задержкой относительно друг друга. Использование простых пауз (time.sleep) оказалось ненадежно и неэффективно. Тогда мы реализовали многопоточное решение:
Первый поток управляет съемкой с камеры с помощью библиотеки pyautogui.
Второй поток управляет съемкой с планшета через ADB.
Оба потока обмениваются информацией через очередь (queue.Queue() из стандартной библиотеки Python) — это потокобезопасная структура данных, которая позволяет одному потоку передать сигнал другому. В нашем случае очередь используется для передачи сигнала о начале съемки с камеры. Получив этот сигнал, планшет почти без задержки запускает захват изображения.
В процессе тестирования среднее время задержки составило 50 мс, но разброс данных достигал 93 мс. То есть, существуют случаи, когда мы получаем изображения с непозволительной задержкой в 100 мс и более. Мы отметили этот момент, но продолжили собирать датасет, а изображения с большой задержкой — удалять.
Скрипт автоматизации съемки кадров:
import subprocess
from threading import Thread
import pyautogui
import time
from queue import Queue
# координаты для кликов мыши
CAMERA_SHUTTER_BUTTON = (329, 748) # кнопка затвора в приложении
FOCUS_POINT = (1189, 204) # точка фокуса или область кадра
def tablet(q):
time.sleep(0.1)
if q.get() == 1:
p = subprocess.Popen(r'.\adb.exe shell', stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdin.write(b'input keyevent 27')
p.stdin.close()
def camera(q):
pyautogui.click(*CAMERA_SHUTTER_BUTTON)
pyautogui.moveTo(*FOCUS_POINT)
q.put(1)
pyautogui.mouseDown()
time.sleep(0.02)
pyautogui.mouseUp()
q = Queue()
thread1 = Thread(target=camera, args=(q,))
thread2 = Thread(target=tablet, args=(q,))
thread1.start()
thread2.start()
В оригинальной работе DPED точные значения задержки не указывались: авторы фиксировали устройства на механическом стенде и выполняли съемку вручную, без программной синхронизации или последующего анализа временного лага между кадрами. Насколько нам удалось выяснить, синхронизация производилась «на глаз», что не позволяет оценить точность в миллисекундах. Таким образом, можно утверждать, что наша реализация обеспечивает более детерминированный и измеримый результат по синхронизации.
Читайте в статье, как команда регионального научно-образовательного центра «Искусственный интеллект и анализ больших данных» при НГТУ доводит снимки с планшета YADRO KVADRA_T до качества полупрофессиональной камеры Sony Alpha ILCE 6600.