机器视觉之Basler工业相机使用和配置方法(C++)

这篇具有很好参考价值的文章主要介绍了机器视觉之Basler工业相机使用和配置方法(C++)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

basler工业相机做双目视觉用,出现很多问题记录一下:

首先是多看手册:https://zh.docs.baslerweb.com/software

手册内有所有的源码和参考示例,实际上在使用过程中,大部分都是这些源码,具体项目选择对应的示例代码。

一、相机和镜头选型

可以通过balser的镜头选型工具,按照自己需要测量目标的距离,目标大小等信息进行配置选择,地址在这;界面如下:
机器视觉之Basler工业相机使用和配置方法(C++),双目视觉,c++,计算机视觉,视觉检测
相机的焦距大小一般和测量的目标距离有关系,一般对应的选择方式总结如下:
(1)焦距越小,测量的范围越大,相应的,目标一般都看起来很小,类似于手机拍照的最小倍数拍摄目标;
(2)焦距越大,测量范围就越窄,对远距离小目标的检查就比较好,但是太大的焦距会导致大目标容易拍不全,类似与手机拍照放大倍数拍摄目标;
(3)具体有计算公式,可以参考,建议直接通过basler的配置工具进行选择

二、相机安装和使用

(1)balser相机使用需要网线和电源线(12V供电),可以在官网找对应的线材;
(2)相机接上电源,网线连接计算机后,去官网下载相机软件和驱动,一般windows下安装后,会在目录下生成对应的文件夹,包括C++对应的库和参考代码示例等,linux下直接下载tar.gz包,解压防止到对应的文件目录下,执行:source pylon目录/bin/pylon-setup-env.sh ./pylon目录 即可,例如我安装的是pylon7.3.0,解压后的目录为:/opt/pylon7,里面直接就是inlcude这些文件夹,在linux下目录执行:

source /opt/pylon7/bin/pylon-setup-env.sh /opt/pylon7

完成linux下相机驱动和环境的安装。
(3)配置相机IP,windows下配置相机IP可以使用basler的工具:
ipconfigurator,Linux下如果安装的系统有GUI界面,一样可以使用,配置相机IP地址,保证IP地址和接计算机的接口IP地址在同一网段即可,子网掩码推荐255。255.255.0,厂家说其他的可能会出现异常断开错误;
(4)IP配置完成后,在windows下启动pylon Viewer工具,查看相机,能找到相机说明IP配置正确,确保计算机和相机处于同一个网段内
(5)要保持basler相机的帧率,需要保证千兆网,如果是两个相机,连交换机之后就要求是2000M的网,依次类推,才可以达到最大帧率,否则会出现相机丢帧等问题,直连相机到计算机不影响,开启巨帧数就行了。

三、C++调用相机环境部署

1.相机驱动和软件安装完成后,有以下文件夹:
机器视觉之Basler工业相机使用和配置方法(C++),双目视觉,c++,计算机视觉,视觉检测
开发环境在development文件夹下,linux下解压之后是:
机器视觉之Basler工业相机使用和配置方法(C++),双目视觉,c++,计算机视觉,视觉检测
2.可以使用visua studio等C++ IDE开发工具进行编程,将依赖库和头文件等信息通过链接include和lib文件,即可开始相机调用;

四、C++相机调用

1.相机初始化:

相机初始化包括寻找相机,匹配对应相机,还可以设置相机的曝光,帧率,增益等,两个相机的初始化,依据API文档整理如下:
参加API:Grab_MultipleCameras

