¿Cuál es la mejor forma (en c/C++) para rotar un IplImage/cv :: Mat 90 grados? Asumiría que debe haber algo mejor que transformarlo usando una matriz, pero parece que no puedo encontrar nada más que eso en la API y en línea.¿La manera más fácil de girar 90 grados una imagen usando OpenCV?
Respuesta
A partir de OpenCV3.2, la vida acaba de recibir un poco más fácil, ahora se puede girar una imagen en una sola línea de código:
cv::rotate(image, image, ROTATE_90_CLOCKWISE);
Para la dirección en la que puede elegir cualquiera de los siguientes:
ROTATE_90_CLOCKWISE
ROTATE_180
ROTATE_90_COUNTERCLOCKWISE
actualización de transposición:
Debe utilizar cvTranspose()
o cv::transpose()
porque (como bien ha señalado) es más eficiente. De nuevo, recomiendo actualizar a OpenCV2.0 ya que la mayoría de las funciones de cvXXX
solo convierten estructuras IplImage*
en objetos Mat
(sin copias de fondo). Si almacenó la imagen en un objeto Mat
, Mat.t()
devolverá la transposición.
Cualquier rotación:
que puedes usar cvWarpAffine mediante la definición de la matriz de rotación en el marco general de la matriz de transformación. Recomiendo encarecidamente actualizar a OpenCV2.0 que tiene varias características, así como una clase Mat
que encapsula matrices e imágenes. Con 2.0 puede usar warpAffine a lo anterior.
Gracias! ¿Estás seguro de que no es menos eficiente que simplemente transponer la matriz de píxeles? La cuestión es que no estaba seguro de si OpenCV incluso representa internamente la imagen como una matriz de píxeles, es decir, algo así como un int * de 32 bits, y si lo hizo, cómo obtener un puntero a esa matriz. –
Lo siento, no leí su pregunta correctamente, he actualizado mi respuesta. – Jacob
La transposición debe ir seguida de un giro (cvFlip) para girar correctamente la imagen – Amnon
Bueno, estaba buscando algunos detalles y no encontré ningún ejemplo. Así que estoy publicando una función transposeImage
que, espero, ayudará a otras personas que están buscando una manera directa para girar 90 ° y sin perder los datos:
IplImage* transposeImage(IplImage* image) {
IplImage *rotated = cvCreateImage(cvSize(image->height,image->width),
IPL_DEPTH_8U,image->nChannels);
CvPoint2D32f center;
float center_val = (float)((image->width)-1)/2;
center.x = center_val;
center.y = center_val;
CvMat *mapMatrix = cvCreateMat(2, 3, CV_32FC1);
cv2DRotationMatrix(center, 90, 1.0, mapMatrix);
cvWarpAffine(image, rotated, mapMatrix,
CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS,
cvScalarAll(0));
cvReleaseMat(&mapMatrix);
return rotated;
}
Pregunta: ¿Por qué esto?
float center_val = (float)((image->width)-1)/2;
Respuesta: Porque funciona :) El único centro que encontré que no traduce la imagen. Aunque si alguien tiene una explicación, me interesaría.
La razón de sus cálculos probablemente se deba a una división entera. Lo que quiere hacer es: float center_val = (float) image-> width/2.0f. –
Tenga en cuenta que el método cvTranspose + cvFlip es un poco más rápido si solo necesita rotación en incrementos de 90 grados. –
La rotación es una composición de una transposición y una voltereta.
Qué en OpenCV puede ser escrito como esto (ejemplo Python a continuación):
img = cv.LoadImage("path_to_image.jpg")
timg = cv.CreateImage((img.height,img.width), img.depth, img.channels) # transposed image
# rotate counter-clockwise
cv.Transpose(img,timg)
cv.Flip(timg,timg,flipMode=0)
cv.SaveImage("rotated_counter_clockwise.jpg", timg)
# rotate clockwise
cv.Transpose(img,timg)
cv.Flip(timg,timg,flipMode=1)
cv.SaveImage("rotated_clockwise.jpg", timg)
vea mi 'cv2' a continuación: http://stackoverflow.com/questions/2259678/easiest-way-to-rotate-by-90-degrees-an-image-using-opencv/42359233#42359233 –
Volteando verticalmente (flipMode = 0) debe ser un poco más caro que voltear horizontalmente, porque está utilizando mejor el caché. Por lo tanto, la rotación en el sentido contrario a las agujas del reloj debería ser algo más rápida haciendo primero un giro horizontal, y luego la transposición. –
Este es un ejemplo sin la nueva interfaz de C++ (funciona para 90, 180 y 270 grados, usando param = 1, 2 y 3). Recuerde llamar al cvReleaseImage
en la imagen devuelta después de usarla.
IplImage *rotate_image(IplImage *image, int _90_degrees_steps_anti_clockwise)
{
IplImage *rotated;
if(_90_degrees_steps_anti_clockwise != 2)
rotated = cvCreateImage(cvSize(image->height, image->width), image->depth, image->nChannels);
else
rotated = cvCloneImage(image);
if(_90_degrees_steps_anti_clockwise != 2)
cvTranspose(image, rotated);
if(_90_degrees_steps_anti_clockwise == 3)
cvFlip(rotated, NULL, 1);
else if(_90_degrees_steps_anti_clockwise == 1)
cvFlip(rotated, NULL, 0);
else if(_90_degrees_steps_anti_clockwise == 2)
cvFlip(rotated, NULL, -1);
return rotated;
}
Aquí es mi EmguCV (AC# puerto de OpenCV) solución:
public static Image<TColor, TDepth> Rotate90<TColor, TDepth>(this Image<TColor, TDepth> img)
where TColor : struct, IColor
where TDepth : new()
{
var rot = new Image<TColor, TDepth>(img.Height, img.Width);
CvInvoke.cvTranspose(img.Ptr, rot.Ptr);
rot._Flip(FLIP.HORIZONTAL);
return rot;
}
public static Image<TColor, TDepth> Rotate180<TColor, TDepth>(this Image<TColor, TDepth> img)
where TColor : struct, IColor
where TDepth : new()
{
var rot = img.CopyBlank();
rot = img.Flip(FLIP.VERTICAL);
rot._Flip(FLIP.HORIZONTAL);
return rot;
}
public static void _Rotate180<TColor, TDepth>(this Image<TColor, TDepth> img)
where TColor : struct, IColor
where TDepth : new()
{
img._Flip(FLIP.VERTICAL);
img._Flip(FLIP.HORIZONTAL);
}
public static Image<TColor, TDepth> Rotate270<TColor, TDepth>(this Image<TColor, TDepth> img)
where TColor : struct, IColor
where TDepth : new()
{
var rot = new Image<TColor, TDepth>(img.Height, img.Width);
CvInvoke.cvTranspose(img.Ptr, rot.Ptr);
rot._Flip(FLIP.VERTICAL);
return rot;
}
no debería ser demasiado difícil de traducir de nuevo en C++.
Aquí es mi pitón cv2
aplicación:
import cv2
img=cv2.imread("path_to_image.jpg")
# rotate ccw
out=cv2.transpose(img)
out=cv2.flip(out,flipCode=0)
# rotate cw
out=cv2.transpose(img)
out=cv2.flip(out,flipCode=1)
cv2.imwrite("rotated.jpg", out)
su código ccw transforma a la cw. – Jason
corregido. Gracias @Jason! –
- 1. Girar una imagen usando css
- 2. Lossless JPEG ¿Girar (90/180/270 grados) en Java?
- 3. Imagen numpy - girar la matriz 270 grados
- 4. Writeablebitmap.SaveJpeg está girando mi imagen -90 grados
- 5. Android - ¿Hay alguna manera de girar un pan tostado 90 grados?
- 6. Cómo rotar una imagen 90 grados en iOS?
- 7. Girar una sola página 90 grados con iTextSharp/VB en un PDF de varias páginas existente
- 8. Rotar una matriz bidimensional en 90 grados
- 9. Rotar un mapa de bits 90 grados
- 10. ¿Manera cruzada del navegador para girar la imagen usando CSS?
- 11. ¿Girando un CALayer 90 grados?
- 12. ¿Hay una manera rápida y fácil en OpenCV para calcular el gradiente de una imagen?
- 13. "Girar" un IEnumerable <IEnumerable <T>> 90 grados
- 14. Girar una página 180 grados en LaTeX
- 15. Girar cara en la imagen
- 16. UIImagePNGR ¿Problemas con la presentación?/Imágenes giradas 90 grados
- 17. Android get Orientación de una cámara Bitmap? Y gire hacia atrás -90 grados
- 18. Zxing - Cambio de la vista de la cámara -90 grados
- 19. Cómo rotar TextView 90 grados y mostrar
- 20. Girar imagen matemáticas (C#)
- 21. restar una imagen de otra usando openCV
- 22. Comparando la imagen en cuántos grados inclinados
- 23. ¿Cómo rotar una matriz N x N en 90 grados?
- 24. Cargando una imagen usando OpenCV en Android
- 25. ¿Cómo rotar la imagen mediante programación en 90 grados en iPhone?
- 26. Android gira mapa de bits 90 grados resultados en imagen aplastada. Necesita una verdadera rotación entre vertical y horizontal
- 27. Girar una imagen en java
- 28. ¿Cómo puedo girar un png transparente en 45 grados usando imagemagick y mantener la nueva imagen transparente?
- 29. La forma más fácil de rotar un rectángulo
- 30. ¿La manera más fácil de reemplazar una cadena usando un diccionario de reemplazos?
respuesta El C++ es [aquí] (http://stackoverflow.com/a/16278334/2436175). – Antonio