当前位置:网站首页>C#联合halcon应用——大华相机采集类
C#联合halcon应用——大华相机采集类
2022-07-01 18:47:00 【123梦野】
大华相机采集类
class Camera // 大华相机类
{
private IDevice m_dev; /* 设备对象 */
List<IGrabbedRawData> m_frameList = new List<IGrabbedRawData>(); /* 图像缓存列表 */
Thread renderThread = null; /* 显示线程 */
bool m_bShowLoop = true; /* 线程控制变量 */
Mutex m_mutex = new Mutex(); /* 锁,保证多线程安全 */
// public event Action<HObject> NewImage; // 图像显示事件
public Camera()
{
if (null == renderThread)
{
renderThread = new Thread(new ThreadStart(ShowThread));
renderThread.IsBackground = true;
renderThread.Start();
}
m_stopWatch.Start();//时间计时开始
}
/* 转码显示线程 */
private void ShowThread()
{
while (m_bShowLoop)//线程控制变量为True
{
if (m_frameList.Count == 0) //图像缓存列表
{
Thread.Sleep(10);
continue;
}
/* 图像队列取最新帧 */
m_mutex.WaitOne();//阻止当前线程,直到当前收到信号
IGrabbedRawData frame = m_frameList.ElementAt(0);//返回队列中指定索引处的元素
m_frameList.RemoveAt(0);
m_frameList.Clear();
m_mutex.ReleaseMutex();
/* 主动调用回收垃圾 */
GC.Collect();
/* 控制显示最高帧率为25FPS */
if (false == isTimeToDisplay())
{
continue;
}
try
{
/* 图像转码成bitmap图像 */
var bitmap = frame.ToBitmap(false);
// 在这里使用采集的图像
//if (NewImage != null)
//{
// NewImage(image);
//}
}
catch
{
}
}
}
const int DEFAULT_INTERVAL = 40;//默认的时间间隔
Stopwatch m_stopWatch = new Stopwatch(); /* 时间统计器 */
/* 判断是否应该做显示操作 */
private bool isTimeToDisplay()
{
m_stopWatch.Stop();
long m_lDisplayInterval = m_stopWatch.ElapsedMilliseconds;//获取实例测量出的总时间
if (m_lDisplayInterval <= DEFAULT_INTERVAL)
{
m_stopWatch.Start();
return false;
}
else
{
m_stopWatch.Reset();
m_stopWatch.Start();
return true;
}
}
/* 相机打开回调 */
private void OnCameraOpen(object sender, EventArgs e)
{
// 在这里记录相机已打开
}
/* 相机关闭回调 */
private void OnCameraClose(object sender, EventArgs e)
{
// 在这里记录相机已关闭
}
/* 相机丢失回调 */
private void OnConnectLoss(object sender, EventArgs e)
{
m_dev.ShutdownGrab();
m_dev.Dispose();
m_dev = null;
}
/* 码流数据回调 */
private void OnImageGrabbed(Object sender, GrabbedEventArgs e)
{
m_mutex.WaitOne();// m_mutex锁,保证多线程安全
m_frameList.Add(e.GrabResult.Clone());/* 图像缓存列表 */
m_mutex.ReleaseMutex();
}
/// <summary>
/// 打开相机
/// </summary>
/// <returns>返回字符串为空表示打开成功,不为空表示打开失败,字符串内容为异常信息</returns>
/// <param name="triggerSource">触发源选择 软触发或外触发</param>
/// <returns></returns>
public string Open(string triggerSource)
{
string sRet = string.Empty;
try
{
/* 设备搜索 */
List<IDeviceInfo> li = Enumerator.EnumerateDevices();
if (li.Count > 0)
{
/* 获取搜索到的第一个设备 */
m_dev = Enumerator.GetDeviceByIndex(0);
/* 注册链接事件 */
m_dev.CameraOpened += OnCameraOpen;
m_dev.ConnectionLost += OnConnectLoss;
m_dev.CameraClosed += OnCameraClose;
/* 打开设备 */
if (!m_dev.Open())
sRet = "打开相机失败";
/* 设置TriggerSource 软触发还是外触发*/
m_dev.TriggerSet.Open(triggerSource);
/* 设置图像格式 */
using (IEnumParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImagePixelFormat])
{
p.SetValue("Mono8");
}
/* 设置缓存个数为8(默认值为16) */
m_dev.StreamGrabber.SetBufferCount(8);
/* 注册码流回调事件 */
m_dev.StreamGrabber.ImageGrabbed += OnImageGrabbed;
/* 开启码流 */
if (!m_dev.GrabUsingGrabLoopThread())
sRet = "开启码流失败";
}
else
{
sRet = "未找到相机设备";
}
}
catch (Exception e)
{
sRet = e.Message;
}
return sRet;
}
/// <summary>
/// 关闭相机
/// </summary>
/// <returns>返回字符串为空表示关闭成功,不为空表示关闭失败,字符串内容为异常信息</returns>
public string Close()
{
string sRet = String.Empty;
1 try
{
if (m_dev == null)
{
sRet = "Device is invalid";
}
m_dev.StreamGrabber.ImageGrabbed -= OnImageGrabbed; /* 反注册回调 */
m_dev.ShutdownGrab(); /* 停止码流 */
m_dev.Close(); /* 关闭相机 */
}
catch (Exception e)
{
sRet = e.Message;
}
return sRet;
}
/* 窗口关闭 */
public void OnClosed(EventArgs e)
{
if (m_dev != null)
{
m_dev.Dispose();
m_dev = null;
}
m_bShowLoop = false;
renderThread.Join();
}
/// <summary>
/// 设置触发模式 软触发下设置On后自由拉流(连续触发)Off(单次触发)
/// </summary>
/// <param name="value"></param>
public string SetTriggerMode(string value = "On")
{
if (m_dev == null)
{
return "Device is invalid";
}
if (!m_dev.IsOpen)
{
return "相机未打开";
}
using (IEnumParameter p = m_dev.ParameterCollection[ParametrizeNameSet.TriggerMode])
{
p.SetValue(value);
}
return "";
}
/// <summary>
/// 设置曝光
/// </summary>
/// <param name="value"></param>
public string SetExposureTime(float value)
{
if (m_dev == null)
{
return "Device is invalid";
}
if (!m_dev.IsOpen)
{
return "相机未打开";
}
double min = GetMinExposureTime();
double max = GetMaxExposureTime();
if (value < min || value > max)
{
return string.Format("参数值不在范围内,min:{0},max:{1}", min, max);
}
using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ExposureTime])
{
p.SetValue(value);
}
return "";
}
/// <summary>
/// 设置增益
/// </summary>
/// <param name="value"></param>
public string SetGainRaw(float value)
{
if (m_dev == null)
{
return "Device is invalid";
}
if (!m_dev.IsOpen)
{
return "相机未打开";
}
double min = GetMinGainRaw();
double max = GetMaxGainRaw();
if (value < min || value > max)
{
return string.Format("参数值不在范围内,min:{0},max:{1}", min, max);
}
using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.GainRaw])
{
p.SetValue(value);
}
return "";
}
/// <summary>
/// 设置图像的宽度
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public string SetImageWidth(int value)
{
if (m_dev == null)
{
return "Device is invalid";
}
if (!m_dev.IsOpen)
{
return "相机未打开";
}
double min = GetMinImageWidth();
double max = GetMaxImageWidth();
if (value < min || value > max)
{
return string.Format("参数值不在范围内,min:{0},max:{1}", min, max);
}
using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageWidth])
{
p.SetValue(value);
}
return "";
}
/// <summary>
/// 设置图像的宽度
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public string SetImageHeight(int value)
{
if (m_dev == null)
{
return "Device is invalid";
}
if (!m_dev.IsOpen)
{
return "相机未打开";
}
double min = GetMinImageHeight();
double max = GetMaxImageHeight();
if (value < min || value > max)
{
return string.Format("参数值不在范围内,min:{0},max:{1}", min, max);
}
using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageHeight])
{
p.SetValue(value);
}
return "";
}
/// <summary>
/// 设置图像偏移X
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public string SetImageOffsetX(int value)
{
if (m_dev == null)
{
return "Device is invalid";
}
if (!m_dev.IsOpen)
{
return "相机未打开";
}
double min = GetMinImageOffsetX();
double max = GetMaxImageOffsetX();
if (value < min || value > max)
{
return string.Format("参数值不在范围内,min:{0},max:{1}", min, max);
}
using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetX])
{
p.SetValue(value);
}
return "";
}
/// <summary>
/// 设置图像偏移Y
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public string SetImageOffsetY(int value)
{
if (m_dev == null)
{
return "Device is invalid";
}
if (!m_dev.IsOpen)
{
return "相机未打开";
}
double min = GetMinImageOffsetY();
double max = GetMaxImageOffsetY();
if (value < min || value > max)
{
return string.Format("参数值不在范围内,min:{0},max:{1}", min, max);
}
using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetY])
{
p.SetValue(value);
}
return "";
}
#region 获取相机参数的取值范围
public double GetMinExposureTime()
{
using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ExposureTime])
{
return p.GetMinimum();
}
}
public double GetMaxExposureTime()
{
using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ExposureTime])
{
return p.GetMaximum();
}
}
public double GetMinGainRaw()
{
using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.GainRaw])
{
return p.GetMinimum();
}
}
public double GetMaxGainRaw()
{
using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.GainRaw])
{
return p.GetMaximum();
}
}
public long GetMinImageWidth()
{
using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageWidth])
{
return p.GetMinimum();
}
}
public long GetMaxImageWidth()
{
using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageWidth])
{
return p.GetMaximum();
}
}
public long GetMinImageHeight()
{
using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageHeight])
{
return p.GetMinimum();
}
}
public long GetMaxImageHeight()
{
using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageHeight])
{
return p.GetMaximum();
}
}
public long GetMinImageOffsetX()
{
using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetX])
{
return p.GetMinimum();
}
}
public long GetMaxImageOffsetX()
{
using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetX])
{
return p.GetMaximum();
}
}
public long GetMinImageOffsetY()
{
using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetY])
{
return p.GetMinimum();
}
}
public long GetMaxImageOffsetY()
{
using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetY])
{
return p.GetMaximum();
}
}
#endregion
/// <summary>
/// bitmap图像转HObject
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
//private HObject Bitmap2HObjectBpp24(Bitmap bmp)
//{
// HObject Hobj;
// HOperatorSet.GenEmptyObj(out Hobj);
// try
// {
// Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
// BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
// HOperatorSet.GenImageInterleaved(out Hobj, srcBmpData.Scan0, "bgr", bmp.Width, bmp.Height, 0, "byte", 0, 0, 0, 0, -1, 0);
// bmp.UnlockBits(srcBmpData);
// }
// catch (Exception e)
// {
// }
// return Hobj;
//}
}
边栏推荐
猜你喜欢

