Самый простой способ повернуть на 90 градусов изображение с помощью OpenCV?

c++ image opencv rotation

68572 просмотра

7 ответа

Каков наилучший способ (в c / c ++) повернуть IplImage / cv :: Mat на 90 градусов? Я бы предположил, что должно быть что-то лучше, чем преобразовать его с помощью матрицы, но я не могу найти ничего, кроме этого в API и онлайн.

Автор: Ben H Источник Размещён: 17.05.2019 03:27

Ответы (7)


23 плюса

Решение

Начиная с OpenCV3.2, жизнь стала немного легче, теперь вы можете поворачивать изображение в одной строке кода:

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

Для направления вы можете выбрать любое из следующего:

ROTATE_90_CLOCKWISE
ROTATE_180
ROTATE_90_COUNTERCLOCKWISE
Автор: Morris Franken Размещён: 23.06.2017 01:45

56 плюса

Вращение - это композиция транспозиции и флип.

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)
Автор: sastanin Размещён: 06.05.2011 02:27

10 плюса

Обновление для транспонирования:

Вы должны использовать cvTranspose()или cv::transpose()потому что (как вы правильно указали) это более эффективно. Опять же, я рекомендую перейти на OpenCV2.0, поскольку большинство cvXXXфункций просто преобразуют IplImage*структуры в Matобъекты (без глубоких копий). Если вы сохранили изображение в Matобъекте, Mat.t()верните транспонирование.

Любое вращение:

Вы должны использовать cvWarpAffine, определив матрицу вращения в общей структуре матрицы преобразования. Я настоятельно рекомендую перейти на OpenCV2.0, который имеет несколько функций, а также Matкласс, который инкапсулирует матрицы и изображения. С 2.0 вы можете использовать warpAffine для вышесказанного.

Автор: Jacob Размещён: 14.02.2010 12:39

4 плюса

Это пример без нового интерфейса 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;
}
Автор: Andres Hurtis Размещён: 05.12.2011 02:47

3 плюса

Вот моя cv2реализация python :

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)
Автор: Eran W Размещён: 21.02.2017 05:15

2 плюса

Вот мой EmguCV (C # порт OpenCV):

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 ++.

Автор: mpen Размещён: 18.04.2012 01:51

1 плюс

Ну, я искал некоторые подробности и не нашел никакого примера. Поэтому я отправляю 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; 

Ответ: Потому что это работает :) Единственный центр, который я нашел, не переводит изображение. Хотя, если у кого-то есть объяснение, мне было бы интересно.

Автор: Artem Размещён: 01.07.2010 03:48
Вопросы из категории :
32x32