大恒水星相机开发记录

前面的话:
最近搞了一个大恒的相机 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();
			//枚举设备
			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拿过来用就行了

大恒水星相机开发记录前面的话:最近搞了一个大恒的相机MER-500-14GC,本着这可是行业龙头的工业相机嘛,终归是在学校摸到了真正的工业级产品了。(٩(๑&gt;◡&lt;๑)۶)想着用opencv调用相机(主要是对opencv比较熟悉嘛,教程也多),不过就是videoCapture嘛,如果是usb口,那直接给编号就可以了嘛,如果的Gige口,那根据规则编一个rtsp流的url就行了嘛,之前海康的相机就是这么用的,也挺好的啊。但是大恒不提供这个接口。。。o(╥﹏╥)o阿西吧,这相机绝对是我用过的最
if (enDstPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8) //************************Mono8 转 Bitmap******************************* Bitmap bmp = new Bitmap(stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.nWidth * 1, PixelFormat.Format8bpp
大恒水星相机自带开发包,安装好相机的驱动后就可以打开vs查看里面的源码了。不过为了方便开发,打算直接使用halcon的接口进行图像的采集。 开始采用了halcon10+VS2010+win10的系统配置,但是安装相机驱动后能够检测到相机,但是总是无法采集图像,提示错误。而换到win7系统就可以使用安装的大恒的图像采集软件了。所以就装了一个win7的双系统。 使用halcon10的图像采集助手
视觉萌新买了工业相机却不会用,上网也查不到具体方法,没办法只能自己硬刚了。刚开始自己摸索,碰到好多问题解决不了,Qt报错不知道咋回事,缺少的链接库一下载就是无法固定软件位置,还以为自己的系统有问题。 还好买相机时商家给了相机使用方法的相关文件,在我几乎绝望的时候,硬是把相关文件全部翻了一遍,才搞明白到底咋用。在安装好相机驱动后的文件夹中有详细的教程,还有相关例程。 我针对自己的配置过程进行了
直接复制和调试大恒相机自带的C++开发软件开发说明书中的示例工程,报错众多,无从下手。 终于经过注释多处代码,跑通了!以此为记,再接再厉。 #include <QDebug> #include "GalaxyIncludes.h" // 用户继承掉线事件处理类 class CSampleDeviceOfflineEventHandler : public IDeviceOfflineEventHandler public : void DoOnDeviceOfflineEvent(voi
Ubuntu16 Linux Opencv4安装与g++编译运行 Ubuntu16 Linux Opencv4安装与g++编译运行 别人写的Opencv4基本安装步骤(安装结束在CLion环境中可运行,但是g++可能会有问题):https://www.jianshu.com/p/f54b0fc13811 g++在终端运行代码(对于Opencv4要加入c++11支持,编写的cpp代码里应该是incl...
水星摄像头; 路由器:电信配的路由器限制ip,只能接8个ip,所以用以前的送的磊科路由器当第二层交换机,分配ip。 插上12v电,插上网线,去路由器里面找到IP。 192.168.2.16. 进入摄像头的设置界面,设置一
使用OpenCV和大恒C SDK可以轻松地采集大恒水星相机的图像。首先,需要下载和安装相应的SDK和库,并确保与相机的连接正常。接下来,可以使用OpenCV提供的函数来打开相机,并设置相应的参数,如分辨率和帧率。然后,可以通过循环不断地从相机中读取图像帧,并使用OpenCV进行图像处理和分析。 可以使用OpenCV中的cv::VideoCapture类来打开相机连接,并设置相应的参数。例如: cv::VideoCapture capture; capture.open(0); // 打开相机连接 if (!capture.isOpened()) { // 相机连接失败 return -1; capture.set(cv::CAP_PROP_FRAME_WIDTH, 1280); // 设置图像宽度 capture.set(cv::CAP_PROP_FRAME_HEIGHT, 720); // 设置图像高度 capture.set(cv::CAP_PROP_FPS, 30); // 设置帧率 然后,可以在循环中读取相机图像,并使用OpenCV函数进行处理。例如,可以使用cv::imshow函数显示图像,使用cv::imwrite保存图像,使用cv::cvtColor将图像转换为不同的颜色空间等等。 cv::Mat frame; while (capture.read(frame)) { cv::imshow("Camera", frame); // 显示图像 // 进行其他的图像处理操作 int key = cv::waitKey(1); if (key == 27) { // 按下Esc键退出循环 break; 最后,记得在程序结束时,释放相机连接和关闭窗口: capture.release(); // 释放相机连接 cv::destroyAllWindows(); // 关闭窗口 以上就是使用OpenCV和大恒C SDK采集大恒水星相机图像的基本步骤。可以根据实际需求,结合OpenCV提供的丰富功能,进行图像处理、计算机视觉和图像分析等任务。