灰点工业网口相机多相机同时使用

最近对灰点的工业网口相机进行了调试,最终目标是要实现多相机的同时采集。

使用工业网口相机

第一步要安装相机的SDK:
包含spinnaker软件包和pyhton扩展。
这个软件包不好下载,可以去下载上传的版本,下载地址稍后上传。

第二步是配置网卡地址:
按照readme中的提示配置就可以,如果使用多个网口,需要配置到不同的网段。在Windows系统下成功实现了配置2个网段的网口分别采集2路相机,总共采集4个相机。但是在Ubuntu18.04系统下,不管怎么配置,都只有一个网段能使用相机,最后只好采用1个网口通过交换机连接4个相机的方式,这样在全分辨率情况下不能做到满帧率。目前还不知道怎么解决。

第三步是按照提供的例程,修改得到多相机同时采集的程序:

#include "Spinnaker.h"
#include "SpinGenApi/SpinnakerGenApi.h"
#include 
#include  
#include 
#include 
#include 
using namespace cv;

using namespace Spinnaker;
using namespace Spinnaker::GenApi;
using namespace Spinnaker::GenICam;
using namespace std;

CameraList camList;
SystemPtr camsystem;

enum triggerType
{
	SOFTWARE,
	HARDWARE
};

const triggerType chosenTrigger = SOFTWARE;

int ConfigureTrigger(INodeMap & nodeMap)
{
	int result = 0;
	if (chosenTrigger == SOFTWARE)
	{
		cout << "Software trigger chosen..." << endl;
	}
	else if (chosenTrigger == HARDWARE)
	{
		cout << "Hardware trigger chosen..." << endl;
	}

	try
	{
		CEnumerationPtr ptrTriggerMode = nodeMap.GetNode("TriggerMode");
		if (!IsAvailable(ptrTriggerMode) || !IsReadable(ptrTriggerMode))
		{
			cout << "Unable to disable trigger mode (node retrieval). Aborting..." << endl;
			return -1;
		}

		CEnumEntryPtr ptrTriggerModeOff = ptrTriggerMode->GetEntryByName("Off");
		if (!IsAvailable(ptrTriggerModeOff) || !IsReadable(ptrTriggerModeOff))
		{
			cout << "Unable to disable trigger mode (enum entry retrieval). Aborting..." << endl;
			return -1;
		}

		ptrTriggerMode->SetIntValue(ptrTriggerModeOff->GetValue());

		cout << "Trigger mode disabled..." << endl;

		CEnumerationPtr ptrTriggerSource = nodeMap.GetNode("TriggerSource");
		if (!IsAvailable(ptrTriggerSource) || !IsWritable(ptrTriggerSource))
		{
			cout << "Unable to set trigger mode (node retrieval). Aborting..." << endl;
			return -1;
		}

		if (chosenTrigger == SOFTWARE)
		{
			// Set trigger mode to software
			CEnumEntryPtr ptrTriggerSourceSoftware = ptrTriggerSource->GetEntryByName("Software");
			if (!IsAvailable(ptrTriggerSourceSoftware) || !IsReadable(ptrTriggerSourceSoftware))
			{
				cout << "Unable to set trigger mode (enum entry retrieval). Aborting..." << endl;
				return -1;
			}

			ptrTriggerSource->SetIntValue(ptrTriggerSourceSoftware->GetValue());

			cout << "Trigger source set to software..." << endl;
		}
		else if (chosenTrigger == HARDWARE)
		{
			// Set trigger mode to hardware ('Line0')
			CEnumEntryPtr ptrTriggerSourceHardware = ptrTriggerSource->GetEntryByName("Line0");
			if (!IsAvailable(ptrTriggerSourceHardware) || !IsReadable(ptrTriggerSourceHardware))
			{
				cout << "Unable to set trigger mode (enum entry retrieval). Aborting..." << endl;
				return -1;
			}

			ptrTriggerSource->SetIntValue(ptrTriggerSourceHardware->GetValue());

			cout << "Trigger source set to hardware..." << endl;
		}

		CEnumEntryPtr ptrTriggerModeOn = ptrTriggerMode->GetEntryByName("On");
		if (!IsAvailable(ptrTriggerModeOn) || !IsReadable(ptrTriggerModeOn))
		{
			cout << "Unable to enable trigger mode (enum entry retrieval). Aborting..." << endl;
			return -1;
		}

		ptrTriggerMode->SetIntValue(ptrTriggerModeOn->GetValue());

		// TODO: Blackfly and Flea3 GEV cameras need 1 second delay after trigger mode is turned on 

		cout << "Trigger mode turned back on..." << endl << endl;
	}
	catch (Spinnaker::Exception &e)
	{
		cout << "Error: " << e.what() << endl;
		result = -1;
	}

	return result;
}

