当前位置:   article > 正文

【opencv】教程代码 —video(1) 对象追踪

【opencv】教程代码 —video(1) 对象追踪

CamShift算法、MeanShift追踪算法来追踪视频中的一个目标

  1. camshift.cpp CamShift算法

d51b48a7669b92e019bd2da22a42a82d.png

90fae2165e3fcf0f90138f745c9da3c8.png

9603051895892a58938b263df76c9a9b.png

  1. // 引入相关的头文件
  2. #include <iostream> // 包含C++的输入输出流库
  3. #include <opencv2/imgcodecs.hpp> // OpenCV图像编解码功能
  4. #include <opencv2/imgproc.hpp> // OpenCV图像处理功能
  5. #include <opencv2/videoio.hpp> // OpenCV视频I/O操作
  6. #include <opencv2/highgui.hpp> // OpenCV高级GUI功能
  7. #include <opencv2/video.hpp> // OpenCV视频处理功能
  8. // 使用命名空间,简化代码中的命名
  9. using namespace cv; // OpenCV命名空间
  10. using namespace std; // 标准命名空间
  11. // 主函数
  12. int main(int argc, char **argv)
  13. {
  14. // 关于程序的说明字符串
  15. const string about =
  16. "This sample demonstrates the camshift algorithm.\n"
  17. "The example file can be downloaded from:\n"
  18. " https://www.bogotobogo.com/python/OpenCV_Python/images/mean_shift_tracking/slow_traffic_small.mp4";
  19. // 命令行参数的说明字符串
  20. const string keys =
  21. "{ h help | | print this help message }"
  22. "{ @image |<none>| path to image file }";
  23. // 解析命令行参数
  24. CommandLineParser parser(argc, argv, keys);
  25. parser.about(about);
  26. // 如果命令行中包含帮助参数,则输出帮助信息并退出程序
  27. if (parser.has("help"))
  28. {
  29. parser.printMessage();
  30. return 0;
  31. }
  32. // 获取图像文件路径
  33. string filename = parser.get<string>("@image");
  34. // 检查参数解析是否成功
  35. if (!parser.check())
  36. {
  37. parser.printErrors();
  38. return 0;
  39. }
  40. // 打开视频文件
  41. VideoCapture capture(filename);
  42. // 检查视频是否成功打开
  43. if (!capture.isOpened()){
  44. // 打开失败时打印错误信息并退出程序
  45. cerr << "Unable to open file!" << endl;
  46. return 0;
  47. }
  48. // 声明一些变量用于处理图像
  49. Mat frame, roi, hsv_roi, mask;
  50. // 读取视频的第一帧
  51. capture >> frame;
  52. // 设置跟踪窗口的初始位置 // 这里硬编码了窗口的值
  53. Rect track_window(300, 200, 100, 50);
  54. // 设置追踪的区域
  55. roi = frame(track_window);
  56. // 将感兴趣区域(ROI)的颜色空间转换为HSV
  57. cvtColor(roi, hsv_roi, COLOR_BGR2HSV);
  58. // 过滤HSV图像中的某些颜色区域,并生成遮罩图像
  59. inRange(hsv_roi, Scalar(0, 60, 32), Scalar(180, 255, 255), mask);
  60. // 直方图的参数设置
  61. float range_[] = {0, 180};
  62. const float* range[] = {range_};
  63. Mat roi_hist;
  64. int histSize[] = {180};
  65. int channels[] = {0};
  66. // 计算HSV图像的直方图
  67. calcHist(&hsv_roi, 1, channels, mask, roi_hist, 1, histSize, range);
  68. // 标准化直方图
  69. normalize(roi_hist, roi_hist, 0, 255, NORM_MINMAX);
  70. // 设置迭代的终止条件,要么是迭代10次,要么至少移动1pt
  71. TermCriteria term_crit(TermCriteria::EPS | TermCriteria::COUNT, 10, 1);
  72. // 循环处理视频帧
  73. while(true){
  74. Mat hsv, dst;
  75. // 读取一帧图像
  76. capture >> frame;
  77. // 如果读取到空帧,则退出循环
  78. if (frame.empty())
  79. break;
  80. // 将图像从BGR转换到HSV色彩空间
  81. cvtColor(frame, hsv, COLOR_BGR2HSV);
  82. // 计算反向投影
  83. calcBackProject(&hsv, 1, channels, roi_hist, dst, range);
  84. // 应用camshift算法获取新的窗口位置
  85. RotatedRect rot_rect = CamShift(dst, track_window, term_crit);
  86. // 在图像上绘制旋转矩形
  87. Point2f points[4];
  88. rot_rect.points(points);
  89. for (int i = 0; i < 4; i++)
  90. line(frame, points[i], points[(i+1)%4], 255, 2);
  91. // 显示图像
  92. imshow("img2", frame);
  93. // 处理键盘输入
  94. int keyboard = waitKey(30);
  95. // 如果按下'q'或Esc键,则退出循环
  96. if (keyboard == 'q' || keyboard == 27)
  97. break;
  98. }
  99. }

这段C++代码使用OpenCV库实现了一个CamShift算法演示程序,用于视频中的对象跟踪。程序首先通过命令行参数获取一个视频文件的路径,然后打开这个视频,设置一个追踪窗口,并计算出该窗口内图像的HSV色彩空间直方图。在一个循环中,程序不断地读取视频帧,计算直方图的反向投影,并利用CamShift算法更新追踪窗口的位置,最后将更新后的位置用椭圆形状绘制在视频帧上,并显示处理后的视频帧。程序允许用户通过按键退出追踪循环。

inRange(hsv_roi, Scalar(0, 60, 32), Scalar(180, 255, 255), mask);

