Opencv影象任意角度旋轉
阿新 • • 發佈:2019-01-31
實現影象的任意角度旋轉
特殊角度(90,180,270)旋轉
Mat img2, src;
transpose(img, img2);
flip(img2, src, 0);
將影象img向左旋轉90度(轉置後沿x軸翻轉)
flip(img2, src, 0);
將影象img向右旋轉90度(轉置後沿y軸翻轉)
flip(img2, src, 1);
將影象img向旋轉180度(轉置後沿x和y軸翻轉)
flip(img2, src, -1);
任意角度旋轉
旋轉並擷取影象(不保留邊緣填充,可能會有影象資訊被截掉)
//影象旋轉1:旋轉(擷取影象)Crop ,擷取影象最大的內接矩形 // Mat img :影象輸入,單通道或者三通道 // Mat & imgout :影象輸出 // int degree :影象要旋轉的角度 // int border_value:影象旋轉填充值(0-255) int rotateImage1(Mat img,Mat & imgout, int degree,int border_value) { if( img.empty()) return 1; degree = -degree;//warpAffine預設的旋轉方向是逆時針,所以加負號表示轉化為順時針 double angle = degree * CV_PI / 180.; // 弧度 double a = sin(angle), b = cos(angle); int width = img.cols; int height = img.rows; int width_rotate = int(width * fabs(b)-height * fabs(a));//height * fabs(a) + int height_rotate = int(height * fabs(b)-width * fabs(a));//width * fabs(a) + if(width_rotate<=20||height_rotate<=20) { width_rotate = 20; height_rotate = 20; } //旋轉陣列map // [ m0 m1 m2 ] ===> [ A11 A12 b1 ] // [ m3 m4 m5 ] ===> [ A21 A22 b2 ] float map[6]; Mat map_matrix = Mat(2, 3, CV_32F, map); // 旋轉中心 CvPoint2D32f center = cvPoint2D32f(width / 2, height / 2); CvMat map_matrix2 = map_matrix; cv2DRotationMatrix(center, degree, 1.0, &map_matrix2);//計算二維旋轉的仿射變換矩陣 map[2] += (width_rotate - width) / 2; map[5] += (height_rotate - height) / 2; //Mat img_rotate; //對影象做仿射變換 //CV_WARP_FILL_OUTLIERS - 填充所有輸出影象的象素。 //如果部分象素落在輸入影象的邊界外,那麼它們的值設定為 fillval. //CV_WARP_INVERSE_MAP - 指定 map_matrix 是輸出影象到輸入影象的反變換, int chnnel =img.channels(); if(chnnel == 3) warpAffine(img, imgout, map_matrix, Size(width_rotate, height_rotate), 1, 0, Scalar(border_value,border_value,border_value)); else warpAffine(img, imgout, map_matrix, Size(width_rotate, height_rotate), 1, 0, border_value); return 0; }
旋轉影象(進行邊緣填充)
//影象旋轉2:擴充影象邊緣full // Mat img :影象輸入,單通道或者三通道 // Mat & imgout :影象輸出 // int degree :影象要旋轉的角度 // int border_value:影象旋轉填充值 int rotateImage2(Mat img,Mat & imgout, int degree,int border_value) { if(img.empty()) return 1; degree = -degree;//warpAffine預設的旋轉方向是逆時針,所以加負號表示轉化為順時針 double angle = degree * CV_PI / 180.; // 弧度 double a = sin(angle), b = cos(angle); int width = img.cols; int height = img.rows; int width_rotate = int(width * fabs(b)+height * fabs(a)); int height_rotate = int(height * fabs(b)+width * fabs(a)); if(width_rotate<=20||height_rotate<=20) { width_rotate = 20; height_rotate = 20; } //旋轉陣列map // [ m0 m1 m2 ] ===> [ A11 A12 b1 ] // [ m3 m4 m5 ] ===> [ A21 A22 b2 ] float map[6]; Mat map_matrix = Mat(2, 3, CV_32F, map); // 旋轉中心 CvPoint2D32f center = cvPoint2D32f(width / 2, height / 2); CvMat map_matrix2 = map_matrix; cv2DRotationMatrix(center, degree, 1.0, &map_matrix2);//計算二維旋轉的仿射變換矩陣 map[2] += (width_rotate - width) / 2; map[5] += (height_rotate - height) / 2; //Mat img_rotate; //對影象做仿射變換 //CV_WARP_FILL_OUTLIERS - 填充所有輸出影象的象素。 //如果部分象素落在輸入影象的邊界外,那麼它們的值設定為 fillval. //CV_WARP_INVERSE_MAP - 指定 map_matrix 是輸出影象到輸入影象的反變換, int chnnel =img.channels(); if(chnnel == 3) warpAffine(img, imgout, map_matrix, Size(width_rotate, height_rotate), 1, 0, Scalar(border_value,border_value,border_value)); else warpAffine(img, imgout, map_matrix, Size(width_rotate, height_rotate), 1, 0, border_value); return 0; }