【08】大恒相机SDK C#发开 —— 多相机采集
文章目录
- 1 创建相机类 DhCamera
- 2 主界面
- 3 运行测试 防呆
- 4 视频教程
1 创建相机类 DhCamera
相机类
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using GxIAPINET;namespace multiCam
{internal class DhCamera{IGXStream cam_stream;//相机流对象IGXFeatureControl cam_remote_control;//远端属性控制器IGXFeatureControl cam_control; //本地属性控制器IGXFeatureControl cam_stream_control;//流属性控制器IGXDevice cam;string m_sn;//相机SN public string m_id;//公共的ID变量,在ComboBox中添加相机设备名称public static int cam_num;//全局静态变量,主程序中也要实用static bool colorFlag = false;// 回调函数的 静态变量,是否彩色相机public PictureBox pictureBox;//相机初始化//第一步,对相机资源进行初始化public static void InitCam(){IGXFactory.GetInstance().Init();}public static void UinitCam(){//最后通过反初始化释放所有资源;IGXFactory.GetInstance().Uninit();}//相机信息public void InfoCam(int index){//先定义一个设备列表,用来存放枚举到的设备List<IGXDeviceInfo> iGXDeviceInfos = new List<IGXDeviceInfo>();//枚举同一网段下的相机 无ALLIGXFactory.GetInstance().UpdateDeviceList(1000, iGXDeviceInfos);//枚举同一网络下所有相机 有ALL//IGXFactory.GetInstance().UpdateAllDeviceList(1000, iGXDeviceInfos);m_sn = iGXDeviceInfos[index].GetSN();m_id = iGXDeviceInfos[index].GetDeviceID();}//相机数量public static void GetCamNum(){//先定义一个设备列表,用来存放枚举到的设备List<IGXDeviceInfo> iGXDeviceInfos = new List<IGXDeviceInfo>();//枚举同一网段下的相机 无ALLIGXFactory.GetInstance().UpdateDeviceList(1000, iGXDeviceInfos);//枚举同一网络下所有相机 有ALL//IGXFactory.GetInstance().UpdateAllDeviceList(1000, iGXDeviceInfos);cam_num = iGXDeviceInfos.Count;}//打开相机public void OpenCam(){//打开相机//第四步,打开相机,可以通过IP、SN、MAC、ID等唯一标识符打开相机//这里通过SN打开相机,打开相机的方式有三种: 只读、控制、独占cam = IGXFactory.GetInstance().OpenDeviceBySN(m_sn, GX_ACCESS_MODE.GX_ACCESS_CONTROL);//获取相机属性控制器cam_remote_control = cam.GetRemoteFeatureControl();cam_control = cam.GetFeatureControl();//打开流通道cam_stream = cam.OpenStream(0);//打开流对象属性控制器cam_stream_control = cam_stream.GetFeatureControl();//是否彩色相机__IsSupportColor(ref colorFlag);}public void StartAqc(){//注册回调函数cam_stream.RegisterCaptureCallback(cam, _CallCaptureBack);//开启流通道采集cam_stream.StartGrab();//发送开采命令,设备参数字符串可以去文档里查看cam_remote_control.GetCommandFeature("AcquisitionStart").Execute();}/// <summary>/// 是否支持彩色/// </summary>/// <param name="bIsColorFilter">是否支持彩色</param>private void __IsSupportColor(ref bool bIsColorFilter){bool bIsImplemented = false;bool bIsMono = false;string strPixelFormat = "";strPixelFormat = cam.GetRemoteFeatureControl().GetEnumFeature("PixelFormat").GetValue();if (0 == string.Compare(strPixelFormat, 0, "Mono", 0, 4)){bIsMono = true;}else{bIsMono = false;}bIsImplemented = cam.GetRemoteFeatureControl().IsImplemented("PixelColorFilter");// 若当前为非黑白且支持PixelColorFilter则为彩色if ((!bIsMono) && (bIsImplemented)){bIsColorFilter = true;}else{bIsColorFilter = false;}}//创建回调函数//其中回调函数中包含一个自定义变量和一个图像数据public void _CallCaptureBack(object userParam, IFrameData imgData){//获取并打印图像宽高int imgHeight = (int)imgData.GetHeight();int imgWidth = (int)imgData.GetWidth();//将图像显示在 PictureBox中//判断是黑板还是彩色相机if (colorFlag)//彩色{//获取图像buffer IntPtr buffer = imgData.ConvertToRGB24(GX_VALID_BIT_LIST.GX_BIT_0_7, GX_BAYER_CONVERT_TYPE_LIST.GX_RAW2RGB_NEIGHBOUR, false);//将图像转成BMP格式Bitmap bitmap = new Bitmap(imgWidth, imgHeight, imgWidth * 3, System.Drawing.Imaging.PixelFormat.Format24bppRgb, buffer);//显示图像//由于回调函数相当于开了一个线程,但pictureBox主界面中的对象;//因此需要使用托管的方式对picturebox进行操作Action action = () =>{pictureBox.Image = bitmap;};pictureBox.BeginInvoke(action);}else//黑白{//如果是黑白相机,直接转为bmpBitmap bitmap = new Bitmap(imgWidth, imgHeight, imgWidth, System.Drawing.Imaging.PixelFormat.Format8bppIndexed, imgData.GetBuffer());//需要使用调色盘进行像素翻转System.Drawing.Imaging.ColorPalette colorPalette = bitmap.Palette;for (int i = 0; i < 255; i++){colorPalette.Entries[i] = System.Drawing.Color.FromArgb(i, i, i);}bitmap.Palette = colorPalette;//显示图像//由于回调函数相当于开了一个线程,但pictureBox主界面中的对象;//因此需要使用托管的方式对picturebox进行操作Action action = () =>{pictureBox.Image = bitmap;};pictureBox.BeginInvoke(action);}}private void CloseCam(){//停止采集和关闭相机//关闭相机首先需要先停止流采集;再注销前面所注册的所有回调函数;//关闭采集命令cam_remote_control.GetCommandFeature("AcquisitionStop").Execute();//关闭流通道cam_stream.StopGrab();//关闭回调函数cam_stream.UnregisterCaptureCallback();//关闭相机cam.Close();//最后通过反初始化释放所有资源;//多相机要等所有相机都关闭后,再反初始化;;所以此处先注释掉//IGXFactory.GetInstance().Uninit(); }}
}
2 主界面
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using GxIAPINET;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;namespace multiCam
{public partial class multiCamForm : Form{//先要做一个PictureBox的列表,后面需要将PictureBox的列表放入到类的PictureBox中List<PictureBox> pictureBoxes = new List<PictureBox>();//全局变量相机类的对象的数组DhCamera[] cam;public multiCamForm(){InitializeComponent();DhCamera.InitCam();//将3个PictureBox添加到PictureBox的列表中pictureBoxes.Add(pictureBox1);pictureBoxes.Add(pictureBox2);pictureBoxes.Add(pictureBox3);}private void multiCamForm_Load(object sender, EventArgs e){//获取相机数量DhCamera.GetCamNum();tBoxCamNum.Text = "检测到" + DhCamera.cam_num.ToString() + "个相机";cam = new DhCamera[DhCamera.cam_num];//根据获取到的相机数量定义相机数组长度//通过一个循环,对获取到的相机实例化for (int i = 0; i < DhCamera.cam_num; i++){cam[i] = new DhCamera();//枚举方式获取相机SN编码cam[i].InfoCam(i);//将相机ID放入到ComboBox中cBoxCamName.Items.Add(cam[i].m_id);//将主窗口中的的PictureBox循环的放入到 我们创建相机类对象中去cam[i].pictureBox = pictureBoxes[i];}//对所有的相机进行一个选择cBoxCamName.Items.Add("All");}private void btOpenCam_Click(object sender, EventArgs e){//通过一个循环,对获取到的相机实例化for (int i = 0; i < DhCamera.cam_num; i++){cam[i].OpenCam();}}}
}
3 运行测试 防呆
4 视频教程
【大恒工业相机SDK开发C#版】Winform多相机同时采集(上)