Реализация функции потока захвата

В этом разделе описывается реализовать функцию потока захвата вашего адаптера. В потоковом проекте адаптера функция потока захвата выполняет фактический захват систем координат от устройства. Когда вы создаете поток (Открытие и закрытие Связи с Устройством), вы задаете имя этой функции потока захвата как начальный адрес для нового потока.

Пользовательский сценарий

Механизм тулбокса вызывает функцию потока захвата косвенно, когда пользователь вызывает start, getsnapshot, или preview функция. После того, как названный, функция потока захвата получает системы координат, пока конкретное количество систем координат не было получено, или пользователь вызывает stop функция.

Предложенный алгоритм

Примечание

Проект функции потока захвата может значительно варьироваться между различными адаптерами, в зависимости от требований SDK устройства. Этот раздел не описывает зависящие от устройств детали реализации, а скорее подсвечивает требуемые задачи, которые характерны для всех реализаций.

На его высшем уровне, в потоковом проекте, функция потока захвата обычно содержит два цикла:

Распараллельте цикл сообщения

Цикл сообщения потока является основным циклом обработки в функции потока захвата. Вы создаете поток в openDevice() функция. Функция потока захвата вводит цикл сообщения потока, ожидающий сообщения, чтобы начать получать системы координат. startCapture() вашего адаптера функция отправляет сообщение в поток захвата, говоря ему начать получать системы координат. Этот пример использует WM_USER обменивайтесь сообщениями, чтобы указать на это состояние. Смотрите Отправку сообщения к Потоку Захвата для получения дополнительной информации.

Когда это получает соответствующее сообщение, функция потока захвата вводит цикл захвата системы координат. Следующая фигура иллюстрирует это взаимодействие между вашими функциями адаптера и потоком захвата. Для получения информации о цикле захвата системы координат смотрите Цикл Захвата Системы координат.

Взаимодействие функций адаптера и потока захвата

Flowchart that shows how the openDevice and startCapture functions interact with the thread message loop and frame acquisition loop. It also shows that the closeDevice function can be used to send a message to the thread message loop that terminates the frame acquisition loop.

Структурируйте цикл захвата

Цикл захвата системы координат - то, где ваш адаптер получает системы координат от устройства и отправляет их в механизм. Этот процесс включает следующие шаги:

  1. Проверяйте, было ли конкретное количество систем координат получено. Цикл захвата системы координат получает системы координат от устройства, пока конкретное количество систем координат не было получено. Используйте IAdaptor функция членства isAcquisitionNotComplete() определить, необходимо ли больше систем координат.

  2. Если бы ваш адаптер поддерживает аппаратные триггеры, вы проверяли бы, сконфигурирован ли аппаратный триггер здесь — Поддерживающий Аппаратные Триггеры.

  3. Захватите систему координат от устройства. Этот код абсолютно зависит от вашего API SDK устройства. Со многими устройство SDKs вы выделяете буфер, и устройство заполняет его данными изображения. См. документацию API своего устройства, чтобы изучить, как получить системы координат от вашего устройства.

  4. Проверяйте, необходимо ли передать полученный кадр к механизму, с помощью IAdaptor функция членства isSendFrame(). Это - то, как тулбокс реализует FrameGrabInterval свойство, где пользователи могут указать, что только хотят получить любую систему координат, например.

    Если необходимо передать кадр к механизму, группируйте систему координат в IAdaptorFrame объект; в противном случае пропустите к шагу 5.

    1. Создайте объект системы координат, с помощью IEngine объект makeFrame() функция членства. Необходимо задать размерности фрейма изображения и тип системы координат, когда вы создаете объект системы координат.

    2. Поместите передававшие изображения в объект системы координат, с помощью IAdaptorFrame объект setImage() функция членства. Вы задаете указатель на буфер, который содержит данные изображения, ширину системы координат и высоту и любые смещения от левого верхнего угла изображения.

      Примечание

      Для получения информации об определении ширины системы координат высота, и возмещенный с ROI, видит ROI Поддержки.

    3. Регистрируйте время захвата в объекте системы координат, с помощью IAdaptorFrame функция членства setTime(). SDKs устройства иногда обеспечивают доступ к информации о метке времени, но можно также использовать набор адаптера getCurrentTime() функция.

    4. Передайте упакованный кадр к механизму, с помощью IEngine функция членства receiveFrame().

  5. Постепенно увеличьте количество системы координат с помощью IAdaptor функция членства incrementFrameCount(). Необходимо ли передать кадр или нет, необходимо всегда постепенно увеличивать количество системы координат каждый раз, когда вы получаете систему координат.

  6. Возвратитесь к верхней части цикла захвата системы координат.

Следующая фигура иллюстрирует цикл захвата системы координат.

Возможный алгоритм для цикла захвата системы координат

Пример

Следующее является объявлением функции потока захвата. Можно дать процедуре потока захвата любое имя, такое как acquireThread().

DWORD WINAPI acquireThread(void* ThreadParam);

Ваша функция потока должна принять один параметр, который задан как указатель на сам объект, т.е. this указатель. Функция потока возвращает значение, которое указывает на успешность или неуспешность. Для получения дополнительной информации смотрите Microsoft Docs.

Следующее является функцией потока захвата, что можно использовать с примером 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;
}