堡盟相机的SDK不夸张的说应该是最好懂最容易上手的相机SDK,哪些接口对用户开放,哪些是内部封装都很清楚,还提供了比较完备的示例。
1.堡盟相机SDK简介
提供了C,C#,C++编程接口;
提供比较详尽的SDK解读(见图)
有针对opencv的示例。
2.环境配置
1)头文件和静态库配置
打开一个示例代码,发现包含了如下文件
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <vector>
#include "bgapi2_genicam/bgapi2_genicam.hpp"
#if _WIN32
# include <direct.h>
#else
# include <sys/stat.h>
# include <stdlib.h>
#endif
#if USE_OPENCV
# include "opencv2/opencv.hpp"
# include "opencv2/highgui/highgui.hpp"
#if USE_OCL_COMPONENT == 3
# include "opencv2/core/ocl.hpp"
#elif USE_OCL_COMPONENT == 2
# include "opencv2/ocl/ocl.hpp"
#endif // USE_OCL_COMPONENT
#endif // USE_OPENCV
a.首先需要配置“bgapi2_genicam/bgapi2_genicam.hpp”的路径,右键项目->属性->VC++目录->包含目录,添加路径“C:\Program Files\Baumer GAPI SDK (64 Bit)\Components\Dev\C++\Inc”;然后点击库目录,添加库目录“C:\Program Files\Baumer GAPI SDK (64 Bit)\Components\Dev\C++\Lib”
点击链接器->输入->附加依赖项:添加bgapi2_genicam.lib。
b.按照网上通用方法配置opencv4.2.0。
2)动态库配置
将路径“C:\Program Files\Baumer GAPI SDK (64 Bit)\Components\Bin”下所有文件拷贝到工程debug目录。
3)需要添加#include "stdafx.h"的项目记着把这个填上。
4)解决方案配置选debug,平台选x64
3.关键代码
源代码多达1000多行,有兴趣的看https://blog.csdn.net/smalbig/article/details/104658550,这里列出关键代码。
pDataStream->StartAcquisitionContinuous();
while(true)
{
//WAIT FOR IMAGE
BGAPI2::Buffer* pBufferFilled = pDataStream->GetFilledBuffer(uGetFilledBufferTimeout); //timeout <n> msec
BGAPI2::ImageProcessor* pImageProcessor = new BGAPI2::ImageProcessor();
void* pBufferDst = NULL;
BGAPI2::Image* pImage = NULL;
void* pRawBuffer = pBufferFilled->GetMemPtr();
const int width = (int)(pBufferFilled->GetWidth());
const int height = (int)(pBufferFilled->GetHeight());
if (pBufferFilled == NULL)
{
std::cout << "Error: Buffer Timeout after " << uGetFilledBufferTimeout << "msec" << std::endl;
}
else
{
if (pBufferFilled->GetIsIncomplete() == true)
{
std::cout << "Error: Image is incomplete" << std::endl;
}
else
{
const bo_uint w = static_cast<bo_uint>(pBufferFilled->GetWidth());
const bo_uint h = static_cast<bo_uint>(pBufferFilled->GetHeight());
void* const pMemSrc = pBufferFilled->GetMemPtr();
BGAPI2::String sPixelFormatSrc = pBufferFilled->GetPixelFormat();
const bo_uint64 memSizeSrc = pBufferFilled->GetMemSize();
std::cout << " Image " << std::setw(5) << pBufferFilled->GetFrameID() << " received in memory address " << std::hex << pMemSrc << std::dec
<< " [" << sPixelFormatSrc << "]" << std::endl;
if (pImageSrc == NULL) {
pImageSrc = pImageProcessor->CreateImage(w, h, sPixelFormatSrc, pMemSrc, memSizeSrc);
}
else
{
pImageSrc->Init(w, h, sPixelFormatSrc, pMemSrc, memSizeSrc);
}
if (pImageSrc != NULL)
{
bo_uint64 bufferLength = pImageSrc->GetTransformBufferLength(sPixelFormatDst);
if (bufferLength > memSizeDst)
{
if (pMemDst != NULL) {
delete[] pMemDst;
pMemDst = NULL;
memSizeDst = 0;
}
pMemDst = new bo_uchar[static_cast<size_t>(bufferLength)];
memSizeDst = bufferLength;
}
std::cout << " convert to " << sPixelFormatDst << std::endl;
pImageProcessor->TransformImageToBuffer(pImageSrc, sPixelFormatDst, pMemDst, bufferLength);
cv::Mat img(height, width, CV_8UC3, pMemDst, cv::Mat::AUTO_STEP);
cv::namedWindow("这波怎么说bbbbb", cv::WINDOW_AUTOSIZE);
cv::imshow("这波怎么说bbbbb", img);
cv::cvtColor(img, img, cv::COLOR_BGR2GRAY);
cv::Mat dst;
cv::threshold(img, dst, 47, 255, cv::THRESH_BINARY);
cv::namedWindow("这波怎么说aaaaa", cv::WINDOW_AUTOSIZE);
cv::imshow("这波怎么说aaaaa", dst);
//pBuffer2->QueueBuffer();
cv::waitKey(20);
}
}
// queue buffer again
pBufferFilled->QueueBuffer();
}
}
前面看不明白没关系,可以去堡盟官网下SDK慢慢看,都是相机sdk自带的一些预处理代码。跟opencv有关的是这几句:
cv::Mat img(height, width, CV_8UC3, pMemDst, cv::Mat::AUTO_STEP);
cv::namedWindow("这波怎么说bbbbb", cv::WINDOW_AUTOSIZE);
cv::imshow("这波怎么说bbbbb", img);
cv::cvtColor(img, img, cv::COLOR_BGR2GRAY);
cv::Mat dst;
cv::threshold(img, dst, 47, 255, cv::THRESH_BINARY);
cv::namedWindow("这波怎么说aaaaa", cv::WINDOW_AUTOSIZE);
cv::imshow("这波怎么说aaaaa", dst);
可以看到pMemDst是void*,可以通过
Mat img(height, width, CV_8UC3, pMemDst,cv::Mat::AUTO_STEP);
构造出一个Mat对象,然后就可以对这个Mat对象为所欲为啦!!!
上面构造代码中height在前,width在后,这是我修改后的代码,经测试没问题;堡盟的源代码是width在前,height在后,测试后出现玄幻的图像重叠,可能是对opencv4.2.0不够支持的缘故。