繁体   English   中英

使用OpenCV将图像旋转90度的最简单方法?

[英]Easiest way to rotate by 90 degrees an image using OpenCV?

将IplImage / cv :: Mat旋转90度的最佳方法(在c / c ++中)是什么? 我认为必须有比使用矩阵转换它更好的东西,但我似乎无法在API和在线中找到除此之外的任何东西。

旋转是转置和翻转的组合。

R _ {+ 90} = F_x \\ circ T.

R _ { -  90} = F_y \\ circ T.

在OpenCV中可以这样编写(下面的Python示例):

img = cv.LoadImage("path_to_image.jpg")
timg = cv.CreateImage((img.height,img.width), img.depth, img.channels) # transposed image

# rotate counter-clockwise
cv.Transpose(img,timg)
cv.Flip(timg,timg,flipMode=0)
cv.SaveImage("rotated_counter_clockwise.jpg", timg)

# rotate clockwise
cv.Transpose(img,timg)
cv.Flip(timg,timg,flipMode=1)
cv.SaveImage("rotated_clockwise.jpg", timg)

从OpenCV3.2开始,生活变得更加简单,您现在可以在一行代码中旋转图像:

cv::rotate(image, image, cv::ROTATE_90_CLOCKWISE);

对于方向,您可以选择以下任何一个:

ROTATE_90_CLOCKWISE
ROTATE_180
ROTATE_90_COUNTERCLOCKWISE

换位更新:

您应该使用cvTranspose()cv::transpose()因为(正如您正确指出的那样)它更有效。 同样,我建议升级到OpenCV2.0,因为大多数cvXXX函数只是将IplImage*结构转换为Mat对象(没有深拷贝)。 如果将图像存储在Mat对象中, Mat.t()将返回转置。

任何轮换:

您应该通过在转换矩阵的一般框架中定义旋转矩阵来使用cvWarpAffine。 我强烈建议升级到具有多个功能的OpenCV2.0以及封装矩阵和图像的Mat类。 使用2.0,您可以使用warpAffine来实现上述目标。

这是我的python cv2实现:

import cv2

img=cv2.imread("path_to_image.jpg")

# rotate ccw
out=cv2.transpose(img)
out=cv2.flip(out,flipCode=0)

# rotate cw
out=cv2.transpose(img)
out=cv2.flip(out,flipCode=1)

cv2.imwrite("rotated.jpg", out)

这是没有新C ++接口的示例(适用于90,180和270度,使用param = 1,2和3)。 记得在使用后在返回的图像上调用cvReleaseImage

IplImage *rotate_image(IplImage *image, int _90_degrees_steps_anti_clockwise)
{
    IplImage *rotated;

    if(_90_degrees_steps_anti_clockwise != 2)
        rotated = cvCreateImage(cvSize(image->height, image->width), image->depth, image->nChannels);
    else
        rotated = cvCloneImage(image);

    if(_90_degrees_steps_anti_clockwise != 2)
        cvTranspose(image, rotated);

    if(_90_degrees_steps_anti_clockwise == 3)
        cvFlip(rotated, NULL, 1);
    else if(_90_degrees_steps_anti_clockwise == 1)
        cvFlip(rotated, NULL, 0);
    else if(_90_degrees_steps_anti_clockwise == 2)
        cvFlip(rotated, NULL, -1);

    return rotated;
}

这是我的EmguCV(OpenCV的C#端口)解决方案:

public static Image<TColor, TDepth> Rotate90<TColor, TDepth>(this Image<TColor, TDepth> img)
    where TColor : struct, IColor
    where TDepth : new()
{
    var rot = new Image<TColor, TDepth>(img.Height, img.Width);
    CvInvoke.cvTranspose(img.Ptr, rot.Ptr);
    rot._Flip(FLIP.HORIZONTAL);
    return rot;
}

public static Image<TColor, TDepth> Rotate180<TColor, TDepth>(this Image<TColor, TDepth> img)
    where TColor : struct, IColor
    where TDepth : new()
{
    var rot = img.CopyBlank();
    rot = img.Flip(FLIP.VERTICAL);
    rot._Flip(FLIP.HORIZONTAL);
    return rot;
}

public static void _Rotate180<TColor, TDepth>(this Image<TColor, TDepth> img)
    where TColor : struct, IColor
    where TDepth : new()
{
    img._Flip(FLIP.VERTICAL);
    img._Flip(FLIP.HORIZONTAL);
}

public static Image<TColor, TDepth> Rotate270<TColor, TDepth>(this Image<TColor, TDepth> img)
    where TColor : struct, IColor
    where TDepth : new()
{
    var rot = new Image<TColor, TDepth>(img.Height, img.Width);
    CvInvoke.cvTranspose(img.Ptr, rot.Ptr);
    rot._Flip(FLIP.VERTICAL);
    return rot;
}

不应该太难将其转换回C ++。

好吧,我正在寻找一些细节,没有找到任何例子。 所以我发布了一个transposeImage函数,希望能帮助那些正在寻找直接旋转90°而不丢失数据的人:

IplImage* transposeImage(IplImage* image) {

    IplImage *rotated = cvCreateImage(cvSize(image->height,image->width),   
        IPL_DEPTH_8U,image->nChannels);
    CvPoint2D32f center;
    float center_val = (float)((image->width)-1) / 2;
    center.x = center_val;
    center.y = center_val;
    CvMat *mapMatrix = cvCreateMat( 2, 3, CV_32FC1 );        
    cv2DRotationMatrix(center, 90, 1.0, mapMatrix);
    cvWarpAffine(image, rotated, mapMatrix, 
        CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, 
        cvScalarAll(0));      
    cvReleaseMat(&mapMatrix);

    return rotated;
}

问题:为什么这样?

float center_val = (float)((image->width)-1) / 2; 

答:因为它有效:)我找到的唯一中心不翻译图像。 虽然如果有人有解释我会感兴趣。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM