python-opencv 目标追踪,多目标追踪(需要opencv扩展模块,C++,python)

提起目标跟踪,大家可能会想起的就是camshift,但是camshift跟踪往往达不到我们的跟踪要求,包括稳定性和准确性。

opencv3.1版本发行后,集成了多个跟踪算法,但需要扩展模块,即tracker,大部分都是近年VOT竞赛榜上有名的算法,虽然仍有缺陷存在,但效果还不错。
下面我提供C++ 版本和python版本,大家自行测试

#include <opencv2/opencv.hpp>
#include <opencv2/video.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/tracking/tracker.hpp>

using namespace cv;

void draw_rectangle(int event, int x, int y, int flags, void*);
Mat firstFrame;
Point previousPoint, currentPoint;
Rect2d bbox;
int main(int argc, char *argv[])
{
    VideoCapture capture;
    Mat frame;
    //frame = capture.open("/home/xiaorun/moving-object-detection/1.mp4");
      frame=capture.open(0);
    if(!capture.isOpened())
    {
        printf("can not open ...\n");
        return -1;
    }
    //获取视频的第一帧,并框选目标
    capture.read(firstFrame);
    if(!firstFrame.empty())
    {
        namedWindow("output", WINDOW_AUTOSIZE);
        imshow("output", firstFrame);
        setMouseCallback("output", draw_rectangle, 0);
        waitKey();
    }
    //使用TrackerMIL跟踪
    //Ptr<TrackerMIL> tracker= TrackerMIL::create();
    //Ptr<TrackerTLD> tracker= TrackerTLD::create();
    // Ptr<TrackerKCF> tracker = TrackerKCF::create();
    // Ptr<TrackerMedianFlow> tracker = TrackerMedianFlow::create();
      Ptr<TrackerBoosting> tracker= TrackerBoosting::create();
    capture.read(frame);
    tracker->init(frame,bbox);
    namedWindow("output", WINDOW_AUTOSIZE);
    while (capture.read(frame))
    {
        tracker->update(frame,bbox);
        rectangle(frame,bbox, Scalar(255, 0, 0), 2, 1);
        imshow("output", frame);
        if(waitKey(20)=='q')
        return 0;
    }
    capture.release();
    destroyWindow("output");
    return 0;
}

//框选目标
void draw_rectangle(int event, int x, int y, int flags, void*)
{
    if (event == EVENT_LBUTTONDOWN)
    {
        previousPoint = Point(x, y);
    }
    else if (event == EVENT_MOUSEMOVE && (flags&EVENT_FLAG_LBUTTON))
    {
        Mat tmp;
        firstFrame.copyTo(tmp);
        currentPoint = Point(x, y);
        rectangle(tmp, previousPoint, currentPoint, Scalar(0, 255, 0, 0), 1, 8, 0);
        imshow("output", tmp);
    }
    else if (event == EVENT_LBUTTONUP)
    {
        bbox.x = previousPoint.x;
        bbox.y = previousPoint.y;
        bbox.width = abs(previousPoint.x-currentPoint.x);
        bbox.height =  abs(previousPoint.y-currentPoint.y);
    }
    else if (event == EVENT_RBUTTONUP)
    {
        destroyWindow("output");
    }
}

python版本测试

import cv2
import sys

(major_ver, minor_ver, subminor_ver) = (cv2.__version__).split('.')

