Интерфейс тепловизионной камеры - проблема с функцией обратного вызова evocortex - PullRequest
0 голосов
/ 06 апреля 2020

Я пытаюсь подключить тепловизионную камеру Optris, используя разделяемую библиотеку evocortex из встроенной системы linux (на основе yocto), а также пытаюсь использовать P C с ubuntu64.

Я могу подключиться к камере и записать необработанные данные, используя в этом примере , записанные данные в произвольном формате, чтобы их можно было открыть приложением Optris (соединение Optris PIX) со всеми Кажется, это работает как ожидалось.

Мне нужно получить необработанные тепловые данные и сохранить их в нашем пользовательском формате (с другим заголовком), а также иметь возможность выполнять некоторую обработку данных. Следуя документации, способ сделать это - использовать функцию обратного вызова ( onThermalFrame ), которая теоретически предоставит данные для пользователя в виде беззнакового короткого типа вместо char. (Все это объясняется в разделе «Формат данных о температуре» документации.)

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

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <pthread.h>
#include <sys/time.h>
#include <fstream>
#include <vector>
#include <list>
#include <signal.h>
// Optris device interfaces
#include "IRDevice.h"
// Optris imager interfaces
#include "IRImager.h"
// Optris logging interface
#include "IRLogger.h"
// Optris raw image file writer
#include "IRFileWriter.h"


// Helper class for checking calibration files
#include "IRCalibrationManager.h"

using namespace std;
using namespace evo;
bool _keepCapturing = true;
void sigHandler(int dummy=0)
{
    _keepCapturing = false;
}

void onThermalFrame(unsigned short* thermal, unsigned int w, unsigned int h, IRFrameMetadata meta, void* arg);

int main (int argc, char* argv[])
{

  signal(SIGINT, sigHandler);
  IRLogger::setVerbosity(IRLOG_DEBUG, IRLOG_DEBUG);
  const char *CONFIG_FILE = "/usr/share/libirimager/cali/generic.xml";
  IRDeviceParams params;
  IRDeviceParamsReader::readXML(CONFIG_FILE, params);
  IRDevice* dev = NULL;
  dev = IRDevice::IRCreateDevice(params);

  if(dev)
  {
    IRImager imager;
    imager.setThermalFrameCallback(onThermalFrame);
    if(imager.init(&params, dev->getFrequency(), dev->getWidth(), dev->getHeight(), dev->controlledViaHID()))
    {
      if(imager.getWidth()!=0 && imager.getHeight()!=0)
      {
        cout << "Thermal channel: " << imager.getWidth() << "x" << imager.getHeight() << "@" << imager.getMaxFramerate() << "Hz" << endl;
        // Start UVC streaming
        if(dev->startStreaming()==0)
        {
          // Enter loop in order to pass raw data to Optris image processing library.
          // Processed data are supported by the frame callback function.
          double timestamp;
          unsigned char* bufferRaw = new unsigned char[dev->getRawBufferSize()];
          char nmea[GPSBUFFERSIZE];
          memset(nmea, 0, GPSBUFFERSIZE*sizeof(*nmea));
         cout << "Decimal places: " << imager.getTemprangeDecimal() << endl;
          int serializedImages = 0;
          int chunk = 1;

          while(_keepCapturing)
          {
            if(dev->getFrame(bufferRaw, &timestamp)==IRIMAGER_SUCCESS)
            {
              imager.process(bufferRaw, NULL);
            }
          }
          delete [] bufferRaw;
        }
        else
        {
          cout << "Error occurred in starting stream ... aborting. You may need to reconnect the camera." << endl;
        }
      }
    }
    else
    {
      cout << "Error: Image streams not available or wrongly configured. Check connection of camera and config file." << endl;
    }
    delete dev;
  }
  return 0;
}

void onThermalFrame(unsigned short* thermal, unsigned int w, unsigned int h, IRFrameMetadata meta, void* arg)
{

    for (unsigned int i=0; i<h; i++)
    {
        for (unsigned int j=0; j<w; j++)
        {
            cout << thermal[i*w+j] << endl;

        }
    }
}

Функция обратного вызова работает, и я вижу, что она выполняется для каждого кадра.

Проблема в том, что считываемые данные являются только минимальными и максимальные значения и все остальные значения температуры равны 0.

Я изменил обратный вызов, чтобы печатать только мин. и макс. значения, и они неверны, потому что они идут от -41,1 ° C до 125,1 ° C, и камера указывает на нормальную комнатную температуру (~ 25 ° C). Это мод обратного вызова .:

void onThermalFrame(unsigned short* thermal, unsigned int w, unsigned int h, IRFrameMetadata meta, void* arg)
{
  unsigned short min = 64000;
  unsigned short max = 0;
    for (unsigned int i=0; i<h; i++)
    {
        for (unsigned int j=0; j<w; j++)
        {
            //cout << thermal[i*w+j] << endl;

      if(min > thermal[i*w+j])
        min = thermal[i*w+j];
      if(max < thermal[i*w+j])
        max = thermal[i*w+j];

        }
    }
  float tMin = (float)min / 10.f - 100.f;
  float tMax = (float)max / 10.f - 100.f;
  std::cout << "min: " << tMin << " max: " << tMax << std::endl;
}

Таким образом, в качестве резюме, в том же коде я вижу «правильные» необработанные данные перед обратным вызовом (массив bufferRaw) (я только что напечатал некоторые значения для проверки ):

      while(_keepCapturing)
      {
        if(dev->getFrame(bufferRaw, &timestamp)==IRIMAGER_SUCCESS)
        {
          imager.process(bufferRaw, NULL);
        }
      }

Но в функции обратного вызова я получаю только неправильные минимальные максимальные значения, а остальные данные равны 0.

Вопрос: Я знаю получить ответ на этот вопрос может быть немного сложно, потому что я имею дело с библиотекой, не имеющей открытых источников, и не могу просмотреть / проверить их код (также поддержка не отвечает), но кто-нибудь знает, что могло ли это происходить здесь?

Любые идеи / подсказки будут оценены. Заранее спасибо.

...