Поверните матрицу Opencv на 90, 180, 270 градусов [дубликат]
этот вопрос уже есть ответ здесь:
Я снимаю изображение с веб-камеры, и мне нужно повернуть его под прямым углом. Я обнаружил, что эти функции:
-
getRotationMatrix2D
- для создания матрицы вращения (что бы это ни было is) -
transform
- преобразование одной матрицы в другую матрицу вращения
но, я не получаю ничего, кроме черной области. Вот мой код:
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
}
выводит только черный экран.
4 ответов
используйте warpAffine.:
попробуй:
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
облик
приведенные выше ответы слишком сложны и Хог ваш процессор. Ваш вопрос не был произвольным вращением, а "Поверните матрицу Opencv на 90, 180, 270 градусов".
ОБНОВЛЕНИЕ 30 ИЮНЯ 2017:
эта функция поддерживается OpenCV, но не документирована: https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core.hpp#L1041
void rotate(InputArray src, OutputArray dst, int rotateCode);
С
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
};
Первоначальный Ответ & Произвольный степень вращения:
вы также можете сделать это, используя флип и транспонировать операцию, т. е. для 90CW:
transpose(matSRC, matROT);
flip(matROT, matROT,1); //transpose+flip(1)=CW
etc. Выясните другие команды самостоятельно (мышление=обучение), представив себя с помощью операции транспонирования и флип из документов.
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;
}
}
Итак, вы называете это так, и обратите внимание, что матрица передается по ссылке.
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
поворот на произвольный градус Пока я на нем, вот как повернуть на произвольная степень, которая, как я ожидаю, будет в 50 раз дороже. Обратите внимание, что вращение таким образом будет включать черную прокладку, а края будут повернуты к oustide исходного размера изображения.
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,
}
вызов этого для вращения 10.5 градусов, то это очевидно:
cv::Mat matImage, matRotated;
//Load in data
rotate(matImage, 10.5, matRotated);
Я нахожу замечательным, что такие чрезвычайно основные функции не являются частью OpenCV, в то время как OpenCV имеет собственные вещи, такие как обнаружение лица (это на самом деле не поддерживается сомнительное исполнение). Замечательный.
Ура
@Абхишек Тхакура хорошо работает только для поворота изображения на 180 градусов. Он не обрабатывает вращение на 90 градусов, потому что
- центр вращения поставляется в
getRotationMatrix2D
некорректно, а - размер выходной матрицы передается в
warpAffline
некорректно.
вот код, который поворачивает изображение на 90 градусов:
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);
Edit: другой подход повернуть изображения 90,180 или 270 градусов включает в себя делать матрицу transpose
а то flip
. Этот метод, вероятно, быстрее.
приведенный выше код работает отлично, но вводит числовую ошибку в изображение из-за матричных вычислений, выполняемых в плавающей точке и интерполяции warpAffine.
для вращения с шагом 90deg я предпочитаю использовать следующее (в python/opencv python)
поскольку изображения OpenCV в Python являются массивами 2d Numpy.
90 град.
образ = и NumPy.rot90( theImage, 1 )
270 град.
образ = и NumPy.rot90( theImage, 3 )
примечание: Я проверил это только на серых изображениях формы ( X, Y ). Если у вас есть цвета (или другие выделение) изображения вам может понадобиться, чтобы изменить его, чтобы убедиться, что вращение вдоль оси.