大恒水星相机开发记录

大恒水星相机开发记录

前面的话:
最近搞了一个大恒的相机MER-500-14GC,本着这可是行业龙头的工业相机嘛,终归是在学校摸到了真正的工业级产品了。(٩(๑>◡<๑)۶)
想着用opencv调用相机(主要是对opencv比较熟悉嘛,教程也多),不过就是videoCapture嘛,如果是usb口,那直接给编号就可以了,如果的Gige口,那根据规则编一个rtsp流的url就行了嘛,之前海康的相机就是这么用的。但是大恒不提供这个接口。。。o(╥﹏╥)o
阿西吧,这相机绝对是我用过的最难用的相机了。。。(也可能是我c++和Visual Studio用的不熟练吧,我一般都用Clion的,也有可能是大恒都用HALCON的,我还没学这个软件)

目标

本文主要记录博主使用大恒MER-500-14GC相机自己开发,目标环境是linux和QT(c++)

Windows

windows(c++)下的准备工作

  1. 准备相机啦
  2. 去官网下资料:这资料里自带文档这里下的是windows的,毕竟官方文档提供的是windows的例程。
  3. 安装啦
  4. 准备好Visual Studio
  5. 在Visual Studio中新建一个项目,这个项目要和opencv链接好,不会的教程看这个大佬写的超级好
  6. 大恒sdk在VS下环境配置,这个在大恒的资料中就有官方文档,但是有点小错,我这里在重复一遍

在这里插入图片描述

  • 在解决方案资源管理窗口中选中用户创建的工程,然后点击菜单中的project->properties弹出Property page窗口。
    选择Configuration Properties->C/C++ ->General在Additional Include Directories中填写GalaxyIncludes.h所在目录路径地址(依用户安装目录为准)。我的GalaxyIncludes.h路径是:G:\GalaxySDK\Samples\C++ SDK\inc。环境是X64的环境,记着那个opencv的环境也是X64,最后编译环境也是X64
    在这里插入图片描述

  • 配置lib文件
    然后选择Configuration Properties->Linker->General在Additional Library Directories中填写GxIAPICPPEx.lib所在目录路径地址(依用户安装目录为准)。我的是:G:\GalaxySDK\Samples\C++ SDK\lib\x64
    在这里插入图片描述

然后选择Configuration Properties->Linker->Input在Additional Dependencies中填写GxIAPICPPEx.lib并不像图中这样啊

在这里插入图片描述

VS(c++)中调用相机

首先先说官方文档提供的例程:

在这里插入图片描述

这个例程在改了一些代码中各种的小错后,我始终是运行不起来,总是报错,错误代码-8,如下
在这里插入图片描述
阿西吧,为啥啊??趟坑路上处处是雷Σ_(꒪ཀ꒪」∠)

大佬的代码

这里的原文参考自这里:感谢这位大佬拯救了我

  1. 首先在这个路径G:\GalaxySDK\Samples\C++ SDK\inc下的gxsmartptr.h中添加一行#include "GalaxyException.h"
  2. 然后上代码
#include <iostream>
#include <opencv2/opencv.hpp>

#include "GalaxyException.h"
//using namespace cv;
using namespace std;
#include <GalaxyIncludes.h>

cv::Mat img;
//用户继承掉线事件处理类
class CSampleDeviceOfflineEventHandler : public IDeviceOfflineEventHandler
{
public:
	void DoOnDeviceOfflineEvent(void* pUserParam)
	{
		cout << "收到设备掉线事件!" << endl;
	}
};

//用户继承属性更新事件处理类

class CSampleFeatureEventHandler : public IFeatureEventHandler
{
public:
	void DoOnFeatureEvent(const GxIAPICPP::gxstring& strFeatureName, void* pUserParam)
	{
		cout << "收到曝光结束事件!" << endl;
	}
};

//用户继承采集事件处理类
class CSampleCaptureEventHandler : public ICaptureEventHandler
{
public:
	void DoOnImageCaptured(CImageDataPointer& objImageDataPointer, void* pUserParam)
	{
		cout << "收到一帧图像!" << endl;
		cout << "ImageInfo: " << objImageDataPointer->GetStatus() << endl;
		cout << "ImageInfo: " << objImageDataPointer->GetWidth() << endl;
		cout << "ImageInfo: " << objImageDataPointer->GetHeight() << endl;
		cout << "ImageInfo: " << objImageDataPointer->GetPayloadSize() << endl;

		img.create(objImageDataPointer->GetHeight(), objImageDataPointer->GetWidth(), CV_8UC3);
		void* pRGB24Buffer = NULL;
		//假设原始数据是BayerRG8图像
		pRGB24Buffer = objImageDataPointer->ConvertToRGB24(GX_BIT_0_7, GX_RAW2RGB_NEIGHBOUR, true);
		memcpy(img.data, pRGB24Buffer, (objImageDataPointer->GetHeight()) * (objImageDataPointer->GetWidth()) * 3);
		cv::flip(img, img, 0);
		cv::imshow("sss", img);
		cv::waitKey(1);

		cout << "帧数:" << objImageDataPointer->GetFrameID() << endl;
	}
};



