40

ウェブカメラから画像をキャプチャしていますが、直角に回転させる必要があります。私は自分自身がこれらの機能を見つけました:

  1. getRotationMatrix2D-回転行列を作成する(それが何であれ)
  2. transform-回転行列によって1つの行列を別の行列に変換します

でも、黒い部分しか出てこない。これは私のコードです:

   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

4 に答える 4

137

上記の答えは複雑すぎてCPUを占有します。あなたの質問は恣意的な回転ではありませんでしたが、「Opencvマトリックスを90、180、270度回転させてください」。

2017年6月30日更新:

この機能は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

など。ドキュメントから転置および反転操作を自己紹介することにより、他のコマンド(thinking = Learning)を自分で理解します。

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には顔検出などのネイティブな機能があることは注目に値します(これは疑わしいパフォーマンスでは実際には維持されません)。顕著。

乾杯

于 2014-06-02T08:37:06.680 に答える
32

ワープアフィンを使用します。:

試す:

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最終的な画像です

于 2013-02-23T17:18:25.253 に答える
9

@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ます。この方法の方がおそらく高速です。

于 2013-05-15T14:25:27.050 に答える
0

上記のコードは問題なく機能しますが、浮動小数点で実行される行列計算とwarpAffine補間により、画像に数値エラーが発生します。

90度の増分回転の場合、私は以下を使用することを好みます(python / opencv pythonで)

PythonのOpenCVイメージは2次元のNumpy配列であるため。

90度
theImage = numpy.rot90(theImage、1)
270度
theImage = numpy.rot90(theImage、3)

注:これは、形状(X、Y)のグレースケール画像でのみテストしました。カラー(または他のマルチセパレーション)画像がある場合は、回転が正しい軸に沿って機能することを確認するために、最初に画像の形状を変更する必要がある場合があります。

于 2013-10-10T12:28:39.960 に答える