2012-05-11 46 views
5

¿Cómo rotar todos los marcos en una secuencia de video usando OpenCV? Intenté usar el código proporcionado en un similar question, pero no parece funcionar con el objeto de imagen Iplimage devuelto cv.RetrieveFrame.Cómo rotar un video con OpenCV

Este es el código que tengo actualmente:

import cv, cv2 
import numpy as np 

def rotateImage(image, angle): 
    if hasattr(image, 'shape'): 
     image_center = tuple(np.array(image.shape)/2) 
     shape = image.shape 
    elif hasattr(image, 'width') and hasattr(image, 'height'): 
     image_center = (image.width/2, image.height/2) 
     shape = np.array((image.width, image.height)) 
    else: 
     raise Exception, 'Unable to acquire dimensions of image for type %s.' % (type(image),) 
    rot_mat = cv2.getRotationMatrix2D(image_center, angle,1.0) 
    result = cv2.warpAffine(image, rot_mat, shape, flags=cv2.INTER_LINEAR) 
    return result 

cap = cv.CaptureFromCAM(cam_index) 
#cap = cv.CaptureFromFile(path) 
fps = 24 
width = int(cv.GetCaptureProperty(cap, cv.CV_CAP_PROP_FRAME_WIDTH)) 
height = int(cv.GetCaptureProperty(cap, cv.CV_CAP_PROP_FRAME_HEIGHT)) 

fourcc = cv.CV_FOURCC('P','I','M','1') #is a MPEG-1 codec 

writer = cv.CreateVideoWriter('out.avi', fourcc, fps, (width, height), 1) 
max_i = 90 
for i in xrange(max_i): 
    print i,max_i 
    cv.GrabFrame(cap) 
    frame = cv.RetrieveFrame(cap) 
    frame = rotateImage(frame, 180) 
    cv.WriteFrame(writer, frame) 

Pero esto sólo da el error:

File "test.py", line 43, in <module> 
    frame = rotateImage(frame, 180) 
    File "test_record_room.py", line 26, in rotateImage 
    result = cv2.warpAffine(image, rot_mat, shape, flags=cv2.INTER_LINEAR) 
TypeError: <unknown> is not a numpy array 

Presumiblemente porque warpAffine toma una CvMat y no un Iplimage. De acuerdo con el C++ cheatsheet, la conversión entre los dos es trivial, pero no puedo encontrar ninguna documentación sobre cómo hacer el equivalente en Python. ¿Cómo convierto Iplimage a Mat en Python?

Respuesta

10

Si son sólo después de una rotación de 180 grados, puede utilizar Flip en ambos ejes,

reemplazar:

frame = rotateImage(frame, 180) 

con:

cv.Flip(frame, flipMode=-1) 

Esto es ' in place ', así que es rápido, y ya no necesitará su función rotateImage :)

Ejemplo:

import cv 
orig = cv.LoadImage("rot.png") 
cv.Flip(orig, flipMode=-1) 
cv.ShowImage('180_rotation', orig) 
cv.WaitKey(0) 

esto: enter image description here convierte, esto: enter image description here

2

No necesita usar warpAffine(), eche un vistazo a transpose() y flip().

This post demuestra cómo rotar una imagen 90 grados.

2

A través de prueba y error finalmente descubrí la solución.

import cv, cv2 
import numpy as np 

def rotateImage(image, angle): 
    image0 = image 
    if hasattr(image, 'shape'): 
     image_center = tuple(np.array(image.shape)/2) 
     shape = tuple(image.shape) 
    elif hasattr(image, 'width') and hasattr(image, 'height'): 
     image_center = tuple(np.array((image.width/2, image.height/2))) 
     shape = (image.width, image.height) 
    else: 
     raise Exception, 'Unable to acquire dimensions of image for type %s.' % (type(image),) 
    rot_mat = cv2.getRotationMatrix2D(image_center, angle,1.0) 
    image = np.asarray(image[:,:]) 

    rotated_image = cv2.warpAffine(image, rot_mat, shape, flags=cv2.INTER_LINEAR) 

    # Copy the rotated data back into the original image object. 
    cv.SetData(image0, rotated_image.tostring()) 

    return image0 
Cuestiones relacionadas