void initCamera()
{
    try
    {
        PylonInitialize();	//初始化
        CTlFactory& tlFactory = CTlFactory::GetInstance();
        pTL = dynamic_cast<IGigETransportLayer*>(tlFactory.CreateTl( BaslerGigEDeviceClass ));
        if (pTL == NULL)
        {
            throw RUNTIME_EXCEPTION( "No GigE cameras available." );
        }

        DeviceInfoList_t allDeviceInfos;
        if (pTL->EnumerateDevices( allDeviceInfos ) == 0)
        {
            throw RUNTIME_EXCEPTION( "No GigE cameras available." );
        }

        DeviceInfoList_t usableDeviceInfos;
        string left_camera_ip="172.16.105.21"
		//left_camera_ip 用于区分两个相机,可以通过配置的IP,序列号等进行区分
        if (string(allDeviceInfos[0].GetIpAddress()) == left_camera_ip) {
            usableDeviceInfos.push_back(allDeviceInfos[0]);
            subnet = allDeviceInfos[0].GetSubnetAddress();//主相机
            usableDeviceInfos.push_back(allDeviceInfos[1]);
            LOG(INFO)<<"主相机:"<<allDeviceInfos[0].GetIpAddress()<<endl;
            LOG(INFO)<<"副相机:"<<allDeviceInfos[1].GetIpAddress()<<endl;
        }
        else if(string(allDeviceInfos[1].GetIpAddress()) == left_camera_ip) {
            usableDeviceInfos.push_back(allDeviceInfos[1]);
            subnet = allDeviceInfos[1].GetSubnetAddress();//主相机
            usableDeviceInfos.push_back(allDeviceInfos[0]);
            LOG(INFO)<<"主相机IP:"<<allDeviceInfos[1].GetIpAddress()<<endl;
            LOG(INFO)<<"SubnetAddress:"<<allDeviceInfos[1].GetSubnetAddress()<<endl;
            LOG(INFO)<<"DefaultGateway:"<<allDeviceInfos[1].GetDefaultGateway()<<endl;
            LOG(INFO)<<"SubnetMask:"<<allDeviceInfos[1].GetSubnetMask()<<endl;

            LOG(INFO)<<"副相机IP:"<<allDeviceInfos[0].GetIpAddress()<<endl;
            LOG(INFO)<<"SubnetAddress:"<<allDeviceInfos[0].GetSubnetAddress()<<endl;
            LOG(INFO)<<"DefaultGateway:" <<allDeviceInfos[0].GetDefaultGateway()<<endl;
            LOG(INFO)<<"SubnetMask:"<<allDeviceInfos[0].GetSubnetMask()<<endl;


        }
        else{
            LOG(INFO) << "Camera IP is error ,please set IP" << endl;
        }
       // CInstantCameraArray cameras = { 2 };
       //初始化两个相机
        for (size_t i = 0; i < 2; ++i)
        {
            cameras[i].Attach(tlFactory.CreateDevice(usableDeviceInfos[i]));
            const CBaslerGigEDeviceInfo& di = cameras[i].GetDeviceInfo();
            LOG(INFO) << "Camera serial: " << di.GetSerialNumber() << endl;
        }

//        srand( (unsigned) time( NULL ) );
//        DeviceKey = rand();
//        GroupKey = 0x112233;

        for (size_t i = 0; i < cameras.GetSize(); ++i)
        {
            cameras[i].Attach( tlFactory.CreateDevice( usableDeviceInfos[i] ) );
            //cameras[i].RegisterConfiguration( new CActionTriggerConfiguration( DeviceKey, GroupKey, AllGroupMask ), RegistrationMode_Append, Cleanup_Delete );
            //cameras[i].SetCameraContext( i );
            const CBaslerGigEDeviceInfo& di = cameras[i].GetDeviceInfo();
            cout << "Using camera " << i << ": " << di.GetSerialNumber() << " (" << di.GetIpAddress() << ")" << endl;
        }

        cameras.Open();

        //相机基本设置
        SetCamera(cameras[0], Type_Basler_ExposureTimeAbs, expore_time_l);			//曝光时间
        SetCamera(cameras[0], Type_Basler_GainRaw, gain_l);						//增益
        SetCamera(cameras[0], Type_Basler_AcquisitionFrameRateAbs, fps_l);			//频率
        SetCamera(cameras[0], Type_Basler_Width, 2448);
        SetCamera(cameras[0], Type_Basler_Height, 2048);

        SetCamera(cameras[1], Type_Basler_ExposureTimeAbs, expore_time_r);			//曝光时间
        SetCamera(cameras[1], Type_Basler_GainRaw, gain_r);						//增益
        SetCamera(cameras[1], Type_Basler_AcquisitionFrameRateAbs, fps_r);			//频率
        SetCamera(cameras[1], Type_Basler_Width, 2448);
        SetCamera(cameras[1], Type_Basler_Height, 2048);

        //设置相机触发模式 	TriggerSelector
        //TriggerSoftware
        //主相机设置为软件触发,输出设置为exposure active
        //SetCamera(cameras[0], Type_Basler_Freerun, 0);

        //从相机设置:触发模式为外触发,IO设置为1
        //SetCamera(cameras[1], Type_Basler_Line1, 0);

    }
    catch (const GenericException& e)
    {
        if(cameras.IsGrabbing())
            cameras.StopGrabbing();
        // Error handling
        LOG(INFO) << "init,An exception occurred." << endl
                  << e.GetDescription() << endl;
    }
}

