Opencv圖像任意角度旋轉

實現圖像的任意角度旋轉

特殊角度(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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章