Wir werden mit den folgenden Inhalten fortfahren
Der optische Fluss ist eine Technologie, die charakteristische Teile eines Bildes erkennt und verfolgt. Es ist eine sehr nützliche Technologie, aber wenn Sie sie ausprobieren, treten verschiedene Probleme auf. Hier werde ich schreiben, dass es für mich etwas mühsam war, es zu benutzen. Insbesondere werden wir Ihnen vorstellen, wie Sie die Funktionspunkte finden und was zu tun ist, wenn Sie sie verlieren.
Wenn es einen charakteristischen Ort gibt, weil es eine Methode ist, einen charakteristischen Teil im Bild zu finden, wird der Ort, den Sie wirklich wollen, möglicherweise nicht charakterisiert. Ein Beispiel ist starke Beleuchtung.
Lassen Sie die Person zuerst die Position des Feature-Punkts angeben und ihm folgen. Wenn Sie beispielsweise einen Teil des Bildes wie den folgenden Quellcode ausschneiden und die Funktionspunkte des Bildes erkennen, sieht es gut aus. Ein Beispielalgorithmus ist unten gezeigt.
Wenn ein Feature-Punkt wie dieser erkannt wurde, wurde er auch dann verfolgt, wenn das Video stark beleuchtet war. Die Quelle wird unten gezeigt, aber da der Code nur extrahiert wird, tritt ein Fehler auf, wenn er unverändert bleibt.
def extractFeatures(self, gray, rect, features):
featureList = cv2.goodFeaturesToTrack(gray,100,0.01,10)
for feature in featureList:
if rect[0] <= feature[0][0] <= rect[2] and rect[1] <= feature[0][1] <= rect[3]:
features = self.addList(features, feature[0][0], feature[0][1])
return features
def featureMouseClicked(self, event, x, y, flags, param):
if event != cv2.EVENT_LBUTTONDOWN and event != cv2.EVENT_LBUTTONUP:
return
if event == cv2.EVENT_LBUTTONDOWN:
self.rect[0]=x
self.rect[1]=y
if event == cv2.EVENT_LBUTTONUP:
self.rect[2]=x
self.rect[3]=y
self.featureRectSet=True
def addList(self,lis,x,y):
if lis == None:
lis = np.array([[[x,y]]], np.float32)
else:
lis = np.append(lis, [[[x, y]]], axis = 0).astype(np.float32)
return lis
def cut(img,x,y,width,height):
ux=0
uy=0
dx=0
dy=0
if img is None:
return None,dy,uy,dx,ux
img_height, img_width = img.shape[:2]
if y+height/2 > img_height:
uy = img_height
else:
uy = y+height/2
if y-height/2 < 0:
dy = 0
else:
dy = y-height/2
if x+width/2 > img_width:
ux = img_width
else:
ux = x+width/2
if x-width/2 < 0:
dx = 0
else:
dx = x-width/2
if not(dx<ux and dy<uy):
return None,dy,uy,dx,ux
if not(0<=ux<=img_width or 0<=dx<=img_width or 0<=uy<=img_height or 0<=dy<=img_height):
return None,dy,uy,dx,ux
return img[dy:uy,dx:ux],dy,uy,dx,ux
def nextFrame(self):
end_flag, Movieframe = self.Moviecap.read()
#Urteil beenden
if( Movieframe is None):
return None
#Aktuellen Frame speichern
self.nowMovieFrame = Movieframe
#Optische Durchflusserkennung
#Schneiden Sie ein Video mit einem Rechteck aus Breite und Höhe aus, das um die Position des vorherigen Feature-Punkts angegeben ist. Hier wird zuerst die Höhe des Rechtecks angegeben. Es ist das gleiche wie die Breite
mask = np.zeros_like(Movieframe)
cutFrame,dy,uy,dx,ux= cut(Movieframe,
int(self.points[len(self.points)-1 - i][0]),#x
int(self.points[len(self.points)-1 - i][1]),#y
2*abs(self.rect[1]-self.rect[3]),2*abs(self.rect[0]-self.rect[2]))#
mask[dy:uy,dx:ux] = cutFrame
self.grayNext = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
self.featureNext, status, err = cv2.calcOpticalFlowPyrLK(self.grayPrev, self.grayNext, self.featurePrev, None,
(dict( winSize = (15,15),
maxLevel = 2,
criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))))
#Wählen Sie Merkmalspunkte aus, für die ein optischer Fluss erkannt wurde (0: nicht erkannt, 1: erkannt).
if status != None:
goodPrev = self.featurePrev[status == 1]
goodNext = self.featureNext[status == 1]
for i, (nextPoint, prevPoint) in enumerate(zip(goodNext, goodPrev)):
prev_x, prev_y = prevPoint.ravel()
next_x, next_y = nextPoint.ravel()
if self.featureNext is None:
return 0
#Vorbereitung für den nächsten optischen Fluss
self.grayPrev = self.grayNext.copy()
self.featurePrev = goodNext.reshape(-1, 1, 2)
#Gibt bei Erfolg 1 zurück
return 1
Wenn die Bewegung langsam ist, verfolgt der optische Fluss sie gut, aber wenn die Bewegung so schnell wie möglich ist, gehen die Merkmalspunkte verloren. Übrigens gibt es möglicherweise die Meinung, dass "Wenn Sie sich schnell bewegen, weil Sie den Bereich in Lösung 1 angegeben haben, die Stelle mit dem Feature-Punkt außerhalb des Bereichs liegt und Sie den Feature-Punkt aus den Augen verlieren", aber den Zustand, in dem Sie den Bereich nicht angeben Es wurde jedoch das Phänomen gesehen, die Merkmalspunkte aus den Augen zu verlieren.
Als Gegenmaßnahme gibt es eine Möglichkeit, die fps beim Aufnehmen eines Videos so weit wie möglich zu erhöhen. Es gibt jedoch oft finanziell unmögliche Dinge. Wenn ich diesmal die Funktionspunkte aus den Augen verlor, musste ich das Video stoppen und von der Bereichsspezifikation neu beginnen. Es ruft die nextFrame-Funktion des obigen Quellcodes auf, unterbricht die Wiedergabe des Videos, wenn 0 zurückgegeben wird, ruft featureMouseClicked und extractFeatures auf, gibt den Bereich erneut an und spielt das Video ab. Vielleicht könnte ich mehr tun, indem ich Zwischenframes generiere und fps erhöhe, aber ich hatte nicht die Kraft, so viel zu implementieren.
opencv 2.4.13 python 2.7.11
Recommended Posts