int ResetTrigger(INodeMap & nodeMap)
{
	int result = 0;

	try
	{
		//
		// Turn trigger mode back off
		//
		// *** NOTES ***
		// Once all images have been captured, turn trigger mode back off to
		// restore the camera to a clean state.
		//
		CEnumerationPtr ptrTriggerMode = nodeMap.GetNode("TriggerMode");
		if (!IsAvailable(ptrTriggerMode) || !IsReadable(ptrTriggerMode))
		{
			cout << "Unable to disable trigger mode (node retrieval). Non-fatal error..." << endl;
			return -1;
		}

		CEnumEntryPtr ptrTriggerModeOff = ptrTriggerMode->GetEntryByName("Off");
		if (!IsAvailable(ptrTriggerModeOff) || !IsReadable(ptrTriggerModeOff))
		{
			cout << "Unable to disable trigger mode (enum entry retrieval). Non-fatal error..." << endl;
			return -1;
		}

		ptrTriggerMode->SetIntValue(ptrTriggerModeOff->GetValue());

		cout << "Trigger mode disabled..." << endl << endl;
	}
	catch (Spinnaker::Exception &e)
	{
		cout << "Error: " << e.what() << endl;
		result = -1;
	}

	return result;
}

int DisableHeartbeat(CameraPtr pCam, INodeMap & nodeMap, INodeMap & nodeMapTLDevice)
{
	cout << "Checking device type to see if we need to disable the camera's heartbeat..." << endl << endl;

	CEnumerationPtr ptrDeviceType = nodeMapTLDevice.GetNode("DeviceType");
	if (!IsAvailable(ptrDeviceType) && !IsReadable(ptrDeviceType))
	{
		cout << "Error with reading the device's type. Aborting..." << endl << endl;
		return -1;
	}
	else
	{
		if (ptrDeviceType->GetIntValue() == DeviceType_GEV)
		{
			cout << "Working with a GigE camera. Attempting to disable heartbeat before continuing..." << endl << endl;
			CBooleanPtr ptrDeviceHeartbeat = nodeMap.GetNode("GevGVCPHeartbeatDisable");
			if (!IsAvailable(ptrDeviceHeartbeat) || !IsWritable(ptrDeviceHeartbeat))
			{
				cout << "Unable to disable heartbeat on camera. Continuing with execution as this may be non-fatal..." << endl << endl;
			}
			else
			{
				ptrDeviceHeartbeat->SetValue(true);
				cout << "WARNING: Heartbeat on GigE camera disabled for the rest of Debug Mode." << endl;
				cout << "         Power cycle camera when done debugging to re-enable the heartbeat..." << endl << endl;
			}
		}
		else
		{
			cout << "Camera does not use GigE interface. Resuming normal execution..." << endl << endl;
		}
	}
	return 0;
}

bool InitCamera()
{
	camsystem = System::GetInstance();
	const LibraryVersion spinnakerLibraryVersion = camsystem->GetLibraryVersion();
	cout << "Spinnaker library version: "
		<< spinnakerLibraryVersion.major << "."
		<< spinnakerLibraryVersion.minor << "."
		<< spinnakerLibraryVersion.type << "."
		<< spinnakerLibraryVersion.build << endl << endl;

	camList = camsystem->GetCameras();

	unsigned int numCameras = camList.GetSize();
	cout << "Number of cameras detected: " << numCameras << endl << endl;


	if (numCameras == 0)
	{
		camList.Clear();
		camsystem->ReleaseInstance();
		return false;
	}

	return true;
}

