2017暑假玉泉总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a356337092/article/details/77855908

一、相机

1.1 Imagingsource DFK 22BUC03 工业相机

Debug

按着教程在VS2010环境下配置库和外部链接并添加头文件后,出现以下报错

error WINDOWS.H already included.  MFC apps must not #include  <windows.h>

出现原因是#include “tisudshl.h” 应该在stdafx.h的最后面。这也是以后在Windows下开发时要注意的,之前都在Linux下开发,现在觉得Windows下C++开发其实也没想象中的复杂。


相机SDK应用

主函数中:
注册CListener(继承于GrabberListener) CListener *pListener = new CListener();

pListener->setBufferSize(10);       设置读取图片数量

……

grabber.addListener(pListener,GrabberListener::eFRAMEREADY|GrabberListener::eOVERLAYCALLBACK);

启用FRAMEREADY和OVERLAYCALLBACK两个回调函数

smart_ptr pSink = FrameHandlerSink::create( acceptedTypes, NUM_BUFFERS );

……
grabber.startLive();  //start the grabber
pSink->snapImages(NUM_BUFFERS);     //获取NUM_BUFFERS张图片
grabber.stopLive();

在frameready回调函数中(Listener.cpp) 【frameready()发生在:相机把一帧copy进buffer后,注册eFRAMEREADY或者eALL】
调用函数saveImage(),保存成功后m_BufferWritten数组里相应位置=true
为了顺利保存,要sleep(),也就意味着buffer里面有些数据没存跳过

主函数然后处理,把BUFFER里面还没有save的数据save(用m_BufferWritten数组判断)。

测试:去掉sleep后100帧会来不及处理3帧左右(大概)。所以主函数的处理是必要的。

2.
grab mode:到达接收器的所有帧都被呈现给帧滤波器或滤波器链,然后被复制到MemBufferCollection中。然后frameready()
snap mode:必须调用snapImages或snapImagesAsync才能触发图像采集过程。

grabber.startLive(false)--not display

3.
GUID结构体 long Data1, short Data2, short Data3, char Data4[8]
可以借鉴 Creating an Overlay 把exposure time overlay在Live上


回调函数

对SDK的运用核心是对回调函数的操作,即:

grabber.addListener( pListener, GrabberListener::eFRAMEREADY );

之中的pListener。GrabberListener::eFRAMEREADY代表每当一帧准备好,进入回调函数
pListener::frameReady( Grabber& caller, smart_ptr<MemBuffer> pBuffer, DWORD currFrame)
,当然还有overlayCallback等模式,我没用到,可以参考手册,测试过可用。
以下代码可以实现在每帧结束时调用回调函数,在函数中保存图片,记录当前曝光时间。

void    CListener::frameReady( Grabber& caller, smart_ptr<MemBuffer> pBuffer, DWORD currFrame)
{

               pBuffer->lock();                    

    std::cout << "Buffer " << currFrame << " processed in CListener::frameReady()." << std::endl;

    tIVCDPropertyItemsPtr pItems = caller.getAvailableVCDProperties();

    // Retrieve the absolute value interface for exposure.
    tIVCDAbsoluteValuePropertyPtr pAbsVal = 0; 
    double out=0;
    if( pItems->findInterfacePtr( VCDID_Exposure, VCDElement_Value, pAbsVal ) != 0 )
    {

         out = pAbsVal->getValue();
         if(count==0)
        {

                pAbsVal->setValue(SetET);   //设置曝光时间    
                std::cout<<std::setiosflags(std::ios::fixed)<<out<<std::endl;
                std::cout<<"Set: "<<SetET<<std::endl;
                std::cout<<"Min"<<pAbsVal->getRangeMin()<<std::endl;
                if(count>11)
                SetET+=k;   //k=1.05

                ::Sleep(5);
        }


    // Interface successfully retrieved.
    }
    count++;
                    if(count<20)
                    return ;
                char ID[1500];
                    sprintf(ID, "%05i ", count);
                outfile<<ID<<" ";
                outfile<<(double)GetTickCount()*1.0 / 1000.;
                outfile<<" "<<out*1000.<<std::endl;
    //saveImage( pBuffer, currFrame ); // Do the buffer processing.
        saveImage( pBuffer, count ); // Do the buffer processing.
    ::Sleep(3); // Simulate a time expensive processing.
            pBuffer->unlock();


}
void    CListener::saveImage( smart_ptr<MemBuffer> pBuffer, DWORD currFrame)
{
    char filename[MAX_PATH];
    //if( currFrame < m_BufferWritten.size() )
    //{
        sprintf( filename, "images/%05i.bmp", currFrame );

        saveToFileBMP( *pBuffer, filename );
        printf("save");
    //}
}

1.2 Optris PI 640 红外热成像相机

这个相机价格很贵(国内含税价7万左右),所以用的时候小心翼翼。。但是坑点很多很多。
在Windows下初次使用时,必须要插入他提供的光盘并安装里面的软件,并不能去官网下载同名的软件!这个软件会在每次打开相机时自动下载标定文件和相机独有的配置文件,没有这些就无法工作。
在光盘里(官网也有)可以找到两套SDK,其中connect-sdk必须在Windows下使用,并且需要打开官方软件,并且需要设置-外部通讯-PIC模式,这样才可以运行自己用SKD写的相关相机的软件。direct-sdk在Windows和Linux下都可以使用,而且在Windows下也不需要打开官方软件。
在Windows下使用比较简单,只要打开官方软件,按着例程操作就行了,一般可以直接使用。其中工具-配置-设备PIF里可以选择触发模式和工作方式。PIF是相机官方提供的触发接口,其实就是触发线,**触发装置必须要5-12V的DC供电**,否则无法触发。一般是VCC-5V,接地GND,脉冲接DI(数字Input),脉冲需要2V以上,一般单片机GPIO出来的5V就能用。
PIF里的触发可以选择模拟输入/数字输入,各自其模式可选。主要用数字触发的snapshot--快照模式,当信号来时保存快照和event--事件模式,相当于回调函数,处理更自由。
**但是经过很久很久的研究,并和售后技术支持确认,触发的极限频率仅为8Hz,原因是相机的设计机制是一直以32Hz采集图像,所以触发的事件也只能在间隙进行。非常之坑,这导致硬触发基本上没办法用了。**

在Linux下没有Windows下支持的好,需要安装库并按以下教程一步步进行:
[libirimager 库](http://www.evocortex.org/downloads-1/)
[libirimager guide](http://documentation.evocortex.com/libirimager2/html/index.html)
相机的机制是,每当有新的一帧图像,进入回调函数onThermalFrame:
void onThermalFrame(unsigned short* thermal, unsigned int w, unsigned int h, IRFrameMetadata meta, void* arg)
{
    ...
        float t = ((((float)data[i])-1000.f))/10.f;//能量-温度
    ...
}

触发的回调函数需要自己设置和注册。

猜你喜欢

转载自blog.csdn.net/a356337092/article/details/77855908