e8a05d0fc950fffc8906a0bf87025aec.png

calcHist(&hsv_roi, 1, channels, mask, roi_hist, 1, histSize, range);

47010e0085199420fcee231875a2586c.png

calcBackProject(&hsv, 1, channels, roi_hist, dst, range);

3a601f31e89e1148449dccf059116b51.png

2. meanshift.cpp MeanShift追踪算法来追踪视频中的一个目标

238f9e894dbc12f05742fa310ab03256.png

  1. #include <iostream> // 引入标准输入输出流库
  2. #include <opencv2/imgcodecs.hpp> // 引入OpenCV图像编解码库
  3. #include <opencv2/imgproc.hpp> // 引入OpenCV图像处理库
  4. #include <opencv2/videoio.hpp> // 引入OpenCV视频输入输出库
  5. #include <opencv2/highgui.hpp> // 引入OpenCV高层GUI库
  6. #include <opencv2/video.hpp> // 引入OpenCV视频分析库
  7. using namespace cv; // 使用OpenCV命名空间
  8. using namespace std; // 使用标准命名空间
  9. // 主程序入口点
  10. int main(int argc, char **argv)
  11. {
  12. // 关于本示例的简介
  13. const string about =
  14. "This sample demonstrates the meanshift algorithm.\n"
  15. "The example file can be downloaded from:\n"
  16. " https://www.bogotobogo.com/python/OpenCV_Python/images/mean_shift_tracking/slow_traffic_small.mp4";
  17. // 命令行参数解析时使用的关键字
  18. const string keys =
  19. "{ h help | | print this help message }"
  20. "{ @image |<none>| path to image file }";
  21. CommandLineParser parser(argc, argv, keys); // 创建命令行解析器
  22. parser.about(about); // 设置关于信息
  23. if (parser.has("help")) // 如果命令行参数中有help
  24. {
  25. parser.printMessage(); // 打印帮助信息
  26. return 0; // 退出程序
  27. }
  28. string filename = parser.get<string>("@image"); // 获取图像文件的路径
  29. if (!parser.check()) // 检查命令行参数
  30. {
  31. parser.printErrors(); // 打印错误
  32. return 0; // 退出程序
  33. }
  34. VideoCapture capture(filename); // 创建视频捕获对象
  35. if (!capture.isOpened()){ // 检查是否成功打开视频文件
  36. cerr << "Unable to open file!" << endl; // 打印无法打开文件的错误信息
  37. return 0; // 退出程序
  38. }
  39. Mat frame, roi, hsv_roi, mask; // 定义矩阵变量:帧,感兴趣区域,HSV色彩空间的感兴趣区域,掩码
  40. capture >> frame; // 读取视频的第一帧
  41. // 设置追踪窗口的初始位置
  42. Rect track_window(300, 200, 100, 50); // 硬编码窗口的值
  43. // 设置追踪的ROI
  44. roi = frame(track_window); // 选取感兴趣区域
  45. cvtColor(roi, hsv_roi, COLOR_BGR2HSV); // 将感兴趣区域转换为HSV色彩空间
  46. inRange(hsv_roi, Scalar(0, 60, 32), Scalar(180, 255, 255), mask); // 对HSV空间进行颜色范围限定
  47. float range_[] = {0, 180}; // 定义直方图的范围
  48. const float* range[] = {range_}; // 设置直方图的范围
  49. Mat roi_hist; // 定义感兴趣区域的直方图
  50. int histSize[] = {180}; // 定义直方图的大小
  51. int channels[] = {0}; // 定义使用的通道
  52. calcHist(&hsv_roi, 1, channels, mask, roi_hist, 1, histSize, range); // 计算直方图
  53. normalize(roi_hist, roi_hist, 0, 255, NORM_MINMAX); // 归一化直方图
  54. // 设置终止条件,迭代10次或至少移动1个点
  55. TermCriteria term_crit(TermCriteria::EPS | TermCriteria::COUNT, 10, 1); // 创建终止条件
  56. while(true){ // 循环进行追踪
  57. Mat hsv, dst; // 定义矩阵变量:HSV色彩空间图像,目标图像
  58. capture >> frame; // 读取视频帧
  59. if (frame.empty()) // 如果帧为空则跳出循环
  60. break;
  61. cvtColor(frame, hsv, COLOR_BGR2HSV); // 将帧转换为HSV色彩空间
  62. calcBackProject(&hsv, 1, channels, roi_hist, dst, range); // 计算反向投影
  63. // 应用meanshift算法获取新的位置
  64. meanShift(dst, track_window, term_crit);
  65. // 在图像上绘制追踪窗口
  66. rectangle(frame, track_window, 255, 2);
  67. imshow("img2", frame); // 显示窗口
  68. int keyboard = waitKey(30); // 等待键盘输入
  69. if (keyboard == 'q' || keyboard == 27) // 如果输入'q'或Esc则退出循环
  70. break;
  71. }
  72. }

该代码使用C++和OpenCV库实现了MeanShift追踪算法来追踪视频中的一个目标。程序首先解析命令行参数来获取视频文件路径,然后使用OpenCV的视频捕获功能来读取视频。它设置了一个初始追踪窗口,计算该窗口中的颜色直方图,并使用归一化处理。接着,程序进入一个循环,在循环中通过MeanShift算法更新追踪窗口的位置,并在视频帧中显示结果。用户可以按'q'或Esc键来退出视频追踪。

a945ea779bd39747990c5f5971dc98d3.png

57d27656f735840b8ac096527eb6193b.png

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/391041
推荐阅读
相关标签
  

闽ICP备14008679号