Я пытаюсь подключить тепловизионную камеру 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(¶ms, 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, ×tamp)==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, ×tamp)==IRIMAGER_SUCCESS)
{
imager.process(bufferRaw, NULL);
}
}
Но в функции обратного вызова я получаю только неправильные минимальные максимальные значения, а остальные данные равны 0.
Вопрос: Я знаю получить ответ на этот вопрос может быть немного сложно, потому что я имею дело с библиотекой, не имеющей открытых источников, и не могу просмотреть / проверить их код (также поддержка не отвечает), но кто-нибудь знает, что могло ли это происходить здесь?
Любые идеи / подсказки будут оценены. Заранее спасибо.