Оптический поток на основе характеристик просеивания? - PullRequest
0 голосов
/ 18 июня 2019

У меня есть кусок кода, который вычисляет и рисует плотный оптический поток:

import cv2 as cv
import numpy as np

cap = cv.VideoCapture(0)

def getFrame():
    ret, img = cap.read()
    img = cv.resize(img,(640,480))
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    return gray

def draw_flow(img, flow, step=16):
    h, w = img.shape[:2]
    y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1).astype(int)
    fx, fy = flow[y,x].T
    lines = np.vstack([x, y, x+fx, y+fy]).T.reshape(-1, 2, 2)
    lines = np.int32(lines + 0.5)
    vis = cv.cvtColor(img, cv.COLOR_GRAY2BGR)
    cv.polylines(vis, lines, 0, (0, 255, 0))
    for (x1, y1), (_x2, _y2) in lines:
        cv.circle(vis, (x1, y1), 1, (0, 255, 0), -1)
    return vis

def main():
    prevgray = getFrame()
    while True:
        gray = getFrame()
        flow = cv.calcOpticalFlowFarneback(prevgray, gray, None, 0.5, 3, 15, 3, 10, 1.2, 0)
        prevgray = gray
        cv.imshow('flow', draw_flow(gray, flow))
        cv.waitKey(1)


if __name__ == '__main__':
    main()

Поскольку это занимает слишком много времени, у меня была идея вычислить элементы просеивания, сопоставить их и затем рассчитать оптический поток

До сих пор у меня есть это:


import cv2 as cv
import numpy as np

cap = cv.VideoCapture(0)
sift = cv.xfeatures2d.SIFT_create()
bf = cv.BFMatcher()

def getFrame():
    ret, img = cap.read()
    img = cv.resize(img,(640,480))
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    return gray

def main():
    prev_gray = getFrame()
    prev_kp, prev_des = sift.detectAndCompute(prev_gray,None)   
    while True:
        next_gray = getFrame()
        next_kp, next_des = sift.detectAndCompute(next_gray,None)
        matches = bf.knnMatch(prev_des, next_des, k=2)

        # Apply ratio test
        good = []
        for m,n in matches:
            if m.distance < 0.75*n.distance:
                good.append([m])

        #calc optical flow


        prev_kp = next_kp
        prev_des = next_des
        prev_gray = next_gray
        cv.waitKey(1)


if __name__ == '__main__':
    main()


Как рассчитать оптический поток элементов просеивания и нарисовать их с помощью функции drwa_flow в первом коде?

У меня также есть этот код:

import numpy as np
import cv2 as cv


lk_params = dict( winSize  = (15, 15),
                                    maxLevel = 2,
                                    criteria = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 0.03))

feature_params = dict( maxCorners = 500,
                                             qualityLevel = 0.3,
                                             minDistance = 7,
                                             blockSize = 7 )


track_len = 5
tracks = []
cam = cv.VideoCapture(0)


def getFrame():
    _ret, bgr = cam.read()
    bgr = cv.resize(bgr, (640,480))
    gray = cv.cvtColor(bgr, cv.COLOR_BGR2GRAY)
    return gray, bgr


while True:
    gray, vis = getFrame()

    if len(tracks) > 0:
            img0, img1 = prev_gray, gray
            p0 = np.float32([tr[-1] for tr in tracks]).reshape(-1, 1, 2)
            p1, _st, _err = cv.calcOpticalFlowPyrLK(img0, img1, p0, None, **lk_params)
            p0r, _st, _err = cv.calcOpticalFlowPyrLK(img1, img0, p1, None, **lk_params)

            d = abs(p0-p0r).reshape(-1, 2).max(-1)
            good = d < 1
            new_tracks = []
            for tr, (x, y), good_flag in zip(tracks, p1.reshape(-1, 2), good):
                    if not good_flag:
                            continue
                    tr.append((x, y))
                    if len(tr) > track_len:
                            del tr[0]
                    new_tracks.append(tr)
                    cv.circle(vis, (x, y), 2, (0, 255, 0), -1)
            tracks = new_tracks
            cv.polylines(vis, [np.int32(tr) for tr in tracks], False, (0, 255, 0))


    mask = np.zeros_like(gray)
    mask[:] = 255
    for x, y in [np.int32(tr[-1]) for tr in tracks]:
            cv.circle(mask, (x, y), 5, 0, -1)
    p = cv.goodFeaturesToTrack(gray, mask = mask, **feature_params)
    if p is not None:
            for x, y in np.float32(p).reshape(-1, 2):
                    tracks.append([(x, y)])

    prev_gray = gray
    cv.imshow('lk_track', vis)
    ch = cv.waitKey(1)

Но с этим кодом не использует функции просеивания, а также не рисует поток, как первый код ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...