如何使用 C++ 在 OpenCV 中追踪颜色?

opencvc++server side programmingprogramming

颜色追踪与颜色检测类似。为了实现追踪,我们额外添加了几条线来计算被检测物体的面积,然后追踪该区域的当前位置,最后使用 OpenCV 的 line() 函数显示物体的运动路径。

以下程序演示了如何使用 C++ 在 OpenCV 中追踪颜色。

示例

#include<iostream>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
   VideoCapture video_load(0);//从默认摄像头捕获视频//
   namedWindow("Adjust");//声明显示图像的窗口//
   int Hue_Low= 0;//色相下限//
   int Hue_high = 22;//色相上限//
   int Sat_Low =99;//饱和度下限//
   int Sat_high = 255;//饱和度上限//
   int Val_Low = 0;//数值下限//
   int Val_high = 255;//值的上限//
   createTrackbar(&"LowH";, &"Adjust";, &Hue_Low, 179);//最小色相的跟踪条//
   createTrackbar(&"HighH";, &"Adjust";, &Hue_high, 179);//最大色相的跟踪条//
   createTrackbar(&"LowS";, &"Adjust";, &Sat_Low, 255);//最小饱和度的跟踪条//
   createTrackbar(&"HighS";, &"Adjust";, &Sat_high, 255);// 最大饱和度的滑动条//
   createTrackbar(&"LowV";, &"Adjust";, &Val_Low,255);// 最小值滑动条//
   createTrackbar(&"HighV";, &"Adjust";, &Val_high, 255);// 最大值的滑动条//  
   int Horizo​​ntal_Last = -1;// 初始水平位置//
   int Vertical_Last = -1;// 初始垂直位置//
   Mat temp;//声明一个矩阵,用于从视频流加载帧//
   video_load.read(temp);//从视频流加载帧//
   Mat track_motion = Mat::zeros(temp.size(), CV_8UC3);//创建用于检测的黑色矩阵//
   while (true) {
      Mat actual_Image;//声明一个用于实际图像的矩阵//
      bool temp_load= video_load.read(actual_Image);//将视频中的帧加载到矩阵//
      Mat convert_to_HSV;//声明一个矩阵,用于存储转换后的图像//
      cvtColor(actual_Image, convert_to_HSV, COLOR_BGR2HSV);//将 BGR 图像转换为 HSV//
      Mat adjusted_frame;//声明检测到的颜色的矩阵//
      inRange(converted_to_HSV,Scalar(Hue_Low, Sat_Low, Val_Low),
      Scalar(Hue_high, Sat_high, Val_high), adjusted_frame);//应用轨迹条值的更改//        
      erode(adjusted_frame,adjusted_frame,getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));//形态学开运算,用于从前景中移除小物体//
      dilate(adjusted_frame, adjusted_frame,getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));//形态学开运算,用于从前景中移除小物体//
      dilate(adjusted_frame, adjusted_frame,getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));//形态学闭运算,用于填充前景中的小洞//
      erode(adjusted_frame, adjusted_frame, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));//形态学闭包填充前景小孔//
      Moments determining_object = moments(adjusted_frame);//根据检测到的彩色帧创建对象//
      double Vertical_moment = Detection_object.m01;//获取垂直位置值//
      double Horizo​​ntal_moment = Detection_object.m10;//获取水平位置值//
      double tracking_area = detecting_object.m00;//获取物体面积//
      if (tracking_area > 10000){ //当物体面积大于 10000 像素时//
         int posX = Horizo​​ntal_moment / Tracking_area;//计算物体的水平位置//
         int posY = Vertical_moment / Tracking_area;//计算物体的垂直位置//
         if (Horizo​​ntal_Last >= 0 && Vertical_Last >= 0 && posX >= 0 && posY >= 0){ //当检测到的物体移动时//
            line(track_motion, Point(posX, posY), Point(Horizo​​ntal_Last, Vertical_Last), Scalar(0, 0, 255), 2);//在检测到的物体运动的路径上绘制红色线条//
         }
           Horizo​​ntal_Last = posX;//获取新的水平位置//
         vertical_Last = posY;//获取新的垂直位置值//
      }
      imshow(&"Detected_Object", adjusted_frame);//显示检测到的物体//
      actual_Image = actual_Image + track_motion;//在原始视频帧中绘制连续线//
      imshow(&"Actual",actual_Image);//显示原始视频//
      cout << "position of the object is:" << Horizontal_Last << "," << vertical_Last << endl;//显示跟踪的坐标值//
if(waitKey(30)==27){//如果按下esc键,循环将中断//
         cout << "esc key is pressed by user" << endl;
         break;
      }
   }
   return 0;
}

输出


相关文章