Nous allons procéder avec le contenu suivant --Lors de l'utilisation du flux optique --Problèmes d'utilisation de 1 Je ne trouve pas les points caractéristiques où je veux --Solution 1 --Problèmes d'utilisation de 2 Lost si vous vous déplacez rapidement
le flux optique est une technologie qui détecte et suit les parties caractéristiques d'une image. C'est une technologie très utile, mais lorsque vous l'essayez, vous rencontrez divers problèmes. J'écrirai ici que c'était un peu gênant pour moi à utiliser. En particulier, nous vous présenterons comment trouver les points caractéristiques et que faire si vous les perdez.
S'il y a un endroit caractéristique parce qu'il s'agit d'une méthode pour trouver une partie caractéristique de l'image, l'endroit que vous voulez vraiment peut ne pas être caractérisé. Un exemple est un éclairage puissant.
Laissez la personne spécifier d'abord l'emplacement du point caractéristique et suivez-le. Par exemple, si vous découpez une partie de l'image comme le code source suivant et détectez les points caractéristiques de l'image, elle aura l'air bien. Un exemple d'algorithme est présenté ci-dessous.
Lorsqu'un point caractéristique était détecté comme celui-ci, il était suivi même s'il y avait un fort éclairage dans la vidéo. La source est indiquée ci-dessous, mais comme le code est uniquement extrait, une sorte d'erreur se produira s'il est laissé tel quel.
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()
#Fin du jugement
if( Movieframe is None):
return None
#Enregistrer l'image actuelle
self.nowMovieFrame = Movieframe
#Détection de flux optique
#Découpez une vidéo avec un rectangle avec une largeur et une hauteur spécifiées autour de la position du point caractéristique précédent, ici la hauteur du rectangle spécifié en premier. C'est la même que la largeur
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))))
#Sélectionnez les points caractéristiques pour lesquels un flux optique a été détecté (0: non détecté, 1: détecté)
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
#Se préparer au prochain flux optique
self.grayPrev = self.grayNext.copy()
self.featurePrev = goodNext.reshape(-1, 1, 2)
#Renvoie 1 en cas de succès
return 1
Si le mouvement est lent, le flux optique le suivra bien, mais si le mouvement est aussi rapide que possible, les points caractéristiques seront perdus. À propos, il peut y avoir une opinion selon laquelle "Si vous vous déplacez rapidement parce que vous avez spécifié la plage dans la solution 1, l'endroit avec le point caractéristique sortira de la plage et vous perdrez de vue le point caractéristique", mais l'état dans lequel vous ne spécifiez pas la plage Cependant, le phénomène de perte de vue des points caractéristiques a été observé.
En guise de contre-mesure, il existe un moyen d'augmenter le fps autant que possible lors de l'enregistrement d'une vidéo. Cependant, il y a souvent des choses financièrement impossibles. Cette fois, si je perdais de vue les points caractéristiques, je devais arrêter la vidéo et recommencer à partir de la spécification de la plage. Il appelle la fonction nextFrame du code source ci-dessus, met en pause la lecture de la vidéo lorsque 0 est renvoyé, appelle featureMouseClicked et extractFeatures, spécifie à nouveau la plage et lit la vidéo. Peut-être pourrais-je faire plus en générant des images intermédiaires et en augmentant les images par seconde, mais je n'avais pas le pouvoir d'implémenter autant.
opencv 2.4.13 python 2.7.11
Recommended Posts