当前位置:网站首页>C#聯合halcon應用——大華相機采集類
C#聯合halcon應用——大華相機采集類
2022-07-01 19:54: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;
//}
}
边栏推荐
猜你喜欢
使用Zadig从0到1搭建持续交付平台
Servlet knowledge points
Cookie和Session的相关概念
STC 32位8051单片机开发实例教程 二 I/O工作模式及其配置
Interview questions shared in today's group
Win11怎么关闭开机自启动软件
EasyCVR通过国标GB28181协议接入设备,出现设备自动拉流是什么原因?
How to configure webrtc video streaming format for easygbs, a new version of national standard gb28181 video platform?
Process steps of vibrating wire acquisition module for measuring vibrating wire sensor
Procédure de mesure du capteur d'accord vibrant par le module d'acquisition d'accord vibrant
随机推荐
Interview question 1
How to correctly use vertx to operate redis (3.9.4 with source code analysis)
Detailed configuration of network security "Splunk" in national vocational college skills competition
一文读懂C语言中的结构体
How to use console Log print text?
Mo Tianlun salon | Tsinghua qiaojialin: Apache iotdb, originated from Tsinghua, builds an open source ecological road
mysql 報錯 Can‘t create table ‘demo01.tb_Student‘ (errno: 150)*
STC 32位8051单片机开发实例教程 三 程序编译设置与下载
Anaconda installs the virtual environment to the specified path
js三元表达式复杂条件判断
[research materials] national second-hand housing market monthly report January 2022 - Download attached
一个悄然崛起的国产软件,低调又强大!
CMU AI PhD first year summary
Gaussdb (for MySQL):partial result cache, which accelerates the operator by caching intermediate results
强大、好用、适合程序员/软件开发者的专业编辑器/笔记软件综合评测和全面推荐
HLS4ML/vivado HLS 报错解决方案
MYSLQ十种锁,一篇文章带你全解析
一个程序员如何快速成长
Remove line breaks from MySQL query results
EasyCVR集群视频广场页面切换时,请求流未能终止的问题优化