当前位置:网站首页>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;
//}
}
边栏推荐
- [research data] observation on the differences of health preservation concepts among people in 2022 - Download attached
- Difference between redo and undo
- 【无标题】
- 再回顾集合容器
- After studying 11 kinds of real-time chat software, I found that they all have these functions
- Cookie和Session的相关概念
- Sum the amount
- A quietly rising domestic software, low-key and powerful!
- GC garbage collection
- Source code series of authentic children -inheritablethreadlocal (line by line source code takes you to analyze the author's ideas)
猜你喜欢

今日群里分享的面试题

JVM memory model

振弦采集模块测量振弦传感器的流程步骤

墨天轮沙龙 | 清华乔嘉林:Apache IoTDB,源于清华,建设开源生态之路

Easycvr accesses the equipment through the national standard gb28181 protocol. What is the reason for the automatic streaming of the equipment?

产品模块化设计的前世今生

Optimization of video streaming with repeated requests in the case of unstable easygbs network

Optaplanner learning notes (I) case cloud balance

Is Dao safe? Build finance encountered a malicious governance takeover and was looted!

EasyCVR通过国标GB28181协议接入设备,出现设备自动拉流是什么原因?
随机推荐
Image acquisition and playback of coaxpress high speed camera based on pxie interface
qobject_ Cast usage
MySQL reports an error can't create table 'demo01 tb_ Student‘ (errno: 150)*
【无标题】
振弦采集模塊測量振弦傳感器的流程步驟
How can a programmer grow rapidly
对象的创建
Analysis of GetMessage underlying mechanism
118. Yanghui triangle
Sum the amount
Understand the structure in C language in one article
GC垃圾回收
Graduation season | Huawei experts teach the interview secret: how to get a high paying offer from a large factory?
Win11快捷键切换输入法无反应怎么办?快捷键切换输入法没有反应
Test self-study people must see: how to find test items in software testing?
Technology T3 domestic platform! Successfully equipped with "Yihui domestic real-time system sylixos"
有意思了!数据库也搞Serverless!
Wechat applet navigator has a shadow after clicking. Remove the shadow effect of navigator
MySQL signale une erreur can 't create table' demo01. TB Étudiant '(errno: 150)
DS Transunet:用于医学图像分割的双Swin-Transformer U-Net