Подтвердить что ты не робот

Поверните матрицу Opencv на 90, 180, 270 градусов

Я собираю изображение с веб-камеры, и мне нужно повернуть его под прямым углом. Я нашел себе следующие функции:

  • getRotationMatrix2D - создать матрицу вращения (что бы она ни была)
  • 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
   }

Выводит только черный экран.

4b9b3361

Ответ 1

Используйте 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 - окончательное изображение

Ответ 2

Вышеупомянутые ответы слишком сложны и выверните ваш процессор. Ваш вопрос не был произвольным вращением, но "Повернуть матрицу 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

и т.д.. Выясните другие команды самостоятельно (мышление = обучение), представив себя с транспозицией и переворачиванием операции с Документами.

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 раз дороже. Обратите внимание, что вращение таким образом будет включать черное отступы, а края будут повернуты до значения оригинального размера изображения.

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 имеет собственные вещи, такие как обнаружение лиц (что действительно не поддерживается с сомнительной производительностью). Примечателен.

Приветствия

Ответ 3

@Abhishek Thakur отвечает только за хорошее вращение изображения на 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);

Изменить: Другой подход для поворота изображений на 90 180 или 270 градусов включает в себя выполнение матрицы transpose, а затем flip. Этот метод, вероятно, быстрее.

Ответ 4

Вышеприведенный код работает просто отлично, но вводит числовую ошибку в изображении из-за вычислений матрицы, выполняемых в плавающей точке и интерполяции warpAffine.

Для поворота с шагом в 90 д. я предпочитаю использовать следующее (в python/opencv python)

Так как изображения OpenCV в Python являются 2d массивами Numpy.

90 град.
theImage = numpy.rot90 (theImage, 1)
270 град.
theImage = numpy.rot90 (theImage, 3)

Примечание. Я тестировал это только на изображениях по шкале серого (X, Y). Если у вас есть цветное (или другое многораздельное) изображение, вам может потребоваться сначала его изменить, чтобы убедиться, что вращение работает по правильной оси.