VS2017下用C++调用Point Grey相机采集视频帧

项目所需全部环境:

  • OpenCV
  • Spinnaker

上述环境是以我自己的代码可以运行为前提而配置的。

OpenCV

VS2017配置OpenCV可以参考这篇帖子:VS2017配置OpenCV-超详细教程 按照这个帖子来,可以成功配置OpenCV,但有几处可以精简。

1.环境变量

如图,加入 "D:\opencv\build\x64\vc15\bin"即可。

2.进入VS2017进行项目环境配置

原作者写的过于繁杂,在此精简,步骤为:

项目(P)  > 你自己的项目名 属性(P) >VC++目录 

VC++目录下只需要更改两个地方:包含目录、库目录。

包含目录

包含目录中需要存放的是 你下载的OpenCV文件夹中的include文件夹的位置,下面两张图可以很好地指明。

将include文件夹下的"D:\opencv\build\include\opencv"和"D:\opencv\build\include\opencv"都加入包含目录中。(不清楚为啥会有opencv和opencv2两个文件夹,保险起见都加进去吧)。至此包含目录配置完成。

库目录

库目录话不多说,直接上图。

按照图中的路径定位到你自己电脑上相应的位置,在x64文件夹下会有vc14和vc15两个文件夹,因为我们用的是VS2017,所以选用vc15(新版本的VS,比如VS2019,VS2022,下载的就是更新版本的OpenCV了,找好相应的版本就行)。

VC++相关的内容已经配置好了,下一步进入"链接器"。

链接器

链接器 > 输入 > 附加依赖项

在此处添加"opencv_world341d.lib",如图所示:

至此,环境配置全部结束。在原作者的帖子里,第六步“勾选微软符号服务器(此步为可选项)”就不要去配置了,百害而无一利。可以根据原帖的最后一步检测自己的OpenCV是否装好,如果没有图片显示出来,逛逛这个帖子下的评论区,可以解决,因为99%的概率是配环境的过程中哪里不小心搞错了,要耐心去排查。

Spinnaker

SpinnakerOpenCV一样,都是让我们程序运行起来的工具,所以它的配置和上述的OpenCV几乎一样,只需要配置VC++目录下的包含目录、库目录,以及链接器中的附加依赖项就可以了,是不是很熟悉!我也放入以下三图供大家参考。贴心的一批!

检验下自己的Spinnaker有没有装好,复制这段代码运行,会出现Spinnaker版本库的版本号

#include<stdio.h>
#include<tchar.h>
#include "Spinnaker.h"
#include <iostream>
#include "SpinGenApi/SpinnakerGenApi.h"

using namespace Spinnaker;
using namespace Spinnaker::GenApi;
using namespace Spinnaker::GenICam;
using namespace std;
int main()
{
	SystemPtr system = System::GetInstance();
	LibraryVersion lv = system->GetLibraryVersion();
	const LibraryVersion spinnakerLibraryVersion = system->GetLibraryVersion();
	cout << "Spinnaker library version: " << spinnakerLibraryVersion.major << "." << spinnakerLibraryVersion.minor
		<< "." << spinnakerLibraryVersion.type << "." << spinnakerLibraryVersion.build << endl
		<< endl;
	return 0;
}

运行结果如下:

在这里,有一个大坑。我之前安装的Spinnaker版本是3.x.x.xxx,而我的代码中有一句死活都报错,凭我多年的经验,我感觉是版本的问题,于是下载了比较低的版本(2.0.0.147),代码就一路绿灯了。

运行代码

// 测试用例 -- 两部相机正常调用
#include <iostream>
#include<sstream>
#include "Spinnaker.h"
#include "SpinGenApi/SpinnakerGenApi.h"
#include "opencv2/opencv.hpp"
using namespace Spinnaker;
using namespace Spinnaker::GenApi;
using namespace Spinnaker::GenICam;
using namespace cv;
using namespace std;

#define IMG_WIDTH 640
#define IMG_HEIGHT 480

