В этом разделе описывается реализовать функцию потока приобретения вашего адаптера. В потоковом проекте адаптера функция потока приобретения выполняет фактическое приобретение кадров от устройства. Когда вы создаете поток (Открытие и закрытие Связи с Устройством), вы задаете имя этой функции потока приобретения как начальный адрес для нового потока.
Механизм тулбокса вызывает функцию потока приобретения косвенно, когда пользователь вызывает start
, getsnapshot
или функцию preview
. После того, как названный, функция потока приобретения получает кадры, пока конкретное количество кадров не было получено, или пользователь вызывает функцию stop
.
Проект функции потока приобретения может значительно отличаться между различными адаптерами, в зависимости от требований SDK устройства. Этот раздел не описывает зависящие от устройств детали реализации, а скорее подсвечивает требуемые задачи, которые характерны для всех реализаций.
На его высшем уровне, в потоковом проекте, функция потока приобретения обычно содержит два цикла:
Цикл сообщения потока является основным циклом обработки в функции потока приобретения. Вы создаете поток в функции openDevice()
. Функция потока приобретения вводит цикл сообщения потока, ожидающий сообщения, чтобы начать получать кадры. Функция startCapture()
вашего адаптера отправляет сообщение в поток приобретения, говоря ему начать получать кадры. Этот пример использует сообщение WM_USER
, чтобы указать на это состояние. Смотрите Отправку сообщения к Потоку Приобретения для получения дополнительной информации.
Когда это получает соответствующее сообщение, функция потока приобретения вводит цикл приобретения кадра. Следующая фигура иллюстрирует это взаимодействие между вашими функциями адаптера и потоком приобретения. Для получения информации о цикле приобретения кадра смотрите Цикл Приобретения Кадра.
Взаимодействие функций адаптера и потока приобретения
Цикл приобретения кадра - то, где ваш адаптер получает кадры от устройства и отправляет их в механизм. Этот процесс включает следующие шаги:
Проверяйте, было ли конкретное количество кадров получено. Цикл приобретения кадра получает кадры от устройства, пока конкретное количество кадров не было получено. Используйте функцию членства IAdaptor
isAcquisitionNotComplete()
, чтобы определить, необходимо ли больше кадров.
Если бы ваш адаптер поддерживает аппаратные триггеры, вы проверяли бы, сконфигурирован ли аппаратный триггер здесь — Поддерживающий Аппаратные Триггеры.
Захватите кадр от устройства. Этот код абсолютно зависит от вашего API SDK устройства. Со многими устройство SDKs вы выделяете буфер, и устройство заполняет его с данными изображения. См. документацию API своего устройства, чтобы изучить, как получить кадры от вашего устройства.
Проверяйте, необходимо ли передать полученный кадр к механизму, с помощью функции членства IAdaptor
isSendFrame()
. Это - то, как тулбокс реализует свойство FrameGrabInterval
, где пользователи могут указать, что только хотят получить любой кадр, например.
Если необходимо передать кадр к механизму, группируйте кадр в объекте IAdaptorFrame
; в противном случае пропустите к шагу 5.
Создайте объект кадра, с помощью объекта IEngine
функция членства makeFrame()
. Необходимо задать размерности фрейма изображения и тип кадра, когда вы создаете объект кадра.
Поместите полученные данные изображения в объект кадра, с помощью объекта IAdaptorFrame
функция членства setImage()
. Вы задаете указатель на буфер, который содержит данные изображения, ширину кадра и высоту и любые смещения от левого верхнего угла изображения.
Для получения информации об определении ширины кадра высота, и смещенный с КОРОЛЯМИ, видит КОРОЛЕЙ Поддержки.
Регистрируйте время приобретения в объекте кадра, с помощью функции членства IAdaptorFrame
setTime()
. SDKs устройства иногда обеспечивают доступ к информации о метке времени, но можно также использовать набор адаптера функция getCurrentTime()
.
Передайте группированный кадр к механизму, с помощью функции членства IEngine
receiveFrame()
.
Постепенно увеличьте количество кадра с помощью функции членства IAdaptor
incrementFrameCount()
. Необходимо ли передать кадр или нет, необходимо всегда постепенно увеличивать количество кадра каждый раз, когда вы получаете кадр.
Возвратитесь к верхней части цикла приобретения кадра.
Следующая фигура иллюстрирует цикл приобретения кадра.
Возможный алгоритм для цикла приобретения кадра
Следующее является объявлением функции потока приобретения. Можно дать процедуре потока приобретения любое имя, такое как acquireThread()
.
DWORD WINAPI acquireThread(void* ThreadParam);
Ваша функция потока должна принять один параметр, который задан как указатель на сам объект, т.е. указатель this
. Функция потока возвращает значение, которое указывает на успешность или неуспешность. Для получения дополнительной информации см. документацию на веб-сайте Microsoft® Developer Network (msdn.microsoft.com
).
Следующее является функцией потока приобретения, что можно использовать с примером MyDeviceAdaptor
. Замените скелетную реализацию, которую вы использовали в Запуске Потока Приобретения с этим кодом.
DWORD WINAPI MyDeviceAdaptor::acquireThread(void* param) { MyDeviceAdaptor* adaptor = reinterpret_cast<MyDeviceAdaptor*>(param); MSG msg; while (GetMessage(&msg,NULL,0,0) > 0) { switch (msg.message) { case WM_USER: // Check if a frame needs to be acquired. while(adaptor->isAcquisitionNotComplete()) { // Insert Device-specific code here to acquire frames // into a buffer. if (adaptor->isSendFrame()) { // Get frame type & dimensions. imaqkit::frametypes::FRAMETYPE frameType = adaptor->getFrameType(); int imWidth = adaptor->getMaxWidth(); int imHeight = adaptor->getMaxHeight(); // Create a frame object. imaqkit::IAdaptorFrame* frame = adaptor->getEngine()->makeFrame(frameType, imWidth, imHeight); // Copy data from buffer into frame object. frame->setImage(imBuffer, imWidth, imHeight, 0, // X Offset from origin 0); // Y Offset from origin // Set image's timestamp. frame->setTime(imaqkit::getCurrentTime()); // Send frame object to engine. adaptor->getEngine()->receiveFrame(frame); } // if isSendFrame() // Increment the frame count. adaptor->incrementFrameCount(); } // while(isAcquisitionNotComplete() break; } //switch-case WM_USER } //while message is not WM_QUIT return 0; }