STC 32位8051单片机开发实例教程 三 程序编译设置与下载

全国职业院校技能大赛网络安全“splunk“详细配置

MYSLQ十种锁,一篇文章带你全解析

Procédure de mesure du capteur d'accord vibrant par le module d'acquisition d'accord vibrant

Shell advanced

Win11如何取消任务栏隐藏?Win11取消任务栏隐藏的方法
![[AI server setup] CUDA environment](/img/ca/2acfc42ea3ba24934a89472a8632f6.png)
[AI server setup] CUDA environment

Graduation season | Huawei experts teach the interview secret: how to get a high paying offer from a large factory?

科技T3国产平台!成功搭载“翼辉国产实时系统SylixOS”

解决VSCode下载慢或下载失败的问题
随机推荐
2022/6/8-2022/6/12
Interview question 1
Anaconda安装虚拟环境到指定路径
毕业季 | 华为专家亲授面试秘诀:如何拿到大厂高薪offer?
自定义插入页面标签以及实现类似通讯录的首字母搜索
对象的创建
ModSim基本使用(Modbus模拟器)
torch. nn. functional. Interpolate function
较真儿学源码系列-InheritableThreadLocal(逐行源码带你分析作者思路)
使用 Kibana Timelion 进行时间序列分析
1592 例题1 国王(Sgu223 LOJ10170 LUOGU1896 提高+/省选-) 暴力思考 状压DP 01背包
SQL getting started plan-1-select
Define dichotomy lookup
How to configure webrtc video streaming format for easygbs, a new version of national standard gb28181 video platform?
今日群里分享的面试题
Detailed configuration of network security "Splunk" in national vocational college skills competition
Linux下安装Redis,并配置环境
How to correctly use vertx to operate redis (3.9.4 with source code analysis)
Shell advanced
What is the essential difference between Bi development and report development?