当前位置:网站首页>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;
//}
}
边栏推荐
- Redis installation and startup in Windows environment (background startup)
- Basic use of MySQL
- [research materials] Huawei Technology ICT 2021: at the beginning of the "Yuan" year, the industry is "new" -- download attached
- STC 32位8051单片机开发实例教程 二 I/O工作模式及其配置
- HLS4ML/vivado HLS 报错解决方案
- 利用win7漏洞进行系统登录密码破解
- Win11暂停更新点不了怎么办?Win11暂停更新是灰色的如何解决?
- Bao, what if the O & M 100+ server is a headache? Use Xingyun housekeeper!
- 使用Zadig从0到1搭建持续交付平台
- [SQL optimization] the difference between with as and temporary tables
猜你喜欢
Mo Tianlun salon | Tsinghua qiaojialin: Apache iotdb, originated from Tsinghua, builds an open source ecological road
Leetcode 1380 lucky numbers in matrix [array] the leetcode path of heroding
产品模块化设计的前世今生
Oracle physical architecture
P2433 [deep foundation 1-2] primary school mathematics n in one
Hls4ml entry method
通过js实现金字塔(星号金字塔,回文对称数字金字塔)
1592 例题1 国王(Sgu223 LOJ10170 LUOGU1896 提高+/省选-) 暴力思考 状压DP 01背包
Optaplanner learning notes (I) case cloud balance
GaussDB(for MySQL) :Partial Result Cache,通过缓存中间结果对算子进行加速
随机推荐
【多线程】锁策略
[exercise] HashSet
[research materials] iResearch tide Watching: seven major trends in the clothing industry - Download attached
February 15, 2022: sweeping robot. There is a floor sweeping robot in the room (represented by a grid). Each grid in the grid has two possibilities: empty and obstacles. The sweeping robot provides fo
面试题篇一
What is the essential difference between Bi development and report development?
一文读懂C语言中的结构体
开发那些事儿:EasyCVR集群设备管理页面功能展示优化
Time series analysis using kibana timelion
对象的创建
科技T3国产平台!成功搭载“翼辉国产实时系统SylixOS”
利用win7漏洞进行系统登录密码破解
Regular expression =regex=regular expression
118. Yanghui triangle
JDBC中如何添加事务
[SQL optimization] the difference between with as and temporary tables
New window open page -window open
Oracle physical architecture
EasyCVR通过国标GB28181协议接入设备,出现设备自动拉流是什么原因?
实例讲解将Graph Explorer搬上JupyterLab