一、安装相机驱动
安装相应相机对应相机厂家软件
标题二、查看相机连接是否正常
使用相机厂家软件连接相机,更改相应配置,可查看软件使用说明书,gige需要更改网口IP配置
标题三、找到相机sdk库,sdk调用示例代码
四、代码示例–网口线阵相机
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "afxmt.h"
#include "afxwin.h"
#include <vector>
using namespace std;
#include "IKapC.h"
#pragma comment (lib, "../Include/IKapC.lib")
class IKap_Gige{
public:
char Camera_Name[260];
public:
ITKDEVICE m_CameraHandle;
ITKSTREAM m_ITKSTREAM;
ITKBUFFER m_buffer;
}
void IKAPC_CC cbStartOfFrame(uint32_t eventType, void* pContext)
{
printf("%s,帧开始\r\n", __FUNCTION__);
}
void IKAPC_CC cbEndOfFrame(uint32_t eventType, void* pContext)
{
printf("%s, 帧结束\r\n", __FUNCTION__);
}
void IKAPC_CC cbEndOfStream(uint32_t eventType, void* pContext)
{
// qDebug() << "帧结束";
}
// 回调函数
void IKAPC_CC cbOnEndOfFrame(uint32_t eventType, void* pContext)
{
IKap_Gige *iHandle=(IKap_Gige )*pContext;
printf("%s,当前采集结束%s \r\n", __FUNCTION__,iHandle->Camera_Name);
// 处理图像
iHandle->ProcessImageData(iHandle);
}
void IKAPC_CC cbOnTimeOut(uint32_t eventType, void* pContext)
{
printf("%s,超时\r\n", __FUNCTION__);
}
void IKAPC_CC cbOnFrameLost(uint32_t eventType, void* pContext)
{
IKap_Gige iHandle = *(IKap_Gige *)pContext;
printf("%s, 当前相机%s,出现帧丢失\r\n", __FUNCTION__, iHandle->Camera_Name);
}
void CreateStreamAndBuffer(ITKDEVICE& _pDevice, ITKSTREAM& _pStream, ITKBUFFER* _itkbuffer)
{
// 流数量
uint32_t streamCount = 0;
// 图像宽
int64_t nWidth = 0;
// 图像高
int64_t nHeight = 0;
// 图像数据类型 - 默认灰度
uint32_t nFormat = ITKBUFFER_VAL_FORMAT_MONO8;
// 图像大小
int64_t nImageSize = 0;
// 图像像素格式
char pixelFormat[16];
// 图像像素格式大小
uint32_t pixelFormatLen = 16;
// 获取当前相机数据流数量
ITKSTATUS res = ITKSTATUS_OK;
res = ItkDevGetStreamCount(_pDevice, &streamCount);
if (ITKSTATUS_OK != res) DEBUGTRACE("%s,获取流数量异常,异常信息为:%d\r\n", __FUNCTION__, res);
if (streamCount == 0) {
// 相机信息
ITKDEV_INFO di;
// 获取相机信息
res = ItkManGetDeviceInfo(0, &di);
if (ITKSTATUS_OK != res) DEBUGTRACE("%s, 相机信息获取异常,异常代码为:%d\r\n", __FUNCTION__, res);
}
// 获取图像宽
res = ItkDevGetInt64(_pDevice, "Width", &nWidth);
if (ITKSTATUS_OK != res) DEBUGTRACE("%s, 获取图像宽异常,异常代码为:%d\r\n", __FUNCTION__, res);
// 获取图像高
res = ItkDevGetInt64(_pDevice, "Height", &nHeight);
if (ITKSTATUS_OK != res) DEBUGTRACE("%s, 获取图像高异常,异常代码为:%d\r\n", __FUNCTION__, res);
// 获取图像数据类型
res = ItkDevToString(_pDevice, "PixelFormat", pixelFormat, &pixelFormatLen);
if (ITKSTATUS_OK != res) DEBUGTRACE("%s, 获取图像数据类型异常,异常代码为:%d\r\n", __FUNCTION__, res);
if (strcmp(pixelFormat, "Mono8") == 0)
nFormat = ITKBUFFER_VAL_FORMAT_MONO8;
else if (strcmp(pixelFormat, "Mono10") == 0)
nFormat = ITKBUFFER_VAL_FORMAT_MONO10;
else if (strcmp(pixelFormat, "Mono10Packed") == 0)
nFormat = ITKBUFFER_VAL_FORMAT_MONO10PACKED;
else if (strcmp(pixelFormat, "BayerGR8") == 0)
nFormat = ITKBUFFER_VAL_FORMAT_BAYER_GR8;
else if (strcmp(pixelFormat, "BayerRG8") == 0)
nFormat = ITKBUFFER_VAL_FORMAT_BAYER_RG8;
else if (strcmp(pixelFormat, "BayerGB8") == 0)
nFormat = ITKBUFFER_VAL_FORMAT_BAYER_GB8;
else if (strcmp(pixelFormat, "BayerBG8") == 0)
nFormat = ITKBUFFER_VAL_FORMAT_BAYER_BG8;
else {
printf("%s, 相机不支持的像素类型,错误类型为:%d\r\n", __FUNCTION__, pixelFormat);
}
// 该缓冲区作为图像数据的默认传输地址
ITKBUFFER hBuffer;
res = ItkBufferNew(nWidth, nHeight, nFormat, &hBuffer);
if (ITKSTATUS_OK != res) printf("%s,缓冲区初始化异常,异常代码为:%d\r\n", __FUNCTION__, res);
*_itkbuffer = hBuffer;
// 获取缓冲区数据大小
res = ItkBufferGetPrm(hBuffer, ITKBUFFER_PRM_SIZE, &nImageSize);
if (ITKSTATUS_OK != res) printf("%s,获取图像缓冲区大小异常,异常代码为:%d\r\n", __FUNCTION__, res);
// 申请内存
/*char* bufferData = (char*)malloc(nImageSize);
if (bufferData != nullptr) {
g_imgBufferList.push_back(bufferData);
}*/
// 申请图像数据流资源
res = ItkDevAllocStream(_pDevice, 0, hBuffer, &_pStream);
if (ITKSTATUS_OK != res) printf("%s,申请图像数据流资源异常,异常代码为:%d\r\n", __FUNCTION__, res);
// 补充其他缓冲区数据
/*for (int i = 1; i < streamCount; i++) {
res = ItkBufferNew(nWidth, nHeight, nFormat, &hBuffer);
CHECK(res, "缓冲区初始化异常,异常代码为:%1");
res = ItkStreamAddBuffer(_pStream, hBuffer);
CHECK(res, "流绑定缓冲区异常,异常代码为:%1");
g_bufferList.push_back(hBuffer);
}*/
}
void ConfigureStream(ITKSTREAM _phStream, void* _iCameraHandle)
{
ITKSTATUS res = ITKSTATUS_OK;
// 异步传输图像模式 -- 同步保护模式,如果下一块缓冲区为空则传输到下一块缓冲区中,否则丢弃图像数据
uint32_t xferMode = ITKSTREAM_VAL_TRANSFER_MODE_SYNCHRONOUS_WITH_PROTECT;
// 非阻塞式启动图像采集
uint32_t startMode = ITKSTREAM_VAL_START_MODE_NON_BLOCK;
// 图像传输超时时间
uint32_t timeOut = INFINITE;
// 相机索引
IKap_Gige * pi = (IKap_Gige *)_iCameraHandle;
int* time = new int;
*time = 999999999;
/* Set block mode which means the grab will not be stopped before an entire image
come into buffer. */
res = ItkStreamSetPrm(_phStream, ITKSTREAM_PRM_START_MODE, &startMode);
if (ITKSTATUS_OK != res) printf("%s, 启动图像采集设定异常,异常代码为:%d\r\n", __FUNCTION__, res);
// 异步传输图像模式
res = ItkStreamSetPrm(_phStream, ITKSTREAM_PRM_TRANSFER_MODE, &xferMode);
if (ITKSTATUS_OK != res) printf("%s,异步传输图像模式设定异常,异常代码为:%d\r\n", __FUNCTION__, res);
// 设置超时时间
res = ItkStreamSetPrm(_phStream, ITKSTREAM_PRM_TIME_OUT, &timeOut);
if (ITKSTATUS_OK != res) printf("%s, 流超时时间设定异常,异常代码为:%d\r\n", __FUNCTION__, res);
// 设置流时间
res = ItkStreamSetPrm(_phStream, ITKSTREAM_PRM_GV_PACKET_INTER_TIMEOUT, (void*)time);
if (ITKSTATUS_OK != res) printf("%s,ITKSTREAM_PRM_GV_PACKET_INTER_TIMEOUT设定异常,异常代码为:%d\r\n", __FUNCTION__, res);
/* Register callback which will be called at the begin of stream. */
// 注册开始采集事件
res = ItkStreamRegisterCallback(_phStream, ITKSTREAM_VAL_EVENT_TYPE_START_OF_FRAME, cbStartOfFrame, (void*)pi);
if (ITKSTATUS_OK != res) printf("%s,帧开始事件注册异常,异常代码为:%d\r\n", __FUNCTION__, res);
res = ItkStreamRegisterCallback(_phStream, ITKSTREAM_VAL_EVENT_TYPE_END_OF_FRAME, cbEndOfFrame, (void*)pi);
if (ITKSTATUS_OK != res) printf("%s,帧结束事件注册异常,异常代码为:%d\r\n", __FUNCTION__, res);
/* Register callback which will be called at the end of stream. */
// 注册结束采集事件
// res = ItkStreamRegisterCallback(_phStream, ITKSTREAM_VAL_EVENT_TYPE_END_OF_STREAM, cbEndOfStream, (void*)pi);
// CHECK(res);
/* Register callback which will be called at the end of one image completely. */
// 注册一帧结束事件----回调注册函数
res = ItkStreamRegisterCallback(_phStream, ITKSTREAM_VAL_EVENT_TYPE_END_OF_FRAME, cbOnEndOfFrame, (void*)pi);
if (ITKSTATUS_OK != res) printf("%s,图像采集回调注册异常,异常代码为:%d\r\n", __FUNCTION__, res);
// 注册超时事件
res = ItkStreamRegisterCallback(_phStream, ITKSTREAM_VAL_EVENT_TYPE_TIME_OUT, cbOnTimeOut, (void*)pi);
if (ITKSTATUS_OK != res) printf("%s,超时时间回调注册异常,异常代码为:%d\r\n", __FUNCTION__, res);
// 注册图像丢失事件
res = ItkStreamRegisterCallback(_phStream, ITKSTREAM_VAL_EVENT_TYPE_FRAME_LOST, cbOnFrameLost, (void*)pi);
if (ITKSTATUS_OK != res) printf("%s,图像丢失回调注册异常,异常代码为:%d\r\n", __FUNCTION__, res);
}
void UnRegisterCallback(ITKSTREAM _phStream)
{
// ITKSTATUS res = ITKSTATUS_OK;
ItkStreamUnregisterCallback(_phStream, ITKSTREAM_VAL_EVENT_TYPE_START_OF_STREAM);
ItkStreamUnregisterCallback(_phStream, ITKSTREAM_VAL_EVENT_TYPE_END_OF_STREAM);
ItkStreamUnregisterCallback(_phStream, ITKSTREAM_VAL_EVENT_TYPE_END_OF_FRAME);
ItkStreamUnregisterCallback(_phStream, ITKSTREAM_VAL_EVENT_TYPE_TIME_OUT);
ItkStreamUnregisterCallback(_phStream, ITKSTREAM_VAL_EVENT_TYPE_FRAME_LOST);
}
void SetFrameTrigger(ITKDEVICE _phanle)
{
ITKSTATUS res = ITKSTATUS_OK;
// Turn off line trigger
res = ItkDevFromString(_phanle, "TriggerSelector", "LineStart");
res = ItkDevFromString(_phanle, "TriggerMode", "Off");
// Trigger selector
res = ItkDevFromString(_phanle, "TriggerSelector", "FrameStart");
// Set trigger mode
res = ItkDevFromString(_phanle, "TriggerMode", "Off");
// Select trigger source(Line3、Software)
res = ItkDevFromString(_phanle, "TriggerSource", "Line3");
// Set Trigger Frames Count(once)
res = ItkDevSetInt64(_phanle, "TriggerFrameCount", 1);
}
bool IKap_Gige ::Init_Camera()
{
bool bRet;
int i;
int nIndex;
int nSnap_Number;
unsigned int unVer;
HANDLE hThread;
unsigned m_nThreadID;
const char* szMsg;
bRet = false;
szServer_Name[0x00] = 0x00;
bRet = Device_User_Camera_Initial(Camera_Name);
return bRet;
}
bool IKap_Gige ::Device_User_Camera_Initial(char* szServer_Name)
{
bool bRet;
bRet = false;
ItkManInitialize();
// 枚举所有相机时,必须先调用该函数ItkManGetDeviceCount()
ITKSTATUS res = ItkManGetDeviceCount(&m_numCameras);
// 调用失败0
if (ITKSTATUS_OK != res) {
return false;
}
// 数量为0,找不到相机
if (m_numCameras == 0) {
DEBUGTRACE("%s, %s 没有找到相机,\r\n", __FUNCTION__, szServer_Name);
ItkManTerminate();
return false;
}
for (int i = 0; i < m_numCameras; i++) {
// 打开一个相机
ITKDEVICE device = nullptr;
// 数据流
ITKSTREAM stream = nullptr;
// 相机信息
ITKDEV_INFO di;
// 获取相机信息 YT2259987317031
ITKSTATUS res = ITKSTATUS_OK;
res = ItkManGetDeviceInfo(i, &di);
if (res != ITKSTATUS_OK) {
printf("%s,SerialNumber为:%d -- 获取相机信息失败,错误代码为:%d,\r\n", __FUNCTION__, di.SerialNumber,res);
return false;
}
// 根据SerialNumber来配置启动相机
//if (strcmp(di.DeviceClass, "GigEVision") == 0 && strcmp(di.SerialNumber, "") != 0 && strcmp(di.UserDefinedName, strDeviceID.toLocal8Bit().data()) == 0)
if (strstr(szServer_Name, (char*)di.SerialNumber)
{
// 打开相机
res = ItkDevOpen(i, ITKDEV_VAL_ACCESS_MODE_EXCLUSIVE, &device);
if (res != ITKSTATUS_OK) {
printf("%s,SerialNumber为:%d -- 打开失败,错误代码为:%d,\r\n", __FUNCTION__, di.SerialNumber, res);
return false;
}
// 打开成功
printf("%s,SerialNumber = %s -- 打开成功\r\n", __FUNCTION__, di.SerialNumber);
// 创建缓存
CreateStreamAndBuffer(device, stream, &m_buffer);
// 注册回调函数
int indxe=0;
ConfigureStream(stream, this);
// 存储相机以及流数据
m_CameraHandle = device;
m_ITKSTREAM = stream;
///采集测试
/* Stop grab image. */
//ItkStreamStop(m_ITKSTREAM);
//UnRegisterCallback(m_ITKSTREAM);
//
SetFrameTrigger(m_CameraHandle);
//ItkStreamStart(m_ITKSTREAM, ITKSTREAM_CONTINUOUS);
//res = ItkStreamStart(m_ITKSTREAM, 1);
//Sleep(5000);
// 获取Gige信息
/*ITKGIGEDEV_INFO gvInfo;
res = ItkManGetGigEDeviceInfo(0, &gvInfo);
if (res != ITKSTATUS_OK) {
qDebug() << QString("SerialNumber = %1 -- 打开失败,ErrorCode == %2").arg(di.SerialNumber).arg(res);
flag &= false;
}*/
return true;
}
}
// 打开失败
return false;
}
int IKap_Gige::CloseDevice()
{
// 停止采集
Grab_Stop();
Sleep(100);
ItkDevClose(m_CameraHandle);
// 结束
ItkManTerminate();
return true;
}
// The user clicked on continuous grab.
void IKap_Gige ::OnStartGrabbing()
{
//开始采集
// 开启采图 -- 连续模式
int iRet = ItkStreamStart(m_ITKSTREAM, ITKSTREAM_CONTINUOUS);
if (ITKSTATUS_OK != iRet) {
printf("%s, start grab camera error:%d\r\n", __FUNCTION__, iRet);
return;
}
DEBUGTRACE("%s, start grab camera\r\n", __FUNCTION__);
}
// The user clicked on stop grab.
void IKap_Gige ::OnStopGrab()
{
//结束采集
// 开启采图 -- 连续模式
int iRet = ItkStreamStop(m_ITKSTREAM);
if (ITKSTATUS_OK != iRet) {
printf("%s, stop grab camera error:%d\r\n", __FUNCTION__, iRet);
return;
}
printf("%s, stop grab camera\r\n", __FUNCTION__);
//grabberUnique->stop();
}
///回调图像采集函数
void IKap_Gige ::ProcessImageData(void* _iHandle)
{
Image_Full_Msg strImage_Full_Msg;
Image_Extend_Msg strImage_Extend_Msg;
DWORD dwStart = GetTickCount64(); // 回调开始时刻
printf("%s, 当前相机%d采集完一帧\r\n", __FUNCTION__, 0);
ITKSTATUS res = ITKSTATUS_OK;
// 缓存状态
unsigned bufferStatus = 0;
// 数据buffer
IKap_Gige * pDevice = (IKap_Gige *)_iHandle;
ITKBUFFER hBuffer = pDevice->m_buffer;
// 获取采集结果
res = ItkBufferGetPrm(hBuffer, ITKBUFFER_PRM_STATE, &bufferStatus);
if (ITKSTATUS_OK != res) printf("%s, 获取采集结果异常,异常代码为:%d\r\n", __FUNCTION__, res);
if (res != ITKSTATUS_OK) {
return;
}
// 判断是否已经采图结束
if (bufferStatus == ITKBUFFER_VAL_STATE_FULL || bufferStatus == ITKBUFFER_VAL_STATE_UNCOMPLETED) {
// 图像大小
int64_t nWidth = 0, nHeight = 0, nReadyLines = 0, nImageSize = 0;
// 图像个数
// 句柄
ITKDEVICE device = m_CameraHandle;
//ITKBUFFER hBuffer;// = g_bufferList[_iHandleIndex];
// 获取图像的信息
res = ItkDevGetInt64(device, "Width", &nWidth);
if (ITKSTATUS_OK != res) printf("%s, 拆分图像时,获取图像宽度异常,异常代码为:%d\r\n", __FUNCTION__, res);
if (res != ITKSTATUS_OK) return;
res = ItkDevGetInt64(device, "Height", &nHeight);
if (ITKSTATUS_OK != res) printf("%s, 拆分图像时,获取图像高度异常,异常代码为:%d\r\n", __FUNCTION__, res);
if (res != ITKSTATUS_OK) return;
// 单帧变长时的有效行数
res = ItkBufferGetPrm(hBuffer, ITKBUFFER_PRM_READY_LINES, &nReadyLines);
if (ITKSTATUS_OK != res) printf("%s, 获取有效行数异常,异常代码为:%d\r\n", __FUNCTION__, res);
if (nReadyLines == 0) return;
// 存储有效高度
g_imgValidHeightList[_iHandleIndex] += nReadyLines;
// 读取buffer数据
res = ItkBufferGetPrm(hBuffer, ITKBUFFER_PRM_SIZE, &nImageSize);
if (ITKSTATUS_OK != res) printf("%s, 获取图像缓存异常,异常代码为:%d\r\n", __FUNCTION__, res);
if (res != ITKSTATUS_OK) return;
int64_t nSize = nWidth * nHeight;
uint8_t* srcData = new uint8_t[nSize];
// 将数据读取到申请的内存中---读取图像数据
res = ItkBufferRead(hBuffer, 0, srcData, (uint32_t)nImageSize);
if (ITKSTATUS_OK != res) printf("%s, 读取数据异常,异常代码为:%d\r\n", __FUNCTION__, res);
if (res != ITKSTATUS_OK) return;
// 图像搬运
uint8_t* dstData = new uint8_t[nSize];
memcpy(dstData, srcData, nSize);
// 存储数据
usigned char* byData = (uint8_t*)dstData;//图像数据
int Width = nWidth;//宽
int Height = nHeight;//高
free(strImage_Full_Msg.byData);
}
}