OpenCV: Optischer Fluss

Django, Flask, Bottle, WSGI, CGI…
Antworten
kiesmo
User
Beiträge: 7
Registriert: Freitag 12. Januar 2018, 21:34

Hallo liebe User,

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)
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:

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()
Würde mich auf eine Antwort sehr freuen.
Lg
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Hast du schonmal systematisch mit den Parametern gespielt?

Ansonsten kannst du natuerlich SIFT-Featuren mit den ueblichen Dingen wie FLANN zuordnen, in C++ zu sehen hier: https://docs.opencv.org/3.4/d5/d6f/tuto ... tcher.html

Oder du schaust dir mal den Code fuer den optischen Fluss an, und programmierst das dann mit anderen Features nach.
kiesmo
User
Beiträge: 7
Registriert: Freitag 12. Januar 2018, 21:34

__deets__ hat geschrieben: Mittwoch 19. Juni 2019, 13:30 Hast du schonmal systematisch mit den Parametern gespielt?

Ansonsten kannst du natuerlich SIFT-Featuren mit den ueblichen Dingen wie FLANN zuordnen, in C++ zu sehen hier: https://docs.opencv.org/3.4/d5/d6f/tuto ... tcher.html

Oder du schaust dir mal den Code fuer den optischen Fluss an, und programmierst das dann mit anderen Features nach.

Hi,

danke für deine Antwort.
Ja, habe mit den Parametern gespielt, aber das liefert mir nicht das gewünschte Ergebnis.

Ich weiss nicht wie ich die gematchten sift-features der cv.calcOpticalFlowPyrLK-Methode übergeben muss.
Etwa so?

Code: Alles auswählen

p1, st, err = cv.calcOpticalFlowPyrLK(prev_gray, next_gray, prev_des, next_des, **lk_params) 
Ich verstehe dann aber nicht was mir die Methode in p1 liefert als Ergebnis und wie ich dann den flow darstellen kann! :/
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich denke nicht, dass das geht. Das ist ja nur ein initialer seed, an dem dann der Lukas-Kanade seine eigenen Features festmacht & verfolgt. Sonst koennte/muesste man da ja verschiedene Strategien fuer Features reingeben koennen etc.

Deshalb mein anderer Vorschlag, sich per SIFT/FLANN selbst den Fluss zu erarbeiten.
kiesmo
User
Beiträge: 7
Registriert: Freitag 12. Januar 2018, 21:34

__deets__ hat geschrieben: Mittwoch 19. Juni 2019, 15:04 Ich denke nicht, dass das geht. Das ist ja nur ein initialer seed, an dem dann der Lukas-Kanade seine eigenen Features festmacht & verfolgt. Sonst koennte/muesste man da ja verschiedene Strategien fuer Features reingeben koennen etc.

Deshalb mein anderer Vorschlag, sich per SIFT/FLANN selbst den Fluss zu erarbeiten.
Macht sinn. Habe mit SIFT die features erfasst, mit FLANN die Korrespondenz gefunden, wie kann ich jetzt den Fluss berechnen?

Lg
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Indem du dir mal den Lukas-Kanade Algorithmus anschaust, und was der da macht. Nur das du es eben mit deinem Korrespondieren Features machst.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ganz doof: A - A' ist dein optischer Fluss, wenn A die neue Position ist, und A' die davor. Viel mehr ist das ja nicht.
Antworten