视频中的多个跟踪

5 c++ opencv feature-detection

我正在进行小型图像处理任务,我需要跟踪4个红色对象.我有如何跟踪单一的.我想知道跟踪多个点的最佳方法是什么.

有4个点定位形成一个矩形,所以我可以使用形状检测或角点检测来检测和跟踪点请参见下图.

在此输入图像描述

And*_*dov 6

以下是我在GitHub上的实现:https://github.com/Smorodov/Multitarget-tracker video on youube:http://www.youtube.com/watch?v = 2fW5TmAtAXM & list = UUhlR5ON5Uqhi_3RXRu-pdVw

简而言之:

  1. 检测对象.该步骤提供一组点(检测到的对象坐标).
  2. 解决分配问题(矩形匈牙利算法).此步骤将检测到的对象分配给现有轨道.
  3. 管理未分配/丢失的曲目.此步骤删除连续丢失检测数太多的曲目,并为新检测添加曲目.
  4. 对每个轨道应用统计滤波器(在这种情况下为卡尔曼滤波器),用于使用对象物体动力学信息(在卡尔曼滤波器矩阵中定义)预测丢失的检测和平滑轨迹.

顺便说一句,要获得4个点的坐标,你需要知道3个点的坐标,因为你的模式是矩形的,你可以计算出第4个点.


kar*_*lip 4

我的简单实现使用OpenCV 边界框中描述的技术来跟踪红色斑点。

以下是用于检索检测到的所有红色对象的中心的辅助函数:

/* get_positions: a function to retrieve the center of the detected blobs.
 * largely based on OpenCV's "Creating Bounding boxes and circles for contours" tutorial.
 */
std::vector<cv::Point2f> get_positions(cv::Mat& image)
{
    if (image.channels() > 1)
    {
        std::cout << "get_positions: !!! Input image must have a single channel" << std::endl;
        return std::vector<cv::Point2f>();
    }

    std::vector<std::vector<cv::Point> > contours;
    cv::findContours(image, contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);

    // Approximate contours to polygons and then get the center of the objects
    std::vector<std::vector<cv::Point> > contours_poly(contours.size());
    std::vector<cv::Point2f> center(contours.size());
    std::vector<float> radius(contours.size());
    for (unsigned int i = 0; i < contours.size(); i++ )
    {
        cv::approxPolyDP(cv::Mat(contours[i]), contours_poly[i], 5, true );
        cv::minEnclosingCircle((cv::Mat)contours_poly[i], center[i], radius[i]);
    }

    return center;
}   
Run Code Online (Sandbox Code Playgroud)

我编写了代码,通过从网络摄像头捕获帧来实时测试我的方法。整个过程与@Dennis 描述的非常相似(抱歉,当你提交答案时我已经在编码了)。

好的,这就是乐趣真正开始的地方。

int main()
{
    // Open the capture device. My webcam ID is 0:
    cv::VideoCapture cap(0);
    if (!cap.isOpened())
    {
        std::cout << "!!! Failed to open webcam" << std::endl;
        return -1;
    }

    // Let's create a few window titles for debugging purposes
    std::string wnd1 = "Input", wnd2 = "Red Objs", wnd3 = "Output";   

    // These are the HSV values used later to isolate RED-ish colors
    int low_h = 160, low_s = 140, low_v = 50;
    int high_h = 179, high_s = 255, high_v = 255;

    cv::Mat frame, hsv_frame, red_objs;
    while (true)
    {
        // Retrieve a new frame from the camera
        if (!cap.read(frame))
            break;

        cv::Mat orig_frame = frame.clone();
        cv::imshow(wnd1, orig_frame);
Run Code Online (Sandbox Code Playgroud)

orig_frame:

在此输入图像描述

        // Convert BGR frame to HSV to be easier to separate the colors
        cv::cvtColor(frame, hsv_frame, CV_BGR2HSV);

        // Isolate red colored objects and save them in a binary image
        cv::inRange(hsv_frame,
                    cv::Scalar(low_h,  low_s,  low_v),
                    cv::Scalar(high_h, high_s, high_v),
                    red_objs);

        // Remove really small objects (mostly noises)
        cv::erode(red_objs, red_objs, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)));
        cv::dilate(red_objs, red_objs, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(7, 7)));

        cv::Mat objs = red_objs.clone();
        cv::imshow(wnd2, objs);
Run Code Online (Sandbox Code Playgroud)

objs:

在此输入图像描述

        // Retrieve a vector of points with the (x,y) location of the objects
        std::vector<cv::Point2f> points = get_positions(objs);

        // Draw a small green circle at those locations for educational purposes
        for (unsigned int i = 0; i < points.size(); i++)
            cv::circle(frame, points[i], 3, cv::Scalar(0, 255, 0), -1, 8, 0);

        cv::imshow(wnd3, frame);
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

        char key = cv::waitKey(33);
        if (key == 27) {   /* ESC was pressed */
            //cv::imwrite("out1.png", orig_frame);
            //cv::imwrite("out2.png", red_objs);
            //cv::imwrite("out3.png", frame);
            break;
        }
    }

    cap.release();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)