int main(int argc, char* argv[])
{

	//声明事件回调对象指针
	IDeviceOfflineEventHandler* pDeviceOfflineEventHandler = NULL;///<掉线事件回调对象
	IFeatureEventHandler* pFeatureEventHandler = NULL;///<远端设备事件回调对象
	ICaptureEventHandler* pCaptureEventHandler = NULL;///<采集回调对象

	//初始化
	IGXFactory::GetInstance().Init();

	try
	{
		do
		{
			//枚举设备
			gxdeviceinfo_vector vectorDeviceInfo;
			IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);
			if (0 == vectorDeviceInfo.size())
			{
				cout << "无可用设备!" << endl;
				break;
			}
			cout << vectorDeviceInfo[0].GetVendorName() << endl;
			cout << vectorDeviceInfo[0].GetSN() << endl;
			//打开第一台设备以及设备下面第一个流
			CGXDevicePointer ObjDevicePtr = IGXFactory::GetInstance().OpenDeviceBySN(
				vectorDeviceInfo[0].GetSN(),
				GX_ACCESS_EXCLUSIVE);
			CGXStreamPointer ObjStreamPtr = ObjDevicePtr->OpenStream(0);

			//注册设备掉线事件【目前只有千兆网系列相机支持此事件通知】
			GX_DEVICE_OFFLINE_CALLBACK_HANDLE hDeviceOffline = NULL;
			pDeviceOfflineEventHandler = new CSampleDeviceOfflineEventHandler();
			hDeviceOffline = ObjDevicePtr->RegisterDeviceOfflineCallback(pDeviceOfflineEventHandler, NULL);

			//获取远端设备属性控制器
			CGXFeatureControlPointer ObjFeatureControlPtr = ObjDevicePtr->GetRemoteFeatureControl();

			//设置曝光时间(示例中写死us,只是示例,并不代表真正可工作参数)
			//ObjFeatureControlPtr->GetFloatFeature("ExposureTime")->SetValue(50);

			//注册远端设备事件:曝光结束事件【目前只有千兆网系列相机支持曝光结束事件】
			//选择事件源
			//ObjFeatureControlPtr->GetEnumFeature("EventSelector")->SetValue("ExposureEnd");

			//使能事件
			//ObjFeatureControlPtr->GetEnumFeature("EventNotification")->SetValue("On");
			//GX_FEATURE_CALLBACK_HANDLE hFeatureEvent = NULL;
			//pFeatureEventHandler = new CSampleFeatureEventHandler();
			//hFeatureEvent = ObjFeatureControlPtr->RegisterFeatureCallback(
			//	"EventExposureEnd",
			//	pFeatureEventHandler,
			//	NULL);

			//注册回调采集
			pCaptureEventHandler = new CSampleCaptureEventHandler();
		ObjStreamPtr->RegisterCaptureCallback(pCaptureEventHandler, NULL);

		//发送开采命令
		ObjStreamPtr->StartGrab();
		ObjFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();

		//此时开采成功,控制台打印信息,直到输入任意键继续
		getchar();

		//发送停采命令
		ObjFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();
		ObjStreamPtr->StopGrab();

		//注销采集回调
		ObjStreamPtr->UnregisterCaptureCallback();

		//注销远端设备事件
			//ObjFeatureControlPtr->UnregisterFeatureCallback(hFeatureEvent);

			//注销设备掉线事件
			//ObjDevicePtr->UnregisterDeviceOfflineCallback(hDeviceOffline);

			//释放资源
			ObjStreamPtr->Close();
		ObjDevicePtr->Close();
		} while (0);
	}

	catch (CGalaxyException& e)
	{
		cout << "错误码: " << e.GetErrorCode() << endl;
		cout << "错误描述信息: " << e.what() << endl;
	}
	catch (std::exception& e)
	{
		cout << "错误描述信息: " << e.what() << endl;
	}

	//反初始化库
	IGXFactory::GetInstance().Uninit();

	//销毁事件回调指针
	if (NULL != pCaptureEventHandler)
	{
		delete pCaptureEventHandler;
		pCaptureEventHandler = NULL;
	}
	if (NULL != pDeviceOfflineEventHandler)
	{
		delete pDeviceOfflineEventHandler;
		pDeviceOfflineEventHandler = NULL;
	}
	if (NULL != pFeatureEventHandler)
	{
		delete pFeatureEventHandler;
		pFeatureEventHandler = NULL;
	}
	return 0;

}

这里我出现了两个结果

  1. 成功执行,显示图像和图像信息在这里插入图片描述
    在这里插入图片描述

  2. 失败,错误代码-8 。。。阿西吧,这里我找了半天错,就是那种同样的代码咋关掉再打开就报错啦??后来发现可能是
    在这里插入图片描述
    也许是这个问题吧,解决方法嘛就果断重启相机试试,哦吼,成了。。。这里之后再看看咋改吧,目前先这样。

windows(python)

比起c++我python更熟悉一些,于是乎又去看了看pyhton的接口
G:\GalaxySDK\Samples\Python SDK这个文件夹中写好了官方给的接口,哦吼吼,这个接口真不错,比C++那个靠谱多了
在这里插入图片描述
我相机彩色的于是乎选了那个color的,完美运行
在这里插入图片描述

