El proyecto: agregue un sello de fecha / hora en cada fotogtwig de un video. (El resultado de la cámara de video digital y mi padre me preguntaron cómo puede agregar la marca de tiempo (a la resolución de milisegundos) permanentemente al video.
Un amigo me señaló a opencv (emgucv en realidad), y debido a mis preferencias probé mi suerte con opencv en python.
La documentación es escasa, e incluso me costó mucho (solo tardé unas 5 horas) en instalar el paquete. Fuentes:
Estoy trabajando en Windows 7 x64, así que tuve que degradar mi python para trabajar con numpy (no hay una versión numpy para win64)
Trabajando con PyCharm IDE.
La instalación resultante me permitió tener el archivo C: \ Python27 \ Lib \ site-packages \ cv2.pyd
Estoy intentando encontrar documentación para comenzar a trabajar, pero estoy muy confundido y no tengo idea de por dónde empezar, todos los ejemplos son confusos, es decir:
Mis preguntas:
Gracias
Su tarea debe ser relativamente fácil de realizar con OpenCV y Python. Parece que eres nuevo en OpenCV, así que trataré de mantener mi explicación a fondo, pero siéntete libre de preguntar si necesitas alguna claridad.
No estoy seguro de si está obteniendo sus datos de una fuente de video en vivo de la cámara, o si está procesando posteriormente las imágenes grabadas. De cualquier manera…
Obtener datos. Si utiliza un feed en vivo:
capture = cv2.VideoCapture(0)
Si utiliza material grabado:
capture = cv2.VideoCapture("your_reading_file.avi")
Inicializar video escritor. Mire esta pregunta para obtener ayuda con los códecs. Encontrar un códec que funcione no es trivial. También estoy usando Windows 7 x64, y el códec que se menciona a continuación fue el único que funcionó para mí. Además, establezca la variable fps
más cerca posible de la tasa de cuadros de video entrante real; no podrá cambiarla una vez que haya comenzado a escribir cuadros.
flag, frame = capture.read() # **EDIT:** to get frame size width = np.size(frame, 1) #here is why you need numpy! (remember to "import numpy as np") height = np.size(frame, 0) writer = cv2.VideoWriter(filename="your_writing_file.avi", fourcc=cv2.cv.CV_FOURCC('I', 'Y', 'U', 'V'), #this is the codec that works for me fps=15, #frames per second, I suggest 15 as a rough initial estimate frameSize=(width, height))
Procesa estos datos y añade tu texto. Por último, escriba el cuadro editado en un archivo de video.
while True: flag, frame = capture.read() #Flag returns 1 for success, 0 for failure. Frame is the currently processed frame if flag == 0: #Something is wrong with your data, or the end of the video file was reached break x = width/2 y = height/2 #change to the desired coordinates text_color = (255,0,0) #color as (B,G,R) cv2.putText(frame, "your_string", (x,y), cv2.FONT_HERSHEY_PLAIN, 1.0, text_color, thickness=1, lineType=cv2.CV_AA) writer.write(frame) #write to the video file
¡Tan sencillo como eso! Utilizo el código anterior para escribir texto en archivos de video casi a diario, por lo que definitivamente funciona. Los únicos problemas potenciales que puedo prever son los códecs, de los que lamentablemente no sé mucho. Espero que esto pueda resolver su problema, siéntase libre de hacer más preguntas.
EDITAR: Respuestas a las preguntas de tu comentario.
1.) Que yo sepa, solo puede usar .avi porque tiene que usar un formato sin comprimir con OpenCV. Me temo que no tengo conocimiento de usar otros formatos (comprimidos). ¿Tal vez podría usar un progtwig de terceros para realizar la conversión previa / posterior? El motivo de la excepción de frame
fue mi error, he editado la respuesta para incluir la línea que falta.
2.) Me temo que no tengo idea de cómo leer los metadatos. Si me entero te lo haré saber. Mi propia solución de pirateo para encontrar la tasa de cuadros del video es permitir que OpenCV ejecute el video una vez, usando el módulo Time
para calcular la tasa de cuadros promedio. Esta estimación se puede utilizar al escribir el archivo de video.
3.) He encontrado que el tamaño del video resultante puede diferir significativamente del original dependiendo de varios factores, el más importante es qué tan cerca estaban los fps
elegidos a la tasa de cuadros original real.
4.) En cuanto a otras fonts, hay varias disponibles. Puedo referirte a esta pregunta para una descripción general rápida. Aquí está la documentación relevante:
fontFace – Font type. One of FONT_HERSHEY_SIMPLEX, FONT_HERSHEY_PLAIN, FONT_HERSHEY_DUPLEX, FONT_HERSHEY_COMPLEX, FONT_HERSHEY_TRIPLEX, FONT_HERSHEY_COMPLEX_SMALL, FONT_HERSHEY_SCRIPT_SIMPLEX, or FONT_HERSHEY_SCRIPT_COMPLEX, where each of the font ID's can be combined with FONT_HERSHEY_ITALIC to get the slanted letters.
Usé hachoir-metadata para leer los metadatos del archivo de video (incluyendo velocidad de fotogtwigs, altura y ancho.
importador:
from hachoir_core.error import HachoirError from hachoir_core.cmd_line import unicodeFilename from hachoir_parser import createParser from hachoir_core.tools import makePrintable from hachoir_metadata import extractMetadata from hachoir_core.i18n import getTerminalCharset from hachoir_metadata.metadata_item import QUALITY_BEST
función:
def metaDataFile(filePath): filename, realname = unicodeFilename(filePath), filePath parser = createParser(filename, realname) try: metadata = extractMetadata(parser, QUALITY_BEST) except HachoirError, err: print "Metadata extraction error: %s" % unicode(err) metadata = None if not metadata: print metadata print "Unable to extract metadata" exit(1) return metadata
uso:
metadata = metaDataFile(videoPath) width = metadata.get('width') height = metadata.get('height') fps = metadata.get('frame_rate')
para ver las propiedades relevantes:
for data in sorted(metadata): if len(data.values ) > 0: print data.key, data.values[0].value