if __name__ == '__main__' :

    # Set up tracker.
    # Instead of MIL, you can also use

    tracker_types = ['BOOSTING', 'MIL','KCF', 'TLD', 'MEDIANFLOW', 'GOTURN', 'MOSSE']
    tracker_type = tracker_types[2]

    if int(minor_ver) < 3:
        tracker = cv2.Tracker_create(tracker_type)
    else:
        if tracker_type == 'BOOSTING':
            tracker = cv2.TrackerBoosting_create()
        if tracker_type == 'MIL':
            tracker = cv2.TrackerMIL_create()
        if tracker_type == 'KCF':
            tracker = cv2.TrackerKCF_create()
        if tracker_type == 'TLD':
            tracker = cv2.TrackerTLD_create()
        if tracker_type == 'MEDIANFLOW':
            tracker = cv2.TrackerMedianFlow_create()
        if tracker_type == 'GOTURN':
            tracker = cv2.TrackerGOTURN_create()
        if tracker_type == 'MOSSE':
            tracker = cv2.TrackerMOSSE_create()

    # Read video
    video = cv2.VideoCapture("videos/chaplin.mp4")

    # Exit if video not opened.
    if not video.isOpened():
        print "Could not open video"
        sys.exit()

    # Read first frame.
    ok, frame = video.read()
    if not ok:
        print 'Cannot read video file'
        sys.exit()

    # Define an initial bounding box
    bbox = (287, 23, 86, 320)

    # Uncomment the line below to select a different bounding box
    bbox = cv2.selectROI(frame, False)

    # Initialize tracker with first frame and bounding box
    ok = tracker.init(frame, bbox)

    while True:
        # Read a new frame
        ok, frame = video.read()
        if not ok:
            break

        # Start timer
        timer = cv2.getTickCount()

        # Update tracker
        ok, bbox = tracker.update(frame)

        # Calculate Frames per second (FPS)
        fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer);

        # Draw bounding box
        if ok:
            # Tracking success
            p1 = (int(bbox[0]), int(bbox[1]))
            p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
            cv2.rectangle(frame, p1, p2, (255,0,0), 2, 1)
        else :
            # Tracking failure
            cv2.putText(frame, "Tracking failure detected", (100,80), cv2.FONT_HERSHEY_SIMPLEX, 0.75,(0,0,255),2)

        # Display tracker type on frame
        cv2.putText(frame, tracker_type + " Tracker", (100,20), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50,170,50),2);

        # Display FPS on frame
        cv2.putText(frame, "FPS : " + str(int(fps)), (100,50), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50,170,50), 2);

        # Display result
        cv2.imshow("Tracking", frame)

        # Exit if ESC pressed
        k = cv2.waitKey(1) & 0xff
        if k == 27 : break

多目标追踪
多目标跟踪使用的是MultiTracker,如MultiTracker myTracker(“KCF”),注意两点,添加目标用其成员函数myTracker.add(Mat src, Rect2d roi),获得跟踪结果使用myTracker.update(Mat src, vector targets),跟踪结果的序号即vector的序号。

import numpy as np
import cv2
import sys
'''
if len(sys.argv) != 2:
    print('Input video name is missing')
    exit()
'''

print('Select 3 tracking targets') 

cv2.namedWindow("tracking")
camera = cv2.VideoCapture(0)
tracker = cv2.MultiTracker_create()
init_once = False

ok, image=camera.read()
if not ok:
    print('Failed to read video')
    exit()

bbox1 = cv2.selectROI('tracking', image)
bbox2 = cv2.selectROI('tracking', image)
bbox3 = cv2.selectROI('tracking', image)

while camera.isOpened():
    ok, image=camera.read()
    if not ok:
        print 'no image to read'
        break

    if not init_once:
        ok = tracker.add(cv2.TrackerMIL_create(), image, bbox1)
        ok = tracker.add(cv2.TrackerMIL_create(), image, bbox2)
        ok = tracker.add(cv2.TrackerMIL_create(), image, bbox3)
        init_once = True

    ok, boxes = tracker.update(image)
    print ok, boxes

    for newbox in boxes:
        p1 = (int(newbox[0]), int(newbox[1]))
        p2 = (int(newbox[0] + newbox[2]), int(newbox[1] + newbox[3]))
        cv2.rectangle(image, p1, p2, (200,0,0))

    cv2.imshow('tracking', image)
    k = cv2.waitKey(1)
    if k == 27 : break # esc pressed

猜你喜欢

转载自blog.csdn.net/xiao__run/article/details/81084209
今日推荐