MainWindow.xaml.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. using System;
  2. using System.Windows;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. using System.IO;
  6. using System.Collections.Generic;
  7. using Microsoft.Win32;
  8. using System.Drawing;
  9. using Accord.Video;
  10. using Accord.Video.FFMPEG;
  11. using Accord.Video.DirectShow;
  12. using CameraDataCapture;
  13. using AI.Common;
  14. using AI.Common.Log;
  15. using Rect = AI.Common.Rect;
  16. using ImageShowUtilsLib;
  17. using System.Windows.Controls;
  18. using Intel.RealSense;
  19. using RUSCommon;
  20. using System.Diagnostics;
  21. using System.Drawing.Imaging;
  22. using System.Runtime.InteropServices;
  23. using Size = System.Drawing.Size;
  24. using Rectangle = System.Drawing.Rectangle;
  25. using RUSCommon.CameraConfigure;
  26. namespace CameraImageCaptureTest
  27. {
  28. /// <summary>
  29. /// MainWindow.xaml 的交互逻辑
  30. /// </summary>
  31. public partial class MainWindow : Window
  32. {
  33. #region private
  34. private CameraDataCapture.CameraDataCapture _cameraImageCapture;
  35. private ManualResetEvent _playEvent = new ManualResetEvent(false);
  36. private VideoFileReader _videoReader;
  37. private readonly object _videoReaderLocker = new object();
  38. private VideoCaptureDevice _videoCapture;
  39. // 相机图像
  40. private bool _isConfirmCameraInfo;// 是否已确认相机信息
  41. private CameraInformation _cameraInfo;
  42. private ICameraPara _cameraPara;
  43. private DateTime _cameraImageReceiveStartTime;
  44. private volatile int _cameraImageReceiveCount = 0;
  45. #endregion
  46. #region 用户界面响应
  47. public MainWindow()
  48. {
  49. InitializeComponent();
  50. try
  51. {
  52. RefreshComboBoxVideoCards();
  53. // 遍历所有的相机、采集卡
  54. var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
  55. foreach (var device in videoDevices)
  56. {
  57. ComboBoxCameras.Items.Add(device);
  58. }
  59. // 相机类型
  60. ComboBoxCameraType.Items.Add("单目");
  61. ComboBoxCameraType.Items.Add("双目");
  62. ComboBoxCameraType.Items.Add("realsense");
  63. ComboBoxCameraType.Items.Add("知微");
  64. ComboBoxCameraType.SelectedIndex = -1;
  65. }
  66. catch (Exception e)
  67. {
  68. MessageBox.Show("初始化过程中出错:" + e);
  69. }
  70. }
  71. /// <summary>
  72. /// 用户关闭窗口
  73. /// </summary>
  74. /// <param name="sender"></param>
  75. /// <param name="e"></param>
  76. private void OnWindowClosing(object sender, System.ComponentModel.CancelEventArgs e)
  77. {
  78. StopPlay();
  79. // 如果已打开相机,则关闭
  80. if (_cameraImageCapture != null)
  81. {
  82. _cameraImageCapture.StopCameraDataAcquire();
  83. _cameraImageCapture.NotifyCameraDataUpdate -= OnCameraDatasUpdate;
  84. _cameraImageCapture.NotifyError -= OnErrorOccur;
  85. _cameraImageCapture.Dispose();
  86. _cameraImageCapture = null;
  87. // 记录一下总共收到多少幅相机图像(主要用来对比一下保存数据输入记录、启用模型监测和不做任何操作时,是否有影响帧率)
  88. var timeSpan = DateTime.Now - _cameraImageReceiveStartTime;
  89. LogHelper.InfoLog("TotalReceivedCameraImageCount:" + _cameraImageReceiveCount + ",TimeSpan:" + timeSpan.TotalMilliseconds + "(ms).", string.Empty);
  90. BtnOpenCameras.Content = "打开相机";
  91. _isConfirmCameraInfo = false;
  92. TextCameraProcessTime.Text = string.Empty;
  93. // 清除耗时显示
  94. Dispatcher.Invoke(() =>
  95. {
  96. TextCameraProcessTime.Text = string.Empty;
  97. });
  98. }
  99. }
  100. /// <summary>
  101. /// 选择相机类型
  102. /// </summary>
  103. /// <param name="sender"></param>
  104. /// <param name="e"></param>
  105. private void OnComboBoxCameraTypeSelectionChanged(object sender, SelectionChangedEventArgs e)
  106. {
  107. if (_isConfirmCameraInfo)
  108. {
  109. MessageBox.Show("注意是否已打开相机,如需重新选择相机类型,请先关闭相机后再重新打开");
  110. }
  111. switch (ComboBoxCameraType.SelectedIndex)
  112. {
  113. case 0:
  114. _cameraInfo.CameraType = EnumCameraType.CameraMonocular;
  115. break;
  116. case 1:
  117. _cameraInfo.CameraType = EnumCameraType.CameraStereo;
  118. break;
  119. case 2:
  120. _cameraInfo.CameraType = EnumCameraType.CameraRealSense435;
  121. break;
  122. case 3:
  123. _cameraInfo.CameraType = EnumCameraType.CameraZhiSensor;
  124. break;
  125. }
  126. }
  127. /// <summary>
  128. /// 打开相机
  129. /// </summary>
  130. /// <param name="sender"></param>
  131. /// <param name="e"></param>
  132. private void OnBtnOpenCameraClick(object sender, RoutedEventArgs e)
  133. {
  134. if (ComboBoxCameraType.SelectedIndex == -1)
  135. {
  136. MessageBox.Show("未选中相机类型");
  137. return;
  138. }
  139. if (ComboBoxCameras.SelectedIndex == -1)
  140. {
  141. MessageBox.Show("未选中相机源(用于拍摄人体和探头二维码模块)");
  142. return;
  143. }
  144. // 如果已打开相机,则关闭
  145. if (_cameraImageCapture != null)
  146. {
  147. _cameraImageCapture.StopCameraDataAcquire();
  148. _cameraImageCapture.NotifyCameraDataUpdate -= OnCameraDatasUpdate;
  149. _cameraImageCapture.NotifyError -= OnErrorOccur;
  150. _cameraImageCapture.Dispose();
  151. _cameraImageCapture = null;
  152. // 记录一下总共收到多少幅相机图像(主要用来对比一下保存数据输入记录、启用模型监测和不做任何操作时,是否有影响帧率)
  153. var timeSpan = DateTime.Now - _cameraImageReceiveStartTime;
  154. LogHelper.InfoLog("TotalReceivedCameraImageCount:" + _cameraImageReceiveCount + ",TimeSpan:" + timeSpan.TotalMilliseconds + "(ms).", string.Empty);
  155. BtnOpenCameras.Content = "打开相机";
  156. _isConfirmCameraInfo = false;
  157. TextCameraProcessTime.Text = string.Empty;
  158. // 清除耗时显示
  159. Dispatcher.Invoke(() =>
  160. {
  161. TextCameraProcessTime.Text = string.Empty;
  162. });
  163. }
  164. else
  165. {
  166. // 检查有没有重复打开同一个视频源
  167. var device = (FilterInfo)ComboBoxCameras.SelectedItem;
  168. var deviceName = device.MonikerString;
  169. _cameraInfo.CameraDeviceName = deviceName;
  170. // 临时设置相机参数
  171. SetCameraPara(_cameraInfo.CameraType);
  172. // todo 根据不同的相机类型选则相应实例
  173. switch (_cameraInfo.CameraType)
  174. {
  175. case EnumCameraType.CameraMonocular:
  176. break;
  177. case EnumCameraType.CameraStereo:
  178. break;
  179. case EnumCameraType.CameraRealSense435:
  180. break;
  181. case EnumCameraType.CameraZhiSensor:
  182. _cameraInfo.CameraDeviceName = "192.168.6.115";
  183. break;
  184. default:
  185. break;
  186. }
  187. _cameraImageCapture = new CameraDataCapture.CameraDataCapture(_cameraInfo);
  188. _cameraImageCapture.NotifyCameraDataUpdate += OnCameraDatasUpdate;
  189. _cameraImageCapture.NotifyError += OnErrorOccur;
  190. _cameraPara = _cameraImageCapture.GetCameraParaInfo;
  191. _cameraImageCapture.StartCameraDataAcquire();
  192. BtnOpenCameras.Content = "关闭相机";
  193. _isConfirmCameraInfo = true;
  194. _cameraImageReceiveStartTime = DateTime.Now;
  195. }
  196. }
  197. /// <summary>
  198. /// 加载视频
  199. /// </summary>
  200. /// <param name="sender"></param>
  201. /// <param name="e"></param>
  202. private void OnBtnLoadVideoClick(object sender, RoutedEventArgs e)
  203. {
  204. StopPlay();
  205. var ofd = new OpenFileDialog();
  206. ofd.Filter = "图像或视频|*.png;*.bmp;*.jpg;*.jpeg;*.mp4;*.avi";
  207. ofd.Multiselect = false;
  208. ofd.Title = "选择一幅图像或一个视频";
  209. if (ofd.ShowDialog() == true)
  210. {
  211. var fileName = ofd.FileName;
  212. var fileExtension = Path.GetExtension(fileName);
  213. if (fileExtension == ".png" || fileExtension == ".bmp" || fileExtension == ".jpg" || fileExtension == ".jpeg")
  214. {
  215. var bitmap = new Bitmap(fileName);
  216. MyImageCanvas.UpdateRGBImage(bitmap);
  217. bitmap.Dispose();
  218. }
  219. else
  220. {
  221. double frameRate;
  222. long frameCount;
  223. lock (_videoReaderLocker)
  224. {
  225. _videoReader = new VideoFileReader();
  226. _videoReader.Open(fileName);
  227. frameRate = _videoReader.FrameRate.ToDouble();
  228. frameCount = _videoReader.FrameCount;
  229. }
  230. var sleepTime = (int)(1000 / frameRate);
  231. _playEvent.Reset();
  232. Task.Run(() =>
  233. {
  234. bool breakFlag = false;
  235. for (var ni = 0; ni < frameCount; ni++)
  236. {
  237. if (_playEvent.WaitOne(1))
  238. {
  239. breakFlag = true;
  240. break;
  241. }
  242. var currentTickCount = Environment.TickCount;
  243. Bitmap bitmap;
  244. lock (_videoReaderLocker)
  245. {
  246. bitmap = _videoReader.ReadVideoFrame(ni);
  247. }
  248. if (bitmap == null)
  249. {
  250. continue;
  251. }
  252. MyImageCanvas.UpdateRGBImage(bitmap);
  253. bitmap.Dispose();
  254. var detectTimeUsed = Environment.TickCount - currentTickCount;
  255. var finalSleepTime = sleepTime - detectTimeUsed;
  256. if (finalSleepTime < 0)
  257. {
  258. finalSleepTime = 0;
  259. }
  260. if (_playEvent.WaitOne(finalSleepTime))
  261. {
  262. breakFlag = true;
  263. break;
  264. }
  265. }
  266. if (!breakFlag)
  267. {
  268. lock (_videoReaderLocker)
  269. {
  270. _videoReader.Close();
  271. _videoReader.Dispose();
  272. _videoReader = null;
  273. }
  274. }
  275. });
  276. }
  277. }
  278. }
  279. /// <summary>
  280. /// 被选择的采集卡有变
  281. /// </summary>
  282. /// <param name="sender"></param>
  283. /// <param name="e"></param>
  284. private void OnComboBoxCardsSelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
  285. {
  286. StopPlay();
  287. }
  288. /// <summary>
  289. /// 刷新所有采集卡
  290. /// </summary>
  291. /// <param name="sender"></param>
  292. /// <param name="e"></param>
  293. private void OnRefreshCardsClick(object sender, RoutedEventArgs e)
  294. {
  295. RefreshComboBoxVideoCards();
  296. }
  297. /// <summary>
  298. /// 打开采集卡
  299. /// </summary>
  300. /// <param name="sender"></param>
  301. /// <param name="e"></param>
  302. private void OnBtnOpenGrabClick(object sender, RoutedEventArgs e)
  303. {
  304. if (ComboBoxCameras.SelectedIndex != -1)
  305. {
  306. StopPlay();
  307. var device = (FilterInfo)ComboBoxCameras.SelectedItem;
  308. _videoCapture = new VideoCaptureDevice(device.MonikerString);
  309. _videoCapture.NewFrame += OnVideoCaptureNewFrame;
  310. _videoCapture.Start();
  311. }
  312. else
  313. {
  314. MessageBox.Show("未检测到可用的视频采集设备!");
  315. }
  316. }
  317. #endregion
  318. #region private
  319. /// <summary>
  320. /// 刷新列表中的采集卡
  321. /// </summary>
  322. private void RefreshComboBoxVideoCards()
  323. {
  324. StopPlay();
  325. ComboBoxCameras.Items.Clear();
  326. var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
  327. foreach (var device in videoDevices)
  328. {
  329. ComboBoxCameras.Items.Add(device);
  330. }
  331. if (ComboBoxCameras.Items.Count > 0)
  332. {
  333. ComboBoxCameras.SelectedIndex = 0;
  334. }
  335. }
  336. /// <summary>
  337. /// 视频更新了一幅新的图像
  338. /// </summary>
  339. private void OnVideoCaptureNewFrame(object sender, NewFrameEventArgs e)
  340. {
  341. var bitmap = e.Frame;
  342. MyImageCanvas.UpdateRGBImage(bitmap);
  343. bitmap.Dispose();
  344. }
  345. /// <summary>
  346. /// 停止播放视频
  347. /// </summary>
  348. private void StopPlay()
  349. {
  350. _playEvent.Set();
  351. lock (_videoReaderLocker)
  352. {
  353. if (_videoReader != null)
  354. {
  355. _videoReader.Close();
  356. _videoReader.Dispose();
  357. _videoReader = null;
  358. }
  359. }
  360. if (_videoCapture != null)
  361. {
  362. _videoCapture.NewFrame -= OnVideoCaptureNewFrame;
  363. _videoCapture.SignalToStop();
  364. _videoCapture = null;
  365. }
  366. }
  367. /// <summary>
  368. /// 有结果更新
  369. /// </summary>
  370. /// <param name="sender"></param>
  371. /// <param name="e"></param>
  372. private void OnCameraDatasUpdate(object sender, CameraDataUpdateEventArgs e)
  373. {
  374. //// 更新显示耗时
  375. string totalTime = string.Empty;
  376. string organSegTime = string.Empty;
  377. totalTime = e.UpdateCameraImageData.CameraProcessTime.ToString();
  378. Dispatcher.Invoke(() =>
  379. {
  380. TextCameraProcessTime.Text = totalTime;
  381. });
  382. int strTime = Environment.TickCount;
  383. _cameraImageReceiveCount += 1;
  384. var imgColor = e.UpdateCameraImageData.ImageColor;
  385. var PCLData = e.UpdateCameraImageData.PCLData;
  386. var bitmapRGB = RawImageShowUtils.RawImageToBitmap(imgColor.Clone());
  387. // 更新界面上显示的图片
  388. MyImageCanvas.UpdateRGBImage(bitmapRGB);
  389. imgColor.Dispose();
  390. PCLData.Dispose();
  391. bitmapRGB.Dispose();
  392. int useTime = Environment.TickCount - strTime;
  393. }
  394. /// <summary>
  395. /// 有log要记
  396. /// </summary>
  397. /// <param name="sender"></param>
  398. /// <param name="e"></param>
  399. private void OnLogWrite(object sender, LogEventArgs e)
  400. {
  401. switch (e.LogType)
  402. {
  403. case EnumLogType.InfoLog:
  404. LogHelper.InfoLog(e.Msg, string.Empty);
  405. break;
  406. case EnumLogType.WarnLog:
  407. LogHelper.WarnLog(e.Msg, string.Empty);
  408. break;
  409. case EnumLogType.ErrorLog:
  410. LogHelper.ErrorLog(e.Msg, string.Empty);
  411. break;
  412. case EnumLogType.FatalLog:
  413. LogHelper.FatalLog(e.Msg, string.Empty);
  414. break;
  415. }
  416. }
  417. /// <summary>
  418. /// 有错误发生
  419. /// </summary>
  420. /// <param name="sender"></param>
  421. /// <param name="e"></param>
  422. private void OnErrorOccur(object sender, ErrorEventArgs e)
  423. {
  424. MessageBox.Show("发生错误:" + e.GetException());
  425. }
  426. /// <summary>
  427. /// 设置相机参数
  428. /// </summary>
  429. /// <param name="cameraType"></param>
  430. private void SetCameraPara(EnumCameraType cameraType)
  431. {
  432. switch (cameraType)
  433. {
  434. case EnumCameraType.CameraMonocular:
  435. _cameraInfo.ImageWidth = 640;
  436. _cameraInfo.ImageHeight = 480;
  437. _cameraInfo.CameraIntrinsicParas = new StructCameraMatrix[1];
  438. _cameraInfo.CameraIntrinsicParas[0] = new StructCameraMatrix { Fx = 968.7391609376731f, Cx = 287.327201924683f, Fy = 973.0819774437676f, Cy = 228.3629053369949f };
  439. _cameraInfo.CameraDistortionParas = new StructDistortionCoeffs[1];
  440. _cameraInfo.CameraDistortionParas[0] = new StructDistortionCoeffs
  441. {
  442. K1 = -0.1423318502459511f,
  443. K2 = 0.9421222939220543f,
  444. P1 = -0.00623928181067679f,
  445. P2 = -0.0001133860088364576f,
  446. K3 = -1.764144824643008f
  447. };
  448. //_cameraPara = new CameraPara(_cameraInfo.CameraType, _cameraInfo.CameraIntrinsicParas, _cameraInfo.CameraDistortionParas);
  449. break;
  450. case EnumCameraType.CameraStereo:
  451. _cameraInfo.ImageWidth = 640;
  452. _cameraInfo.ImageHeight = 480;
  453. _cameraInfo.CameraIntrinsicParas = new StructCameraMatrix[2];
  454. _cameraInfo.CameraDistortionParas = new StructDistortionCoeffs[2];
  455. _cameraInfo.CameraIntrinsicParas[0] = new StructCameraMatrix { Fx = 418.20295986882917f, Cx = 331.58936826262072f, Fy = 416.81959360159908f, Cy = 237.67218546829204f };
  456. _cameraInfo.CameraDistortionParas[0] = new StructDistortionCoeffs
  457. {
  458. K1 = -0.054219464530630361f,
  459. K2 = 0.34091210469992994f,
  460. P1 = -0.0015726118762586696f,
  461. P2 = -0.0044293500195294868f,
  462. K3 = -0.54448581741567326f
  463. };
  464. _cameraInfo.CameraIntrinsicParas[1] = new StructCameraMatrix { Fx = 415.80928115541127f, Cx = 317.71374656324372f, Fy = 415.03444466070465f, Cy = 241.40091921800106f };
  465. _cameraInfo.CameraDistortionParas[1] = new StructDistortionCoeffs
  466. {
  467. K1 = -0.10663788123585277f,
  468. K2 = 0.52465203680907246f,
  469. P1 = -0.0035902534296184912f,
  470. P2 = -0.0031625627870525645f,
  471. K3 = -0.81617126606653123f
  472. };
  473. _cameraInfo.CameraExteriorPara = new StructCamExternalParam
  474. {
  475. RVec1 = 0.0032517163600536804f,
  476. RVec2 = -0.014466251153525995f,
  477. RVec3 = -0.0020912953401341617f,
  478. TVec1 = -120.19263575225523f,
  479. TVec2 = 0.37262915065413843f,
  480. TVec3 = -0.41720831397963321f
  481. };
  482. //_cameraPara = new CameraPara(_cameraInfo.CameraType, _cameraInfo.CameraIntrinsicParas, _cameraInfo.CameraDistortionParas);
  483. break;
  484. case EnumCameraType.CameraRealSense435:
  485. _cameraInfo.ImageWidth = 848;
  486. _cameraInfo.ImageHeight = 480;
  487. _cameraInfo.CameraIntrinsicParas = new StructCameraMatrix[1];
  488. _cameraInfo.CameraIntrinsicParas[0] = new StructCameraMatrix { Fx = 603.784f, Cx = 324.581f, Fy = 602.461f, Cy = 253.871f };
  489. _cameraInfo.CameraDistortionParas = new StructDistortionCoeffs[1];
  490. _cameraInfo.CameraDistortionParas[0] = new StructDistortionCoeffs
  491. {
  492. K1 = 0.0f,
  493. K2 = 0.0f,
  494. P1 = 0.0f,
  495. P2 = 0.0f,
  496. K3 = 0.0f
  497. };
  498. //_cameraPara = new CameraPara(_cameraInfo.CameraType, _cameraInfo.CameraIntrinsicParas, _cameraInfo.CameraDistortionParas);
  499. break;
  500. case EnumCameraType.CameraZhiSensor:
  501. _cameraInfo.ImageWidth = 1280;
  502. _cameraInfo.ImageHeight = 720;
  503. _cameraInfo.CameraIntrinsicParas = new StructCameraMatrix[1];
  504. _cameraInfo.CameraIntrinsicParas[0] = new StructCameraMatrix { Fx = 957.37f, Cx = 660.29f, Fy = 950.03f, Cy = 479.29f };
  505. _cameraInfo.CameraDistortionParas = new StructDistortionCoeffs[1];
  506. _cameraInfo.CameraDistortionParas[0] = new StructDistortionCoeffs
  507. {
  508. K1 = 0.06723f,
  509. K2 = -0.06952f,
  510. P1 = -2.49e-03f,
  511. P2 = 1.24e-03f,
  512. K3 = 0.0f
  513. };
  514. //_cameraPara = new CameraPara(_cameraInfo.CameraType, _cameraInfo.CameraIntrinsicParas, _cameraInfo.CameraDistortionParas);
  515. break;
  516. }
  517. }
  518. private unsafe Bitmap BytesToBmp(byte[] bmpBytes, Size imageSize)
  519. {
  520. Bitmap bmp = new Bitmap(imageSize.Width, imageSize.Height);
  521. BitmapData bData = bmp.LockBits(new Rectangle(0, 0, imageSize.Width, imageSize.Height),
  522. ImageLockMode.ReadWrite,
  523. PixelFormat.Format48bppRgb);
  524. // Copy the bytes to the bitmap object
  525. Marshal.Copy(bmpBytes, 0, bData.Scan0, bmpBytes.Length);
  526. bmp.UnlockBits(bData);
  527. return bmp;
  528. }
  529. #endregion
  530. }
  531. }