// 传入参数类型为CameraList
void RunCameras(CameraList camList)
{
	// 创建一个OpenCV的图像对象
	cv::Size img_size(IMG_WIDTH, IMG_HEIGHT);

	// 循环遍历相机列表 camlist 中所有相机
	for (int i = 0; i < camList.GetSize(); ++i)
	{
		// 获取索引为i的相机,并赋值给 pCam 相机指针
		CameraPtr pCam = camList.GetByIndex(i);

		// 获取相机的设备映射点
		INodeMap& nodeMapTLDevice = pCam->GetTLDeviceNodeMap();
		
		// 初始化相机
		pCam->Init();

		// 获取相机的节点映射
		INodeMap& nodeMap = pCam->GetNodeMap();

		// 从相机的节点映射中获取了名为 "AcquisitionMode" 的节点
		// 并将其赋值给名为 ptrAcquisitionMode 的枚举指针。
		CEnumerationPtr ptrAcquisitionMode = nodeMap.GetNode("AcquisitionMode");

		// 从"AcquisitionMode"节点的枚举值中获取了名为"Continuous"的枚举条目
		// 并赋值给"ptrAcquisitionModeContinuous"枚举条目指针
		CEnumEntryPtr ptrAcquisitionModeContinuous = ptrAcquisitionMode->GetEntryByName("Continuous");

		// 获取"Continuous"的值,并赋值给acquisitionModeContinuous
		const int64_t acquisitionModeContinuous = ptrAcquisitionModeContinuous->GetValue();

		// 将相机的采集模式设置为连续模式
		ptrAcquisitionMode->SetIntValue(acquisitionModeContinuous);

		// 开始相机的图像采集过程,从此开始相机会持续获取图像。
		pCam->BeginAcquisition();
	}

	char q;  // 接收用户键入
	while (true)
	{
		Mat l_img, r_img;  // 定义2个OpenCV图像对象,用于存储左、右相机的图像
		for (int i = 0; i < camList.GetSize(); ++i)
		{
			CameraPtr pCam = camList.GetByIndex(i);

			// 从相机中获取下一帧图像,最多等待1秒钟,将结果保存在pResultImage中
			ImagePtr pResultImage = pCam->GetNextImage(1000);

			// 获取图像的宽度和高度
			const size_t width = pResultImage->GetWidth();
			const size_t height = pResultImage->GetHeight();


			// 将获取到的图像转换为RGB8格式
			ImagePtr convertedImage = pResultImage->Convert(PixelFormat_RGB8, NEAREST_NEIGHBOR);
			
			// 将转换后的图像数据转为OpenCV的Mat格式
			// Mat cvimg = cv::Mat(height, width, CV_8UC3, pResultImage->GetData(), pResultImage->GetStride());
			Mat cvimg = cv::Mat(height, width, CV_8UC3, convertedImage->GetData(), convertedImage->GetStride());
			
			// 将左右相机的图像进行尺寸调整,并存储在l_img和r_img中
			if (i == 0) {
				cv::resize(cvimg, l_img, img_size);
			}
			else {
				cv::resize(cvimg, r_img, img_size);
			}
			pResultImage->Release();  // 释放获取到的图像资源
		}

		// 显示图像
		cv::imshow("camera_1", l_img);
		cv::imshow("camera_2", r_img);

		// 等待用户键入
		q = cv::waitKey(1);
		if (q == 'q') break;  // 结束图像采集过程
	}
	for (int i = 0; i < camList.GetSize(); ++i)
	{
		CameraPtr pCam = camList.GetByIndex(i);
		pCam->EndAcquisition();  // 结束相机的图像采集
		pCam->DeInit();  // 对相机进行反初始化,可能是释放资源等操作
	}
}


int main()
{
	// InitRecorreParams();
	// 获取一个系统实例,用于初始化和管理相机
	SystemPtr system = System::GetInstance();

	// 获取Spinnaker库的版本信息,并输出至控制台
	const LibraryVersion spinnakerLibraryVersion = system->GetLibraryVersion();
	cout << "Spinnaker library version: " << spinnakerLibraryVersion.major << "." << spinnakerLibraryVersion.minor
		<< "." << spinnakerLibraryVersion.type << "." << spinnakerLibraryVersion.build << endl
		<< endl;
	
	// 获取了相机列表,即检测到的所有连接至计算机的相机
	CameraList camList = system->GetCameras();

	// 获取相机数量并输出至控制台
	const unsigned int numCameras = camList.GetSize();
	cout << "Number of cameras detected: " << numCameras << endl << endl;
	if (numCameras == 0)
	{
		std::cout << "no cameras..." << std::endl;
		return 1;
	}


	CameraPtr pCam = nullptr;
	int result = 0;

	// 创建2个窗口,分别用于显示左右相机的图像
	cv::namedWindow("camera_1", cv::WINDOW_NORMAL);
	cv::namedWindow("camera_2", cv::WINDOW_NORMAL);

	RunCameras(camList);  // 采集相机图像并在窗口中显示

	// 清理操作:将相机指针置为空指针;清空相机列表;释放相机系统实例。
	pCam = nullptr;
	camList.Clear();
	system->ReleaseInstance();

	// 等待用户按下Enter键,然后返回result
	cout << endl << "Done! Press Enter to exit..." << endl;
	getchar();
	return result;
}

在电脑上接入2部相机,在此用的是Point Grey相机,只需要将相机的USB接口插入电脑就行了。不需要其他软件(比如Spin View)。看看最终的运行结果吧!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值