type rotate copyto convertto clase c++ opencv matrix image-rotation

c++ - rotate - opencv mat type



Gire la matriz Opencv por 90, 180, 270 grados (4)

Esta pregunta ya tiene una respuesta aquí:

Estoy capturando la imagen de la cámara web y necesito rotarla en ángulo recto. Me encontré estas funciones:

  1. getRotationMatrix2D - para crear una matriz de rotación (cualquiera que sea)
  2. transform - transformar una matriz en otra por matriz de rotación

Pero, no obtengo nada más que área negra. Este es mi código:

if(rotate_button.click%4>0) { double angle = (rotate_button.click%4)*90; //button increments its click by 1 per click Mat transform_m = getRotationMatrix2D(Point(cam_frame_width/2, cam_frame_height/2), angle, 1); //Creating rotation matrix Mat current_frame; transform(cam_frame, current_frame, transform_m); //Transforming captured image into a new one cam_frame = Mat((int)current_frame.cols,(int)current_frame.rows, cam_frame_type) = Scalar(0,128,0); //resizing captured matrix, so I can copy the resized one on it current_frame.copyTo(cam_frame); //Copy resized to original }

Salidas solo pantalla en negro.


El código anterior funciona bien, pero introduce un error numérico en la imagen debido a que los cómputos de la matriz se realizan en coma flotante y la interpolación warpAffine.

Para una rotación de incrementos de 90 grados, prefiero usar lo siguiente (en python / opencv python)

Dado que las imágenes OpenCV en Python son 2d Numpy Arrays.

90 grados
theImage = numpy.rot90 (theImage, 1)
270 grados
theImage = numpy.rot90 (theImage, 3)

Nota: Solo probé esto en imágenes de forma gris (X, Y). Si tiene una imagen de color (u otra separación múltiple), es posible que deba reformarla primero para asegurarse de que la rotación funciona a lo largo del eje correcto.


La respuesta de @Abhishek Thakur solo funciona bien para girar la imagen 180 grados. No maneja la rotación en 90 grados porque

  • el centro de rotación suministrado a getRotationMatrix2D es incorrecto, y
  • el tamaño de la matriz de salida pasado a warpAffline es incorrecto.

Aquí está el código que gira una imagen 90 grados:

Mat src = imread("image.jpg"); Mat dst; double angle = 90; // or 270 Size src_sz = src.size(); Size dst_sz(src_sz.height, src_sz.width); int len = std::max(src.cols, src.rows); Point2f center(len/2., len/2.); Mat rot_mat = cv::getRotationMatrix2D(center, angle, 1.0); warpAffine(src, dst, rot_mat, dst_sz);

Editar: Otro enfoque para rotar imágenes en 90.180 o 270 grados implica hacer la transpose matriz y luego flip . Este método es probablemente más rápido.


Las respuestas anteriores son muy complejas y acaparan tu CPU. Su pregunta no fue una rotación arbitraria, sino ''Gire la matriz Opencv por 90, 180, 270 grados''.

ACTUALIZACIÓN 30 JUN 2017:

Esta funcionalidad es compatible con OpenCV, pero no está documentada: https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core.hpp#L1041

void rotate(InputArray src, OutputArray dst, int rotateCode);

con

enum RotateFlags { ROTATE_90_CLOCKWISE = 0, //Rotate 90 degrees clockwise ROTATE_180 = 1, //Rotate 180 degrees clockwise ROTATE_90_COUNTERCLOCKWISE = 2, //Rotate 270 degrees clockwise };

Respuesta original y rotación de grado arbitrario:

También puede hacer esto utilizando la operación de volteo y transposición, es decir, para 90CW:

transpose(matSRC, matROT); flip(matROT, matROT,1); //transpose+flip(1)=CW

etc. Calcula los otros comandos tú mismo (pensar = aprender) presentándote con la operación de transposición y volteo de los Documentos.

void rot90(cv::Mat &matImage, int rotflag){ //1=CW, 2=CCW, 3=180 if (rotflag == 1){ transpose(matImage, matImage); flip(matImage, matImage,1); //transpose+flip(1)=CW } else if (rotflag == 2) { transpose(matImage, matImage); flip(matImage, matImage,0); //transpose+flip(0)=CCW } else if (rotflag ==3){ flip(matImage, matImage,-1); //flip(-1)=180 } else if (rotflag != 0){ //if not 0,1,2,3: cout << "Unknown rotation flag(" << rotflag << ")" << endl; } }

Entonces lo llamas así y ten en cuenta que la matriz se pasa por referencia.

cv::Mat matImage; //Load in sensible data rot90(matImage,3); //Rotate it //Note if you want to keep an original unrotated version of // your matrix as well, just do this cv::Mat matImage; //Load in sensible data cv::Mat matRotated = matImage.clone(); rot90(matImage,3); //Rotate it

Girar por grados arbitrarios Mientras estoy en ello, he aquí cómo rotar en un grado arbitrario, que espero que sea 50 veces más caro. Tenga en cuenta que la rotación de esta manera incluirá un relleno negro, y los bordes se girarán hacia fuera del tamaño original de la imagen.

void rotate(cv::Mat& src, double angle, cv::Mat& dst){ cv::Point2f ptCp(src.cols*0.5, src.rows*0.5); cv::Mat M = cv::getRotationMatrix2D(ptCp, angle, 1.0); cv::warpAffine(src, dst, M, src.size(), cv::INTER_CUBIC); //Nearest is too rough, }

Llamar a esto por una rotación de 10.5 grados es obviamente:

cv::Mat matImage, matRotated; //Load in data rotate(matImage, 10.5, matRotated);

Me parece notable que este tipo de funciones extremadamente básicas no sean parte de OpenCV, mientras que OpenCV tiene cosas nativas como la detección de rostros (que en realidad no se mantiene con un rendimiento cuestionable). Notable.

Aclamaciones


Utilice warpAffine .:

Tratar:

Point2f src_center(source.cols/2.0F, source.rows/2.0F); Mat rot_mat = getRotationMatrix2D(src_center, angle, 1.0); Mat dst; warpAffine(source, dst, rot_mat, source.size());

dst es la imagen final