J'écris un programme qui dessine une ligne sur une vidéo où se rencontrent les premiers pixels de la balustrade, mon problème est que la lecture vidéo est lente.

entrez la description de l'image ici Capture d'écran pour référence à quoi ressemble la vidéo. Pendant la vidéo, la caméra s'est rapprochée mais à cause de la vitesse lente, je dois attendre quelques minutes pour voir le changement, mais lorsque le tournage a eu lieu, elle a été déplacée toutes les quelques secondes.

Je suppose que le problème est le fait que les boucles for fonctionnent sur chaque image de la vidéo, mais je ne suis pas sûr.

Quelle solution pourrais-je mettre en place pour accélérer mon programme?

import cv2

cap = cv2.VideoCapture('video.mp4')

while(cap.isOpened()):

    ret, frame = cap.read()
    canny = cv2.Canny(frame, 85, 255)
    height, width = canny.shape

    first_black_array = []

    for x in range(width):
        first_black_pixel_found = 0
        for y in range(height):
            if first_black_pixel_found == 0:
                if canny[y,x] == 255:
                    first_black_array.append(height - y)
                    first_black_pixel_found = 1
                    cv2.line(frame,(x,y),(x,y),(0,255,0),1)

    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

Merci!

5
Gentem 14 mars 2019 à 19:10

2 réponses

Meilleure réponse

C'est le problème...

for x in range(width):
    for y in range(height):
         if canny[y,x] == 255:

Numpy.argmax est la solution ...

for x in range(width-1):
    # Slice the relevant column from the image
    # The image 'column' is a tall skinny image, only 1px thick
    column = np.array(canny[:,x:x+1])
    # Use numpy to find the first non-zero value
    railPoint = np.argmax(column)

Code complet:

import cv2, numpy as np, time
# Get start time
start = time.time()
# Read in the image
img = cv2.imread('/home/stephen/Desktop/rail.jpg')[40:,10:-10]
# Canny filter
canny = cv2.Canny(img, 85, 255)
# Get height and width
height, width = canny.shape
# Create list to store rail points
railPoints = []
# Iterate though each column in the image
for position in range(width-1):
    # Slice the relevant column from the image
    # The image 'column' is a tall skinny image, only 1px thick
    column = np.array(canny[:,position:position+1])
    # Use numpy to find the first non-zero value
    railPoint = np.argmax(column)
    # Add the railPoint to the list of rail points
    railPoints.append(railPoint)
    # Draw a circle on the image
    cv2.circle(img, (position, railPoint), 1, (123,234,123), 2)
cv2.imshow('img', img)                      
k = cv2.waitKey(1)
cv2.destroyAllWindows()
print(time.time() - start)

Ma solution utilisant Numpy a pris 6 ms et votre solution a pris 266 ms. sortie ferroviaire

1
Stephen Meschke 15 mars 2019 à 16:42

Une autre amélioration potentielle pourrait être de placer l'opération de capture de trame dans un thread séparé. Étant donné que cv2.VideoCapture().read() est une opération de blocage, votre programme subit une latence d'E / S lors de l'interrogation d'une nouvelle trame. Actuellement, le thread principal interroge une trame, puis la traite dans un ordre séquentiel . En dédiant un thread complètement différent uniquement pour les cadres d'interrogation et en vous concentrant uniquement sur le traitement des cadres, vous pouvez effectuer votre tâche en parallèle .

0
nathancy 14 mars 2019 à 19:49