这个大概需要一些。。。opencv啊PIL啊numpy啊大概的包吧,这些我都有了就不讲咋安了,都是conda install 或者pip 嘛。
官方提供的那个readme我没用那种安装方法,conda多好,环境这里就不讲了。

OK我们来看看代码,嗯嗯嗯。。。官方接口都给到numpy了,最后用的PIL显示,这不就简单了嘛,分分钟改成opencv的Mat格式。

import gxipy as gx
from PIL import Image
import cv2


def main():
    # print the demo information
    print("")
    print("-------------------------------------------------------------")
    print("Sample to show how to acquire color image continuously and show acquired image.")
    print("-------------------------------------------------------------")
    print("")
    print("Initializing......")
    print("")

    # create a device manager
    device_manager = gx.DeviceManager()
    dev_num, dev_info_list = device_manager.update_device_list()
    if dev_num == 0:
        print("Number of enumerated devices is 0")
        return

    # open the first device
    cam = device_manager.open_device_by_index(1)

    # exit when the camera is a mono camera
    if cam.PixelColorFilter.is_implemented() is False:
        print("This sample does not support mono camera.")
        cam.close_device()
        return

    # set continuous acquisition
    cam.TriggerMode.set(gx.GxSwitchEntry.OFF)

    # set exposure
    cam.ExposureTime.set(10000.0)

    # set gain
    cam.Gain.set(10.0)

    # get param of improving image quality
    if cam.GammaParam.is_readable():
        gamma_value = cam.GammaParam.get()
        gamma_lut = gx.Utility.get_gamma_lut(gamma_value)
    else:
        gamma_lut = None
    if cam.ContrastParam.is_readable():
        contrast_value = cam.ContrastParam.get()
        contrast_lut = gx.Utility.get_contrast_lut(contrast_value)
    else:
        contrast_lut = None
    if cam.ColorCorrectionParam.is_readable():
        color_correction_param = cam.ColorCorrectionParam.get()
    else:
        color_correction_param = 0

    # start data acquisition
    cam.stream_on()

    # acquisition image: num is the image number
    num = 1
    for i in range(num):
        # get raw image
        raw_image = cam.data_stream[0].get_image()
        if raw_image is None:
            print("Getting image failed.")
            continue

        # get RGB image from raw image
        rgb_image = raw_image.convert("RGB")
        if rgb_image is None:
            continue

        # improve image quality
        rgb_image.image_improvement(color_correction_param, contrast_lut, gamma_lut)

        # create numpy array with data from raw image
        numpy_image = rgb_image.get_numpy_array()
        if numpy_image is None:
            continue

        # show acquired image

        # 这里改用opencv显示
        cv_img = cv2.cvtColor(numpy_image, cv2.COLOR_BGR2RGB)
        cv2.imshow("opencv", cv_img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

        # 这里用PIL显示
        img = Image.fromarray(numpy_image, 'RGB')
        img.show()

        # print height, width, and frame ID of the acquisition image
        print("Frame ID: %d   Height: %d   Width: %d"
              % (raw_image.get_frame_id(), raw_image.get_height(), raw_image.get_width()))

    # stop data acquisition
    cam.stream_off()

    # close device
    cam.close_device()


if __name__ == "__main__":
    main()

还是python简单啊,唉,要不是行业里都是C++部署,python多好用啊,唉。

相机的内部设定

照出来的图像各种参数,颜色,饱和度,伽马值,亮度啥的这些其实是用官方文档里写的接口去调的,调好了直接写在相机内部,这里由于本博主太菜,且发现用demo也能调,所以嘛就不费事了。
下载的资料中,官方提供了一个工具demo,GalaxyView.exe,这个咋用官方文档里写的清清楚楚,我只讲一下用这个设置相机,这里如图:
在这里插入图片描述

把插件下面第2,3,4全打开

在这里插入图片描述
可以看到这里可以进行各种设定,原理这里我也不是很懂,之前我都是采集上来用opencv或者imaug去调的,而像这种工业相机应该是要用自己的库,所以这种调整处理是大恒官方写的,文档里有方法,这里就不深究了。
这里调好了就写入到设备里,这样就OK了。

ubuntu系统

c++接口

  1. 这里在官网下载指定的SDK

  2. 根据readme安装,这里会在环境变量中添加几个路径,所以安装完了不能改路径

  3. 安装完成后进入看bin目录下的GalaxyView和GxGigeIPConfig和windows下的一样设置一下ip

  4. 重点:我是直接网口连的电脑主板,在上一步发现读取不到图像信息。询问技术客服后解决

    1. 方法:设置网口的mtu<字节> 设置网络设备的MTU
      在这里插入图片描述
    2. 之前是1500,现在设置成8192
      在这里插入图片描述
    3. 这里也要设置成8192(默认就是,但是还是要看一眼)
      在这里插入图片描述
  5. OK,这样运行提供的例子就没问题了

python接口

这里下载的linux文件没有提供python接口
其实直接把windows提供的python—SDK拿过来用就行了

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值