1 class Camera // 大华相机类 2 { 3 private IDevice m_dev; /* 设备对象 */ 4 ListIGrabbedRawData m_frameList = new ListIGrabbedRawData(); /* 图像缓存列表 */ 5 Thread renderThread = null ; /* 显示线程 */ 6 bool m_bShowLoop =
1 class Camera // 大华相机类 2 { 3 private IDevice m_dev; /* 设备对象 */ 4 List<IGrabbedRawData> m_frameList = new List<IGrabbedRawData>(); /* 图像缓存列表 */ 5 Thread renderThread = null; /* 显示线程 */ 6 bool m_bShowLoop = true; /* 线程控制变量 */ 7 Mutex m_mutex = new Mutex(); /* 锁,保证多线程安全 */ 8 // public event Action<HObject> NewImage; // 图像显示事件 9 10 public Camera() 11 { 12 if (null == renderThread) 13 { 14 renderThread = new Thread(new ThreadStart(ShowThread)); 15 renderThread.IsBackground = true; 16 renderThread.Start(); 17 } 18 m_stopWatch.Start();//时间计时开始 19 } 20 21 /* 转码显示线程 */ 22 private void ShowThread() 23 { 24 while (m_bShowLoop)//线程控制变量为True 25 { 26 if (m_frameList.Count == 0) //图像缓存列表 27 { 28 Thread.Sleep(10); 29 continue; 30 } 31 32 /* 图像队列取最新帧 */ 33 m_mutex.WaitOne();//阻止当前线程,直到当前收到信号 34 IGrabbedRawData frame = m_frameList.ElementAt(0);//返回队列中指定索引处的元素 35 m_frameList.RemoveAt(0); 36 m_frameList.Clear(); 37 m_mutex.ReleaseMutex(); 38 39 /* 主动调用回收垃圾 */ 40 GC.Collect(); 41 42 /* 控制显示最高帧率为25FPS */ 43 if (false == isTimeToDisplay()) 44 { 45 continue; 46 } 47 48 try 49 { 50 /* 图像转码成bitmap图像 */ 51 var bitmap = frame.ToBitmap(false); 52 53 // 在这里使用采集的图像 54 //if (NewImage != null) 55 //{ 56 // NewImage(image); 57 //} 58 } 59 catch 60 { 61 62 } 63 } 64 } 65 66 const int DEFAULT_INTERVAL = 40;//默认的时间间隔 67 Stopwatch m_stopWatch = new Stopwatch(); /* 时间统计器 */ 68 69 /* 判断是否应该做显示操作 */ 70 private bool isTimeToDisplay() 71 { 72 m_stopWatch.Stop(); 73 long m_lDisplayInterval = m_stopWatch.ElapsedMilliseconds;//获取实例测量出的总时间 74 if (m_lDisplayInterval <= DEFAULT_INTERVAL) 75 { 76 m_stopWatch.Start(); 77 return false; 78 } 79 else 80 { 81 m_stopWatch.Reset(); 82 m_stopWatch.Start(); 83 return true; 84 } 85 } 86 87 /* 相机打开回调 */ 88 private void OnCameraOpen(object sender, EventArgs e) 89 { 90 // 在这里记录相机已打开 91 } 92 93 /* 相机关闭回调 */ 94 private void OnCameraClose(object sender, EventArgs e) 95 { 96 // 在这里记录相机已关闭 97 } 98 99 /* 相机丢失回调 */ 100 private void OnConnectLoss(object sender, EventArgs e) 101 { 102 m_dev.ShutdownGrab(); 103 m_dev.Dispose(); 104 m_dev = null; 105 } 106 107 /* 码流数据回调 */ 108 private void OnImageGrabbed(Object sender, GrabbedEventArgs e) 109 { 110 m_mutex.WaitOne();// m_mutex锁,保证多线程安全 111 m_frameList.Add(e.GrabResult.Clone());/* 图像缓存列表 */ 112 m_mutex.ReleaseMutex(); 113 } 114 115 /// <summary> 116 /// 打开相机 117 /// </summary> 118 /// <returns>返回字符串为空表示打开成功,不为空表示打开失败,字符串内容为异常信息</returns> 119 /// <param name="triggerSource">触发源选择 软触发或外触发</param> 120 /// <returns></returns> 121 public string Open(string triggerSource) 122 { 123 string sRet = string.Empty; 124 try 125 { 126 /* 设备搜索 */ 127 List<IDeviceInfo> li = Enumerator.EnumerateDevices(); 128 if (li.Count > 0) 129 { 130 /* 获取搜索到的第一个设备 */ 131 m_dev = Enumerator.GetDeviceByIndex(0); 132 133 /* 注册链接事件 */ 134 m_dev.CameraOpened += OnCameraOpen; 135 m_dev.ConnectionLost += OnConnectLoss; 136 m_dev.CameraClosed += OnCameraClose; 137 138 /* 打开设备 */ 139 if (!m_dev.Open()) 140 sRet = "打开相机失败"; 141 142 /* 设置TriggerSource 软触发还是外触发*/ 143 m_dev.TriggerSet.Open(triggerSource); 144 145 /* 设置图像格式 */ 146 using (IEnumParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImagePixelFormat]) 147 { 148 p.SetValue("Mono8"); 149 } 150 151 /* 设置缓存个数为8(默认值为16) */ 152 m_dev.StreamGrabber.SetBufferCount(8); 153 154 /* 注册码流回调事件 */ 155 m_dev.StreamGrabber.ImageGrabbed += OnImageGrabbed; 156 157 /* 开启码流 */ 158 if (!m_dev.GrabUsingGrabLoopThread()) 159 sRet = "开启码流失败"; 160 } 161 else 162 { 163 sRet = "未找到相机设备"; 164 } 165 } 166 catch (Exception e) 167 { 168 sRet = e.Message; 169 } 170 return sRet; 171 } 172 173 /// <summary> 174 /// 关闭相机 175 /// </summary> 176 /// <returns>返回字符串为空表示关闭成功,不为空表示关闭失败,字符串内容为异常信息</returns> 177 public string Close() 178 { 179 string sRet = String.Empty; 180 try 181 { 182 if (m_dev == null) 183 { 184 sRet = "Device is invalid"; 185 } 186 187 m_dev.StreamGrabber.ImageGrabbed -= OnImageGrabbed; /* 反注册回调 */ 188 m_dev.ShutdownGrab(); /* 停止码流 */ 189 m_dev.Close(); /* 关闭相机 */ 190 } 191 catch (Exception e) 192 { 193 sRet = e.Message; 194 } 195 return sRet; 196 } 197 198 /* 窗口关闭 */ 199 public void OnClosed(EventArgs e) 200 { 201 if (m_dev != null) 202 { 203 m_dev.Dispose(); 204 m_dev = null; 205 } 206 207 m_bShowLoop = false; 208 renderThread.Join(); 209 } 210 /// <summary> 211 /// 设置触发模式 软触发下设置On后自由拉流(连续触发)Off(单次触发) 212 /// </summary> 213 /// <param name="value"></param> 214 public string SetTriggerMode(string value="On") 215 { 216 if (m_dev == null) 217 { 218 return "Device is invalid"; 219 } 220 if (!m_dev.IsOpen) 221 { 222 return "相机未打开"; 223 } 224 using (IEnumParameter p = m_dev.ParameterCollection[ParametrizeNameSet.TriggerMode]) 225 { 226 p.SetValue(value); 227 } 228 return ""; 229 } 230 /// <summary> 231 /// 设置曝光 232 /// </summary> 233 /// <param name="value"></param> 234 public string SetExposureTime(float value) 235 { 236 if (m_dev == null) 237 { 238 return "Device is invalid"; 239 } 240 if (!m_dev.IsOpen) 241 { 242 return "相机未打开"; 243 } 244 double min = GetMinExposureTime(); 245 double max = GetMaxExposureTime(); 246 if (value < min || value > max) 247 { 248 return string.Format("参数值不在范围内,min:{0},max:{1}", min, max); 249 } 250 using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ExposureTime]) 251 { 252 p.SetValue(value); 253 } 254 return ""; 255 } 256 /// <summary> 257 /// 设置增益 258 /// </summary> 259 /// <param name="value"></param> 260 public string SetGainRaw(float value) 261 { 262 if (m_dev == null) 263 { 264 return "Device is invalid"; 265 } 266 if (!m_dev.IsOpen) 267 { 268 return "相机未打开"; 269 } 270 double min = GetMinGainRaw(); 271 double max = GetMaxGainRaw(); 272 if (value < min || value > max) 273 { 274 return string.Format("参数值不在范围内,min:{0},max:{1}", min, max); 275 } 276 using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.GainRaw]) 277 { 278 p.SetValue(value); 279 } 280 return ""; 281 } 282 /// <summary> 283 /// 设置图像的宽度 284 /// </summary> 285 /// <param name="value"></param> 286 /// <returns></returns> 287 public string SetImageWidth(int value) 288 { 289 if (m_dev == null) 290 { 291 return "Device is invalid"; 292 } 293 if (!m_dev.IsOpen) 294 { 295 return "相机未打开"; 296 } 297 double min = GetMinImageWidth(); 298 double max = GetMaxImageWidth(); 299 if (value < min || value > max) 300 { 301 return string.Format("参数值不在范围内,min:{0},max:{1}", min, max); 302 } 303 using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageWidth]) 304 { 305 p.SetValue(value); 306 } 307 return ""; 308 } 309 /// <summary> 310 /// 设置图像的宽度 311 /// </summary> 312 /// <param name="value"></param> 313 /// <returns></returns> 314 public string SetImageHeight(int value) 315 { 316 if (m_dev == null) 317 { 318 return "Device is invalid"; 319 } 320 if (!m_dev.IsOpen) 321 { 322 return "相机未打开"; 323 } 324 double min = GetMinImageHeight(); 325 double max = GetMaxImageHeight(); 326 if (value < min || value > max) 327 { 328 return string.Format("参数值不在范围内,min:{0},max:{1}", min, max); 329 } 330 using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageHeight]) 331 { 332 p.SetValue(value); 333 } 334 return ""; 335 } 336 /// <summary> 337 /// 设置图像偏移X 338 /// </summary> 339 /// <param name="value"></param> 340 /// <returns></returns> 341 public string SetImageOffsetX(int value) 342 { 343 if (m_dev == null) 344 { 345 return "Device is invalid"; 346 } 347 if (!m_dev.IsOpen) 348 { 349 return "相机未打开"; 350 } 351 double min = GetMinImageOffsetX(); 352 double max = GetMaxImageOffsetX(); 353 if (value < min || value > max) 354 { 355 return string.Format("参数值不在范围内,min:{0},max:{1}", min, max); 356 } 357 using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetX]) 358 { 359 p.SetValue(value); 360 } 361 return ""; 362 } 363 /// <summary> 364 /// 设置图像偏移Y 365 /// </summary> 366 /// <param name="value"></param> 367 /// <returns></returns> 368 public string SetImageOffsetY(int value) 369 { 370 if (m_dev == null) 371 { 372 return "Device is invalid"; 373 } 374 if (!m_dev.IsOpen) 375 { 376 return "相机未打开"; 377 } 378 double min = GetMinImageOffsetY(); 379 double max = GetMaxImageOffsetY(); 380 if (value < min || value > max) 381 { 382 return string.Format("参数值不在范围内,min:{0},max:{1}", min, max); 383 } 384 using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetY]) 385 { 386 p.SetValue(value); 387 } 388 return ""; 389 } 390 391 #region 获取相机参数的取值范围 392 public double GetMinExposureTime() 393 { 394 using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ExposureTime]) 395 { 396 return p.GetMinimum(); 397 } 398 } 399 public double GetMaxExposureTime() 400 { 401 using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ExposureTime]) 402 { 403 return p.GetMaximum(); 404 } 405 } 406 public double GetMinGainRaw() 407 { 408 using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.GainRaw]) 409 { 410 return p.GetMinimum(); 411 } 412 } 413 public double GetMaxGainRaw() 414 { 415 using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.GainRaw]) 416 { 417 return p.GetMaximum(); 418 } 419 } 420 public long GetMinImageWidth() 421 { 422 using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageWidth]) 423 { 424 return p.GetMinimum(); 425 } 426 } 427 public long GetMaxImageWidth() 428 { 429 using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageWidth]) 430 { 431 return p.GetMaximum(); 432 } 433 } 434 public long GetMinImageHeight() 435 { 436 using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageHeight]) 437 { 438 return p.GetMinimum(); 439 } 440 } 441 public long GetMaxImageHeight() 442 { 443 using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageHeight]) 444 { 445 return p.GetMaximum(); 446 } 447 } 448 public long GetMinImageOffsetX() 449 { 450 using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetX]) 451 { 452 return p.GetMinimum(); 453 } 454 } 455 public long GetMaxImageOffsetX() 456 { 457 using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetX]) 458 { 459 return p.GetMaximum(); 460 } 461 } 462 public long GetMinImageOffsetY() 463 { 464 using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetY]) 465 { 466 return p.GetMinimum(); 467 } 468 } 469 public long GetMaxImageOffsetY() 470 { 471 using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetY]) 472 { 473 return p.GetMaximum(); 474 } 475 } 476 #endregion 477 478 /// <summary> 479 /// bitmap图像转HObject 480 /// </summary> 481 /// <param name="bmp"></param> 482 /// <returns></returns> 483 //private HObject Bitmap2HObjectBpp24(Bitmap bmp) 484 //{ 485 // HObject Hobj; 486 // HOperatorSet.GenEmptyObj(out Hobj); 487 // try 488 // { 489 // Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); 490 491 // BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); 492 // HOperatorSet.GenImageInterleaved(out Hobj, srcBmpData.Scan0, "bgr", bmp.Width, bmp.Height, 0, "byte", 0, 0, 0, 0, -1, 0); 493 // bmp.UnlockBits(srcBmpData); 494 // } 495 // catch (Exception e) 496 // { 497 498 // } 499 // return Hobj; 500 //} 501 }