scikit - python image processing library
¿Cómo leer el video mp4 para ser procesado por scikit-image? (2)
Puede usar scikit-video , así:
from skvideo.io import VideoCapture
cap = VideoCapture(filename)
cap.open()
while True:
retval, image = cap.read()
# image is a numpy array containing the next frame
# do something with image here
if not retval:
break
Esto usa avconv o ffmpeg debajo del capó. El rendimiento es bastante bueno, con una pequeña sobrecarga para mover los datos a python en comparación con la simple decodificación del video en avconv.
La ventaja de scikit-video es que la API es exactamente la misma que la API de lectura / escritura de video de OpenCV; simplemente reemplace cv2.VideoCapture con skvideo.io.VideoCapture.
Me gustaría aplicar una función scikit-image
(específicamente la función de coincidencia de plantilla match_template
) a los marcos de un video mp4
, codificación h264
. Es importante que mi aplicación rastree la hora de cada fotograma, pero conozco la velocidad de fotogramas, por lo que puedo calcularla fácilmente a partir del número de fotograma.
Tenga en cuenta que me estoy ejecutando con pocos recursos, y me gustaría mantener las dependencias lo más escasas posible: numpy
es necesario de todos modos, y como estoy planeando usar scikit-image
, evitaría importar (y compilar) openCV
solo para leer el video
Veo en la parte inferior de esta página que scikit-image
puede procesar seamleassly video almacenado como una matriz numpy
, obteniendo que sería ideal.
El paquete Imageio python debe hacer lo que quiera. Aquí hay un fragmento de Python usando este paquete:
import pylab
import imageio
filename = ''/tmp/file.mp4''
vid = imageio.get_reader(filename, ''ffmpeg'')
nums = [10, 287]
for num in nums:
image = vid.get_data(num)
fig = pylab.figure()
fig.suptitle(''image #{}''.format(num), fontsize=20)
pylab.imshow(image)
pylab.show()
También puede iterar directamente sobre las imágenes en el archivo ( consulte la documentación ):
for i, im in enumerate(vid):
print(''Mean of frame %i is %1.1f'' % (i, im.mean()))
Para instalar imageio puedes usar pip:
pip install imageio
Otra solución sería usar Moviepy (que usa un código similar para leer video), pero creo que la imagen es más liviana y hace el trabajo.
respuesta al primer comentario
Para comprobar si la velocidad de fotogramas nominal es la misma en todo el archivo, puede contar el número de fotogramas en el iterador:
count = 0
try:
for _ in vid:
count += 1
except RuntimeError:
print(''something went wront in iterating, maybee wrong fps number'')
finally:
print(''number of frames counted {}, number of frames in metada {}''.format(count, vid.get_meta_data()[''nframes'']))
In [10]: something went wront in iterating, maybee wrong fps number
number of frames counted 454, number of frames in metada 461
Para mostrar la marca de tiempo de cada fotograma:
try:
for num, image in enumerate(vid.iter_data()):
if num % int(vid._meta[''fps'']):
continue
else:
fig = pylab.figure()
pylab.imshow(image)
timestamp = float(num)/ vid.get_meta_data()[''fps'']
print(timestamp)
fig.suptitle(''image #{}, timestamp={}''.format(num, timestamp), fontsize=20)
pylab.show()
except RuntimeError:
print(''something went wrong'')