search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

fanfuhan OpenCV 教學084 ~ opencv-084-視頻分析(移動對象的KLT光流跟踪/5偵測算法) – jashliao部落格

fanfuhan OpenCV 教學084 ~ opencv-084-視頻分析(移動對象的KLT光流跟踪/5偵測算法)

資料來源: https://fanfuhan.github.io/

https://fanfuhan.github.io/2019/04/26/opencv-084/

GITHUB:https://github.com/jash-git/fanfuhan_ML_OpenCV


光流跟踪方法分為密集密實光流跟踪與稀疏光流跟踪算法,KLT是稀疏光流跟踪算法,這個算法最初是由Bruce D. Lucas和Takeo Kanade兩位作者提出來的,所以又被稱為KLT 。

稀疏光流算法工作有三個假設前提條件:
  ◎亮度恆定
  ◎短距離移動
  ◎空間一致性


C++

#include 
#include 

using namespace std;
using namespace cv;

vector featurePoints;
RNG rng(12345);

/*
 * 视频分析(移动对象的KLT光流跟踪算法)
 */
int main() {
    VideoCapture capture("../images/vtest.avi");
    if (!capture.isOpened()) {
        cout << "could not open video..." << endl;
        return -1;
    }

    // 角点检测参数
    double qualityLevel = 0.01;
    int minDistance = 10;
    int maxCorners = 100;

    // KLT光流跟踪参数
    vector pts[2];
    vector status;
    vector err;

    // 读取第一帧及其角点
    Mat old_frame, old_gray;
    capture.read(old_frame);
    cvtColor(old_frame, old_gray, COLOR_BGR2GRAY);
    goodFeaturesToTrack(old_gray, featurePoints, maxCorners,
                        qualityLevel, minDistance, Mat());

    pts[0].insert(pts[0].end(), featurePoints.begin(), featurePoints.end());
    int width = capture.get(CAP_PROP_FRAME_WIDTH);
    int height = capture.get(CAP_PROP_FRAME_HEIGHT);
    Rect roi(0, 0, width, height);

    Mat gray, frame;

    while (true) {
        bool ret = capture.read(frame);
        if (!ret) break;
        imshow("frame", frame);
        roi.x = 0;
        cvtColor(frame, gray, COLOR_BGR2GRAY);

        // 计算光流
        calcOpticalFlowPyrLK(old_gray, gray, pts[0], pts[1],
                             status, err, Size(31, 31));
        size_t i, k;
        for (int i = k = 0; i < pts[1].size(); ++i) {
            // 根据状态选择
            if (status[i]){
                pts[0][k] = pts[0][i];
                pts[1][k++] = pts[1][i];
                int b = rng.uniform(0, 256);
                int g = rng.uniform(0, 256);
                int r = rng.uniform(0, 256);
                Scalar color(b, g, r);
                // 绘制跟踪线
                circle(frame, pts[1][i], 4, color, -1);
                line(frame, pts[0][i], pts[1][i], color, 2);
            }
        }

        // resize 有用特征点
        pts[0].resize(k);
        pts[1].resize(k);
        imshow("result", frame);
        roi.x = width;
        char c = waitKey(50);
        if (c == 27) break;

        // 更新old
        std::swap(pts[1], pts[0]);
        cv::swap(old_gray, gray);
    }

    return 0;
}


Python

import numpy as np
import cv2 as cv
cap = cv.VideoCapture('D:/images/video/vtest.avi')

# 角点检测参数
feature_params = dict(maxCorners=100, qualityLevel=0.01, minDistance=10, blockSize=3)

# KLT光流参数
lk_params = dict(winSize=(31, 31), maxLevel=3, criteria=(cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 30, 0.01))

# 随机颜色
color = np.random.randint(0,255,(100,3))

# 读取第一帧
ret, old_frame = cap.read()
old_gray = cv.cvtColor(old_frame, cv.COLOR_BGR2GRAY)
p0 = cv.goodFeaturesToTrack(old_gray, mask=None, **feature_params)

# 光流跟踪
while True:
    ret, frame = cap.read()
    if ret is False:
        break
    frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    # 计算光流
    p1, st, err = cv.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)
    # 根据状态选择
    good_new = p1[st == 1]
    good_old = p0[st == 1]

    # 绘制跟踪线
    for i, (new, old) in enumerate(zip(good_new,good_old)):
        a,b = new.ravel()
        c,d = old.ravel()
        frame = cv.line(frame, (a,b),(c,d), color[i].tolist(), 2)
        frame = cv.circle(frame,(a,b),5,color[i].tolist(),-1)
    cv.imshow('frame',frame)
    k = cv.waitKey(30) & 0xff
    if k == 27:
        break

    # 更新
    old_gray = frame_gray.copy()
    p0 = good_new.reshape(-1, 1, 2)

cv.destroyAllWindows()
cap.release()


熱門推薦

本文由 jashliaoeuwordpress 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