作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
操作系统:Windows 10 1903 18362.778
相机型号:IMAGING SOURCE DMK 33G274
相机软件:ic_setup_3.4.0.2744,gigecam_setup_3.7.1.4512
软件版本:Qt 5.12.8, vs2017 Community
通信方式:GigE - 千兆以太网通信协议
开发包和驱动下载地址
提取码:34mt
安装驱动和开发包完成之后,可以找到以下2个目录:
映美精相机实时显示图像比较简单,因为SDK中提供了封装好的函数可以直接调用,如下所示:
bool startLive( bool show_videowindow = true );
show_videowindow 设置为true就是启用实时视频窗口,设置为false仅用于图片抓取。
我们只需要提供一个窗口的句柄就可以实时显示图像了。
这里先介绍一个叫 FrameHandlerSink 的东西,这是设计采集图像的模式,一共有两种模式:
我们主要来看一下如何使用映美精相机来处理每一帧的数据,映美精相机处理每一帧数据有以下两种方法:
方法一步骤如下:
添加新的侦听器对象
m_Grabber.addListener( this, GrabberListener::eALL );
设置采集模式
m_Sink->setSnapMode( true ); // true为snap采图模式,false为grab采集模式
重写 frameReady 函数
virtual void frameReady(Grabber &caller, smart_ptr
调用 startLive 开启实时模式
m_Grabber.startLive(true);
调用 snapImages 抓取图片
m_Sink->snapImages( 1, 2000 ); // 抓取一张图片,每次调用 snapImages() 之后,就会触发 Listener 中的 frameReady()
实现功能:相机图像的实时显示,并且可以在需要的时候获取当前帧数据,用于分析或者保存;
首先需要在pro中配置头文件和库文件
CONFIG += debug_and_release
INCLUDEPATH += $$PWD/classlib/include/
windows {
CONFIG(debug, debug|release) {
CONFIG += console
contains(DEFINES, WIN64) {
LIBS += -L$$PWD/classlib/x64/debug/ -lTIS_UDSHL11d_x64
} else {
LIBS += -L$$PWD/classlib/win32/debug/ -lTIS_UDSHL11d_x64
}
} else {
contains(DEFINES, WIN64) {
LIBS += -L$$PWD/classlib/x64/release/ -lTIS_UDSHL11d_x64
} else {
LIBS += -L$$PWD/classlib/win32/release/ -lTIS_UDSHL11d_x64
}
}
}
自定义相机基类 Camera
#ifndef CAMERA_H
#define CAMERA_H
#include
#include
#include
#include
#include
class Camera : public QObject
{
Q_OBJECT
public:
enum CameraType {
Basler = 1, // 巴斯勒相机
IC_Imaging, // 映美精相机
MV, // 海康威视相机
Virtual // 虚拟相机
};
explicit Camera(CameraType type = Basler) : m_type(type) {}
virtual void initCamera() = 0; // 初始化相机
virtual void destroyCamera() = 0; // 销毁相机
virtual void openCamera() = 0; // 打开相机
virtual void closeCamera() = 0; // 关闭相机
virtual void startWork() = 0; // 开始工作
virtual void stopWork() = 0; // 停止工作
virtual cv::Mat takeAPic() = 0; // 获取当前图像
void start() { m_timer.start(); }
void stop() { m_timer.stop(); }
void setInterval(int time) { m_timer.setInterval(time); }
CameraType getCameraType() { return m_type; }
signals:
void updateImage(QImage image);
protected:
CameraType m_type;
QMutex m_mutex;
QTimer m_timer;
};
#endif // CAMERA_H
自定义 BICCameraControl 相机控制类
#ifndef BICCAMERACONTROL_H
#define BICCAMERACONTROL_H
#include "../camera.h"
#include
#include "Grabber.h"
using namespace _DSHOWLIB_NAMESPACE;
#define NUM_BUFFERS 10
class BICCameraControl : public Camera
{
Q_OBJECT
public:
explicit BICCameraControl(Camera::CameraType type = Camera::CameraType::IC_Imaging);
virtual void initCamera() override;
virtual void destroyCamera() override;
virtual void openCamera() override;
virtual void closeCamera() override;
virtual void startWork() override;
virtual void stopWork() override;
virtual cv::Mat takeAPic() override;
void showDialog();
double getExposure();
public slots:
void updateFrame();
protected:
DShowLib::Grabber m_Grabber;
DShowLib::FrameHandlerSink::tFHSPtr m_Sink;
};
#endif // BICCAMERACONTROL_H
#include "biccameracontrol.h"
#include "globalfun.h"
BICCameraControl::BICCameraControl(Camera::CameraType type) : Camera(type)
{
try {
DShowLib::InitLibrary();
atexit(DShowLib::ExitLibrary);
} catch (DShowLib::Error &e) {
qDebug() << "InitLibrary erroer: " + QString::fromStdString(e.toString());
}
m_timer.setInterval(GlobalValue::cam_itl);
connect(&m_timer, &QTimer::timeout, this, &BICCameraControl::updateFrame);
}
void BICCameraControl::initCamera()
{
try {
m_Sink = DShowLib::FrameHandlerSink::create( FrameTypeInfoArray::createRGBArray(), NUM_BUFFERS );
m_Sink->setSnapMode( true );
// Apply the sink to the grabber.
m_Grabber.setSinkType( m_Sink );
} catch (DShowLib::Error &e) {
qDebug() << "initCamera erroer: " + QString::fromStdString(e.toString());
}
}
void BICCameraControl::destroyCamera()
{
try {
stopWork();
closeCamera();
} catch (DShowLib::Error &e) {
qDebug() << "destroyCamera erroer: " + QString::fromStdString(e.toString());
}
}
void BICCameraControl::openCamera()
{
// Check if a device is open.
if ( m_Grabber.isDevOpen() ) {
return;
}
if (m_Grabber.getAvailableVideoCaptureDevices()->size() == 0) {
return;
}
try {
Grabber::tVidCapDevListPtr pVidCapDevList = m_Grabber.getAvailableVideoCaptureDevices();
if( pVidCapDevList == 0 || pVidCapDevList->empty() )
{
qDebug() << "No device available !";
return;
}
__int64 num;
pVidCapDevList->at(0).getSerialNumber(num);
// Open camera from serialNumber.
m_Grabber.openDev(num);
m_Grabber.setVideoFormat(dstringa(GlobalValue::cam_fmt.toLatin1().data()));
m_Grabber.setFPS(GlobalValue::cam_fps);
} catch (DShowLib::Error &e) {
qDebug() << "openCamera erroer: " + QString::fromStdString(e.toString());
}
}
void BICCameraControl::closeCamera()
{
// Check if a device is open.
if ( !m_Grabber.isDevOpen() ) {
return;
}
try {
// Closes the currently active video capture device.
m_Grabber.closeDev();
} catch (DShowLib::Error &e) {
qDebug() << "closeCamera erroer: " + QString::fromStdString(e.toString());
}
}
void BICCameraControl::startWork()
{
// Check if live mode is on.
if ( m_Grabber.isLive() ) {
return;
}
// Check if there is a valid device.
if ( !m_Grabber.isDevValid() ) {
return;
}
try {
// Start the live video. Set true to enable the live video window, false to grab only.
m_Grabber.startLive(false);
m_timer.start();
} catch (DShowLib::Error &e) {
qDebug() << "startWork erroer: " + QString::fromStdString(e.toString());
}
}
void BICCameraControl::stopWork()
{
// Check if live mode is on.
if ( !m_Grabber.isLive() ) {
return;
}
try {
// Stop live mode.
m_Grabber.stopLive();
m_timer.stop();
} catch (DShowLib::Error &e) {
qDebug() << "stopWork erroer: " + QString::fromStdString(e.toString());
}
}
cv::Mat BICCameraControl::takeAPic()
{
// Check if live mode is on.
if ( !m_Grabber.isLive() ) {
return cv::Mat();
}
QMutexLocker locker(&m_mutex);
try {
m_Sink->snapImages( 1, 1000 );
smart_ptr pBuffer = m_Sink->getLastAcqMemBuffer();
QImage image(static_cast< uchar* >( pBuffer->getPtr() ),
int( pBuffer->getSize().cx ),
int( pBuffer->getSize().cy ),
QImage::Format_RGB32);
QImage retImage = image.mirrored(false, true);
cv::Mat mat = GlobalFun::convertQImageToMat(retImage);
return mat.clone();
} catch (DShowLib::Error &e) {
qDebug() << "takeAPic erroer: " + QString::fromStdString(e.toString());
return cv::Mat();
}
}
void BICCameraControl::showDialog()
{
if ( m_Grabber.isDevOpen() && m_Grabber.isLive() ) {
m_Grabber.stopLive();
m_timer.stop();
std::thread th([=](){ m_Grabber.showDevicePage(); });
th.join();
GlobalValue::cam_fps = m_Grabber.getFPS();
GlobalValue::cam_fmt = QString::fromStdString(m_Grabber.getVideoFormat().toString());
qDebug() << "FPS: " + QString::number(GlobalValue::cam_fps);
qDebug() << "Format: " + GlobalValue::cam_fmt;
m_Grabber.startLive(false);
m_timer.start();
m_Grabber.showVCDPropertyPage();
GlobalValue::cam_exp = getExposure() * 1000;
qDebug() << "Exposure: " + QString::number(GlobalValue::cam_exp);
}
}
double BICCameraControl::getExposure() {
tIVCDPropertyItemsPtr pItems = m_Grabber.getAvailableVCDProperties();
if( pItems != 0 )
{
tIVCDPropertyItemPtr pExposureItem = pItems->findItem( VCDID_Exposure );
tIVCDPropertyElementPtr pExposureValueElement = pExposureItem->findElement( VCDElement_Value );
tIVCDAbsoluteValuePropertyPtr m_pExposureAbsoluteValue;
if( pExposureValueElement != 0 )
{
pExposureValueElement->getInterfacePtr( m_pExposureAbsoluteValue );
}
if( m_pExposureAbsoluteValue != 0 )
{
return m_pExposureAbsoluteValue->getValue();
}
}
return 0.033;
}
void BICCameraControl::updateFrame()
{
QMutexLocker locker(&m_mutex);
try {
m_Sink->snapImages( 1, 1000 );
smart_ptr pBuffer = m_Sink->getLastAcqMemBuffer();
QImage image(static_cast< uchar* >( pBuffer->getPtr() ),
int( pBuffer->getSize().cx ),
int( pBuffer->getSize().cy ),
QImage::Format_RGB32);
emit updateImage(image.mirrored(false, true));
} catch (DShowLib::Error &e) {
qDebug() << "updateFrame erroer: " + QString::fromStdString(e.toString());
}
}