OpenCV图像逆时针旋转90度

updated @ 2022.1.28

方法

三种方法:

  1. 水平翻转 + 转置: flip + transpose。 先flip或先transpose均可
  2. 用仿射变换实现: warpAffine
  3. 调用 rotate 函数

方法3最简单,方法1其次。

对于不懂仿射变换的人来说,方法2有可能正确,也可能得到错误结果:

  • 很多博客是用 n x n 的方形图像做测试,旋转前后的图像中心点没有变化, 也就是纯粹的旋转,结果确实正确
  • 如果测试图像换成长方形的, 例如 100 x 200 的尺寸,需要考虑:
      1. 结果图的尺寸, 是原图尺寸颠倒过来: (w, h) -> (h, w)
      1. 图像中心点发生了平移: (w/2, h/2) -> (h/2, w/2), 需要手动改仿射变换矩阵M (增加中心点变化导致的平移向量)
      • 图像中心点平移的解释: 图像左上角需要始终保持为(0,0)坐标,因而旋转后需要平移回来

OpenCV图像逆时针旋转90度

代码

Python

#coding:utf-8
import cv2 

def rotate_method1(src):
    dst = cv2.flip(src, 1)  #原型:cv2.flip(src, flipCode[, dst]) → dst  flipCode表示对称轴 0:x轴  1:y轴.  -1:both
    dst = cv2.transpose(dst)
    return dst

def rotate_method2(src):
    height, width, channels = src.shape
    src_center = (width/2, height/2)
    
    print("src_center:", src_center)
    angle = 90
    scale = 1.0
    rot_mat = cv2.getRotationMatrix2D(src_center, angle, scale)

    dsize = (height, width)
    dst_center = (src_center[1], src_center[0])
    rot_mat[0, 2] += (dst_center[0] - src_center[0])
    rot_mat[1, 2] += (dst_center[1] - src_center[1])
    print("dsize:", dsize)
    print("rot_mat:", rot_mat)
    dst = cv2.warpAffine(src, rot_mat, dsize, flags=cv2.INTER_LINEAR)
    return dst

def rotate_method3(src):
    dst = cv2.rotate(src, cv2.ROTATE_90_COUNTERCLOCKWISE)
    return dst

if __name__ == '__main__':
    src = cv2.imread('../assets/1920x1080.jpg')
    
    dst1 = rotate_method1(src)
    cv2.imwrite("rotate90_method1.jpg", dst1)

    dst2 = rotate_method2(src)
    cv2.imwrite("rotate90_method2.jpg", dst2)

    dst3 = rotate_method3(src)
    cv2.imwrite("rotate90_method3.jpg", dst3)

C++

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/opencv.hpp>
#include <iostream>
#include "plain/opencv_helper.hpp"

void rotate_method1(const cv::Mat& src, cv::Mat& dst)
{
    cv::flip(src, dst, 1);
    cv::transpose(dst, dst);
}

void rotate_method2(const cv::Mat& src, cv::Mat& dst)
{
    cv::Size ssize = src.size();
    int height = ssize.height;
    int width = ssize.width;
    
    cv::Point2f src_center(src.size()/2);
    std::cout << "src_center:" << src_center << std::endl;
    double angle = 90;
    double scale = 1;
    cv::Mat rot_mat = cv::getRotationMatrix2D(src_center, angle, scale);

    // manually do center point translation
    cv::Point2f dst_center;
    dst_center.x = src_center.y;
    dst_center.y = src_center.x;

    rot_mat.ptr<double>(0, 2)[0] += (dst_center.x - src_center.x);
    rot_mat.ptr<double>(1, 2)[0] += (dst_center.y - src_center.y);
    // std::cout << rot_mat << std::endl;

    cv::Size dsize;
    dsize.height = ssize.width;
    dsize.width = ssize.height;
    std::cout << "dsize:" << dsize << std::endl;
    std::cout << "rot_mat:" << rot_mat << std::endl;
    cv::warpAffine(src, dst, rot_mat, dsize, cv::INTER_LINEAR);
}

void rotate_method3(const cv::Mat& src, cv::Mat& dst)
{
    cv::rotate(src, dst, cv::ROTATE_90_COUNTERCLOCKWISE);
}

int main()
{
    std::string image_path = "1920x1080.jpg";
    cv::Mat src = cv::imread(image_path);
    
    cv::Mat dst1;
    rotate_method1(src, dst1);
    cv::imwrite("rotate90_method1.jpg", dst1);
    
    cv::Mat dst2;
    rotate_method2(src, dst2);
    cv::imwrite("rotate90_method2.jpg", dst2);

    cv::Mat dst3;
    rotate_method3(src, dst3);
    cv::imwrite("rotate90_method3.jpg", dst3);

    return 0;
}

原文链接: https://www.cnblogs.com/zjutzz/p/7207854.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    OpenCV图像逆时针旋转90度

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/257120

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月14日 上午10:37
下一篇 2023年2月14日 上午10:38

相关推荐