2.调用相机

调用相机时,最容易出现的问题是,grab image丢帧,在抓取图像丢帧的原因中,主要是由相机帧率设置过大,带宽不足等问题导致。
其中:
if(cameras.IsGrabbing()) 这句可以改成while循环,这样就可以持续输出,if表示就近输出了,根据实际使用情况而定,基本上抓取一帧在50ms左右。其中 cameras.StartGrabbing()可以放在初始化中,这样就不停的抓取,能够保证1秒20帧,不用频繁开始抓取和停止抓取,实际上很耗时。

void GetCameraImage() {
	try {
        //pTL->IssueActionCommand(DeviceKey, GroupKey, AllGroupMask, subnet );
		//1秒内抓取了多少张图,全部存下来
        int skiptime = 1000;
        //LOG(INFO)<<"采集图像的最长时间:"<<skiptime<<" ms"<<endl;
        cameras.StartGrabbing(GrabStrategy_OneByOne,GrabLoop_ProvidedByUser);

        if(cameras.IsGrabbing()) {
            std::chrono::high_resolution_clock::time_point tStartTime(std::chrono::high_resolution_clock::now());
            int lTimeAloInterval = 0;
            count_grab_once++;
            cameras[0].RetrieveResult(skiptime, ptrGrabResultl, TimeoutHandling_ThrowException);
            cameras[1].RetrieveResult(skiptime, ptrGrabResultr, TimeoutHandling_ThrowException);

            if (ptrGrabResultl->GrabSucceeded() && ptrGrabResultr->GrabSucceeded() ) {
                intptr_t cameraContextValuel = ptrGrabResultl->GetCameraContext();
                intptr_t cameraContextValuer = ptrGrabResultr->GetCameraContext();
                const uint8_t *pImageBufferl = (uint8_t *) ptrGrabResultl->GetBuffer();
                const uint8_t *pImageBufferr = (uint8_t *) ptrGrabResultr->GetBuffer();
                // 将 pylon image转成OpenCV image.
                Mat SaveImagel = cv::Mat(ptrGrabResultl->GetHeight(), ptrGrabResultl->GetWidth(), CV_8UC1,
                                        (uint8_t *) pImageBufferl);
                Mat SaveImager = cv::Mat(ptrGrabResultr->GetHeight(), ptrGrabResultr->GetWidth(), CV_8UC1,
                                         (uint8_t *) pImageBufferr);

               
            }
         
            lTimeAloInterval =std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1, 1000> >>(std::chrono::high_resolution_clock::now() - tStartTime).count();
            LOG(INFO) << "------------ single Grab image cost time:----------------" << lTimeAloInterval << " ms" << endl;
        }
        cameras.StopGrabbing();
	}
	catch (const GenericException& e)
	{
        if(cameras.IsGrabbing())
            cameras.StopGrabbing();
		// Error handling
		LOG(INFO) << "An exception occurred." << endl
			<< e.GetDescription() << endl;
	}
	
}

3.关闭相机

相机及时关闭:

void CloseCamera()
{
	//最后终止Pylon相机,即调用PylonTerminate。//关闭摄像头
	try
	{
		if (cameras.IsOpen()) {
			cameras.DetachDevice();
			cameras.Close();
			cameras.DestroyDevice();
			//关闭库
			LOG(INFO) << "SBaslerCameraControl deleteAll: PylonTerminate";
			PylonTerminate();
		}
	}
	catch (const Pylon::GenericException& e)
	{
		LOG(INFO) << "close camera failed..." << e.what();
	}
}

五、常见问题

1.相机连不上

IP配置不正确,确保在同一网段,子网掩码相同。

2.连接后丢帧

 Error: e1004 The bufer was incopletely gratbed. This can be caused by perfomnane problens of the metwork hardware used,fer underuns can also case ina loss.To fix this, us the pylonbioEtonfigurator tol to optinize your setip and use more uffers for aratbin in your aplication to prerent buferunderruns

常见于连接多个相机的时候出现,确保开启巨帧,相机帧率和网络传输的帧率是否满足要求,参加API手册
机器视觉之Basler工业相机使用和配置方法(C++),双目视觉,c++,计算机视觉,视觉检测

