OpenCV: Optischer Fluss
Verfasst: Mittwoch 19. Juni 2019, 12:44
				
				Hallo liebe User,
ich suche eine Methode in OpenCV zur Berechnung des optischen Flusses.
OpenCv bietet folgenden Beispiellose an:
Dies funktioniert einwandfrei, allerdings kann ich das nicht für mein Projekt gebrauchen, da nicht genug 'Features' gefunden und getrackt werden.
Ausserdem besteht das Problem, dass bei schnelleren Bewegungen/Motion, die Punkte nicht mehr getrackt werden können.
Zudem werden hier "Eckpunkte" als Features genutzt.
Meine Frage:
Gibt es eine Möglichkeit den optischen Fluss für schnellere Bewegungen zu berechnen oder für Sift-Features?
Mein Code soweit:
Würde mich auf eine Antwort sehr freuen. 
Lg
			ich suche eine Methode in OpenCV zur Berechnung des optischen Flusses.
OpenCv bietet folgenden Beispiellose an:
Code: Alles auswählen
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)Ausserdem besteht das Problem, dass bei schnelleren Bewegungen/Motion, die Punkte nicht mehr getrackt werden können.
Zudem werden hier "Eckpunkte" als Features genutzt.
Meine Frage:
Gibt es eine Möglichkeit den optischen Fluss für schnellere Bewegungen zu berechnen oder für Sift-Features?
Mein Code soweit:
Code: Alles auswählen
import cv2 as cv
import numpy as np
cap = cv.VideoCapture(0)
sift = cv.xfeatures2d.SIFT_create()
bf = cv.BFMatcher()
# Parameters for lucas kanade optical flow
lk_params = dict( winSize  = (15,15),
			maxLevel = 2,
			criteria = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 0.03))
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])
		
		#hier müsste ich irgendwie den optischen Fluss der gefundenen features in zwei aufeinanderfolgenden frames berechnen
		#wie kann ich den optischen Fluss anhand sift features berechnen?
		#p1, st, err = cv.calcOpticalFlowPyrLK(prev_gray, next_gray, prev_des, next_des, **lk_params)
		
		
		
		prev_kp = next_kp
		prev_des = next_des
		prev_gray = next_gray
		cv.waitKey(1)
if __name__ == '__main__':
	main()Lg