CVideoCaptureWorker.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #include "../pch/pch.h"
  2. #include "CVideoCaptureWorker.h"
  3. //开始工作
  4. void CVideoCaptureWorker::Start()
  5. {
  6. m_is_work = true;
  7. //持续获取摄像头数据,直到程序退出,这里开启一个线程来处理摄像头数据的获取,避免阻塞主线程
  8. std::thread(&CVideoCaptureWorker::HandleVideoCapture, this).detach();
  9. }
  10. //停止工作
  11. void CVideoCaptureWorker::Stop()
  12. {
  13. m_is_work = false;
  14. }
  15. // 新增:自动检测可用摄像头索引
  16. int CVideoCaptureWorker::findAvailableCamera()
  17. {
  18. for (int i = 0; i < 10; i++)
  19. { // 检测前10个索引
  20. cv::VideoCapture tempCap(i, cv::CAP_DSHOW);
  21. if (tempCap.isOpened())
  22. {
  23. tempCap.release();
  24. return i;
  25. }
  26. }
  27. return -1;
  28. }
  29. void CVideoCaptureWorker::HandleVideoCapture()
  30. {
  31. int cameraIndex = findAvailableCamera();
  32. if (cameraIndex == -1)
  33. {
  34. DEBUG_LOG("未找到任何可用摄像头!");
  35. return;
  36. }
  37. cv::VideoCapture cap(cameraIndex, cv::CAP_DSHOW);
  38. if (!cap.isOpened())
  39. {
  40. CSystem::my_sleep(1);
  41. DEBUG_LOG("打开摄像头失败,正在重试...");
  42. return;
  43. }
  44. DEBUG_LOG("摄像头打开成功!");
  45. /*
  46. 160×120‌(QQVGA):适用于低带宽或嵌入式场景,资源占用极低
  47. ‌320×240‌(QVGA):轻量级视频传输常用,适合实时性要求高的应用
  48. ‌640×480‌(VGA):OpenCV 默认常用分辨率,兼容性强,广泛用于基础图像处理
  49. ‌800×600‌(SVGA):中等清晰度,适用于需要细节但不追求高清的场景
  50. ‌1024×768‌(XGA):较高清分辨率,适合文档扫描或静态图像采集
  51. ‌1280×720‌(720p HD):标准高清分辨率,广泛用于人脸识别、目标检测等视觉任务
  52. ‌1920×1080‌(1080p Full HD):全高清分辨率,提供高质量图像,适用于高精度视觉分析
  53. */
  54. int width = 1024;
  55. int height = 768;
  56. cap.set(cv::CAP_PROP_FRAME_WIDTH, width);
  57. cap.set(cv::CAP_PROP_FRAME_HEIGHT, height);
  58. // 验证设置是否成功
  59. double actualWidth = cap.get(cv::CAP_PROP_FRAME_WIDTH);
  60. double actualHeight = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
  61. std::cout << "设置的分辨率: " << width << " x " << height << std::endl;
  62. std::cout << "实际分辨率: " << actualWidth << " x " << actualHeight << std::endl;
  63. while (m_is_work == true)
  64. {
  65. m_worker_mutex.lock();
  66. // 读取摄像头帧
  67. cap >> m_frame;
  68. if (m_frame.empty())
  69. {
  70. m_worker_mutex.unlock();
  71. DEBUG_LOG("读取摄像头帧失败,正在重试...");
  72. CSystem::my_sleep(1);
  73. continue;
  74. }
  75. m_worker_mutex.unlock();
  76. Sleep(20);
  77. //什么都不用做,只需要把摄像头读取的帧放在成员变量里就行,后续其他地方需要用到摄像头数据的时候直接从成员变量里取就行了
  78. // 显示摄像头帧(可选)
  79. // cv::imshow("Camera", m_frame);
  80. // if (cv::waitKey(30) >= 0) break; // 按任意键退出
  81. }
  82. // ====================== 资源释放 ======================
  83. cap.release();
  84. cv::destroyAllWindows();
  85. return;
  86. }
  87. void CVideoCaptureWorker::GetFrame(cv::Mat& frame)
  88. {
  89. auto time_1 = std::chrono::high_resolution_clock::now();
  90. m_worker_mutex.lock();
  91. auto time_2 = std::chrono::high_resolution_clock::now();
  92. frame = m_frame.clone();
  93. m_worker_mutex.unlock();
  94. auto time_3 = std::chrono::high_resolution_clock::now();
  95. auto duration_1 = std::chrono::duration_cast<std::chrono::milliseconds>(time_2 - time_1);
  96. std::wstring msg = L"获得锁耗时: " + std::to_wstring(duration_1.count()) + L" 毫秒";
  97. DEBUG_LOG(msg.c_str());
  98. auto duration_2 = std::chrono::duration_cast<std::chrono::milliseconds>(time_3 - time_2);
  99. std::wstring msg2 = L"复制数据耗时: " + std::to_wstring(duration_2.count()) + L" 毫秒";
  100. DEBUG_LOG(msg2.c_str());
  101. int a = 1;
  102. }