3.相机连接后,使用过程中出现找得到相机,但卡住不动了

这种问题不知道是什么原因导致的,因为可以找到相机,而且也能连上相机,所以大概率是以下几种可能:
(1)可能是长时间没调用导致相机休眠,关机重启下可解决。
(2)相机打开过程中异常中断,即句柄没有被释放,这种情况使用官方给的软件pylon Viewer重新打开和关闭一下即可恢复。
机器视觉之Basler工业相机使用和配置方法(C++),双目视觉,c++,计算机视觉,视觉检测

4.grab time out 抓取超时

一般是设置waittime时间太短导致,可以改大一些:

 cameras[1].RetrieveResult(waittime, ptrGrabResultr, TimeoutHandling_ThrowException);

还有一种可能是相机连上之后一直么有抓取成功,导致等待时间过长,需要检查代码,常见有时候做触发的操作导致。文章来源地址https://www.toymoban.com/news/detail-732318.html

到了这里,关于机器视觉之Basler工业相机使用和配置方法(C++)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 机器视觉_工业相机及相关配件选型

    凭我的经验,一般能带上工业两字的,和日常版最大的区别就是更稳定、抗干扰能力更强(高温、高压、防尘、防水、防爆、抗电磁干扰等;列举这么多,并不意味着必须带有这些功能,这些功能通常是可定制的),当然还有其他特点,比如接口可扩展、定制性比较强等。

    2024年02月13日
    浏览(36)
  • 机器视觉海康工业相机SDK参数设置获取

    视觉人机器视觉培训-缺陷检测项目-食品行业草鸡蛋外观检测 相机参数类型可分为六类,除 command 参数外,每一类都有其对应的设置与获取函数接口。 表 1 参数类型及对应函数接口介绍 *详细函数接口可参考 SDK 手册: ​C:Program Files (x86)MVSDevelopmentDocumentations 相机参数类型

    2024年02月07日
    浏览(71)
  • 工业视觉相机镜头选型方法

    一、相机选型 1、首先,根据检测需求确定选用黑白/彩色、面阵/线阵相机,接口类型一般选择GigE 2、确定检测精度要求(最小特征尺寸mm)、视野范围,一个测量精度对应几个像素数(一般取3-5) 3、计算 单 方向分辨率=单方向视野范围/检测精度*像素倍数 4、选择分辨率大于

    2024年02月12日
    浏览(30)
  • 【重明】机器视觉QT/C++实现工业相机二次开发框架

    工业相机二次开发是机器视觉行业必不可少的技能之一。 而如何实现一个框架,能够兼容所有工业相机二次开发,从而支持多种类型的工业相机,就是机器视觉行业的进阶技能了。 重明工业相机二次开发项目就是在实现相机二开框架的基础上,完成了海康工业相机的二次开

    2024年02月02日
    浏览(35)
  • 【机器视觉】电脑连接相机配置的二三事

            最近手上有个机器视觉项目,现场总是反馈相机拍照取图是取的上一次的图,折腾很久,发现是配置的锅,这里记录下,防止下次再犯。 举例:第一个网口:100.100. 100 .100     第二个网口:100.100. 101 .200 第三位必须要不同网段: IP设置不对,都没法连接相机   

    2024年02月09日
    浏览(25)
  • Baumer工业相机堡盟工业相机如何使用BGAPISDK生成视频(C++)

    Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理 Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具有快速数据传输、低功耗、易于集成以及高度可扩展

    2024年02月08日
    浏览(24)
  • Baumer工业相机堡盟工业相机如何使用OpenCV实现相机图像的显示(C++)

    ​ Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具有快速数据传输、低功耗、易于集成以及高度

    2024年01月20日
    浏览(25)
  • Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用相机日志跟踪功能(C++)

    Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具有快速数据传输、低功耗、易于集成以及高度可扩

    2024年01月22日
    浏览(40)
  • Baumer工业相机堡盟工业相机如何通过BGAPISDK使用短曝光功能(C++)

    Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具有快速数据传输、低功耗、易于集成以及高度可扩

    2024年02月10日
    浏览(28)
  • Baumer工业相机堡盟工业相机如何通过BGAPISDK使用AutoFocus自动对焦功能(C++)

    Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具有快速数据传输、低功耗、易于集成以及高度可扩

    2024年02月09日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包