bool UnInitCamera()
{
	camList.Clear();
	camsystem->ReleaseInstance();
	return true;
}

int main()
{
	clock_t start, finish;
	double totaltime;

	CameraPtr pCam[4] = {NULL};
	try
	{
		if (!InitCamera())
			return -1;

		int cameranumber = camList.GetSize();

		for (unsigned int i = 0; i < cameranumber; i++)
		{
			pCam[i] = camList.GetByIndex(i);

			

			pCam[i]->Init();
			cout << "camera " << i << " init su" << endl;


			INodeMap & nodeMap = pCam[i]->GetNodeMap();
			ConfigureTrigger(nodeMap);
			cout << "camera " << i << "set to software trigger" << endl;

			//CIntegerPtr ptrWidth = nodeMap.GetNode("Width");
			//ptrWidth->SetValue(320);
			//CIntegerPtr ptrHeight = nodeMap.GetNode("Height");
			//ptrHeight->SetValue(240);

			//DisableHeartbeat(pCam[i], pCam[i]->GetNodeMap(), pCam[i]->GetTLDeviceNodeMap());

			pCam[i]->BeginAcquisition();
			
		}

		while (1)
		{
			start = clock();

			//cout << "send trigger command" << endl;
			CCommandPtr ptrSoftwareTriggerCommand[4];
			ImagePtr pResultImage[4];

			for (unsigned int i = 0; i < cameranumber; i++)
			{
				ptrSoftwareTriggerCommand[i] = pCam[i]->GetNodeMap().GetNode("TriggerSoftware");
				if (!IsAvailable(ptrSoftwareTriggerCommand[i]) || !IsWritable(ptrSoftwareTriggerCommand[i]))
				{
					cout << "Unable to execute trigger. Aborting..." << endl;
					return -1;
				}
			}

			for (unsigned int i = 0; i < cameranumber; i++)
			{
				ptrSoftwareTriggerCommand[i]->Execute();

				pResultImage[i] = pCam[i]->GetNextImage();

				if (!pResultImage[i]->IsIncomplete())
				{
					// Convert image to mono 8
					ImagePtr bgrImage = pResultImage[i]->Convert(PixelFormat_BGR8, HQ_LINEAR);

					Mat image = Mat(bgrImage->GetHeight(), bgrImage->GetWidth(), CV_8UC3, bgrImage->GetData());

					string windowname = "image" + to_string(i);

					namedWindow(windowname);
					imshow(windowname, image);

					waitKey(1);
				}
				else
					cout << "Image incomplete with image status " << pResultImage[i]->GetImageStatus() << "..." << endl << endl;
				//sleep(50);
			}
			

			finish = clock();
			totaltime = (double)(finish - start) / CLOCKS_PER_SEC;
			cout << "\n time is:" << totaltime << " " << endl;
		}

		for (unsigned int i = 1; i GetNodeMap();
			ResetTrigger(nodeMap);
			pCam[i]->DeInit();
		}
	}
	catch (Spinnaker::Exception &e)
	{
		cout << "Error: " << e.what() << endl;
	}

	UnInitCamera();
	return 0;
}

cmakelist文件内容

cmake_minimum_required(VERSION 3.5)

add_definitions(-std=c++11)
#项目名称
project(camera)

#代码路径
aux_source_directory(. DIR_TOOT_SRCS)

#dubug 模式
set (CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -g")

find_package(OpenCV REQUIRED)

include_directories(${OpenCV_INCLUDE_DIRS})
include_directories("/usr/include/spinnaker")

#生成可执行的文件
add_executable(camera ${DIR_TOOT_SRCS})

target_link_libraries(camera 
    ${OpenCV_LIBS} 
    Spinnaker )

这里用到了opencv进行图像的显示。

你可能感兴趣的:(相机,opencv,开发技术)