Реализация функции потока сбора данных

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

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

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

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

Примечание

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

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

Цикл сообщения о потоке

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

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

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

Цикл сбора систем координат

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

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

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

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

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

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

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

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

      Примечание

      Для получения информации об указании ширины, высоты и смещения системы координат с помощью ROIs, смотрите Вспомогательные ROIs.

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

    4. Отправьте упакованную систему координат в двигатель, используя IEngine функции представителя receiveFrame().

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

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

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

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

Пример

Ниже приведено объявление функции потока сбора. Вы можете присвоить процедуре приема потока любое имя, например acquireThread().

DWORD WINAPI acquireThread(void* ThreadParam);

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

Ниже приведена функция набора потоков, которую можно использовать в примере MyDeviceAdaptor. Замените скелетную реализацию, которую вы использовали в Starting an Acquisition Thread, этим кодом.

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;
}