zoukankan      html  css  js  c++  java
  • opencv 旋转 点旋转 以及 逆旋转

    #include"opencv2/highgui/highgui.hpp"
    #include"opencv2/imgproc/imgproc.hpp"
    #include <iostream>
    using namespace std;
    
    using namespace cv;
    
    
    
    void CalcRotateMatrix(const cv::Mat& img, float degree, cv::Mat& trans_mat, cv::Size& dst_size){
        degree = fmod(degree + 360.0f, 360.0f);
        double angle = degree  * CV_PI / 180.;
        int width = img.cols;
        int height = img.rows;
        double a = sin(angle), b = cos(angle);
        int widthRotate = int(height * fabs(a) + width * fabs(b));
        int heightRotate = int(width * fabs(a) + height * fabs(b));
        
        //    int widthRotate = width;
        //    int heightRotate = height;
        
        // [ m0  m1  m2 ] ===>  [ A11  A12   b1 ]
        // [ m3  m4  m5 ] ===>  [ A21  A22   b2 ]
        trans_mat.create(2, 3, CV_32F);
        float *map = (float *)trans_mat.ptr<float>();
        
        CvPoint2D32f center = cvPoint2D32f(width / 2.0f, height / 2.0f);
        CvMat mapMatrix = trans_mat;
        cv2DRotationMatrix(center, degree, 1.0f, &mapMatrix);
        map[2] += (widthRotate - width) / 2.0f;
        map[5] += (heightRotate - height) / 2.0f;
        
        dst_size = cv::Size(widthRotate, heightRotate);
    }
    
    std::vector<cv::Point> PointAffine(const std::vector<cv::Point>& points, const cv::Mat& trans_mat){
        float *m = (float *)trans_mat.ptr<float>();
        vector<Point> transPoints;
        for(size_t i = 0; i < points.size(); i++)
        {
            Point p = points[i];
            int x = p.x * m[0] + p.y * m[1] + m[2];
            int y = p.x * m[3] + p.y * m[4] + m[5];
            transPoints.push_back(Point(x, y));
        }
        return transPoints;
    }
    
    
    
    int main()
    {
        Mat img = imread("/data_2/everyday/1228/plane.png");
        Point pt(285,67);
        circle(img,pt,13,Scalar(0,0,255),2);
        
        float angle = 32.5;
        
        
        Mat M;
        Mat img_rot, img_roi;
        Size dst_size;
        vector<Point> rot_points;
        
        CalcRotateMatrix(img, angle, M, dst_size);
        warpAffine(img, img_rot, M, dst_size, 1, 0, 0);
        
        
        std::vector<cv::Point> points,points_rot;
        points.push_back(pt);
        points_rot = PointAffine(points, M);
        Point pt_rot = points_rot[0];
        circle(img_rot,pt_rot,13,Scalar(255,0,255),2);
            
        imshow("img",img);
        imshow("img_rot",img_rot);
        waitKey(0);
    
        return 0;
    }
    


    通过旋转角度可以求得旋转矩阵,然后原图中的一个点通过旋转矩阵可以对应到旋转之后的图。但是问题来了,已知旋转矩阵,旋转后的图上的一个点,能对应到原图上面去吗???

    经过分析原图上面点通过防射变换矩阵旋转到旋转之后的图上,这段代码如下:

     Point p = points[i];
            int x = p.x * m[0] + p.y * m[1] + m[2];
            int y = p.x * m[3] + p.y * m[4] + m[5];
    

    我们现在是已知旋转矩阵,旋转后的图上的一个点,即x,y已知,所有m已知,要求的是p.x,p.y,二元一次方程组可以求出来。所以代码如下:

        float *m = (float *)M.ptr<float>();
        int xx = (m[4]*pt_rot.x-m[2]*m[4]-m[1]*pt_rot.y+m[1]*m[5])*1.0/MAX((m[0]*m[4]-m[1]*m[3]),0.01);
        int yy = (pt_rot.y-m[5]-m[3]*xx)*1.0/MAX(m[4],0.01);
    
    #include"opencv2/highgui/highgui.hpp"
    #include"opencv2/imgproc/imgproc.hpp"
    #include <iostream>
    using namespace std;
    using namespace cv;
    
    void CalcRotateMatrix(const cv::Mat& img, float degree, cv::Mat& trans_mat, cv::Size& dst_size){
        degree = fmod(degree + 360.0f, 360.0f);
        double angle = degree  * CV_PI / 180.;
        int width = img.cols;
        int height = img.rows;
        double a = sin(angle), b = cos(angle);
        int widthRotate = int(height * fabs(a) + width * fabs(b));
        int heightRotate = int(width * fabs(a) + height * fabs(b));
    
        //    int widthRotate = width;
        //    int heightRotate = height;
    
        // [ m0  m1  m2 ] ===>  [ A11  A12   b1 ]
        // [ m3  m4  m5 ] ===>  [ A21  A22   b2 ]
        trans_mat.create(2, 3, CV_32F);
        float *map = (float *)trans_mat.ptr<float>();
    
        CvPoint2D32f center = cvPoint2D32f(width / 2.0f, height / 2.0f);
        CvMat mapMatrix = trans_mat;
        cv2DRotationMatrix(center, degree, 1.0f, &mapMatrix);
        map[2] += (widthRotate - width) / 2.0f;
        map[5] += (heightRotate - height) / 2.0f;
    
        dst_size = cv::Size(widthRotate, heightRotate);
    }
    
    std::vector<cv::Point> PointAffine(const std::vector<cv::Point>& points, const cv::Mat& trans_mat){
        float *m = (float *)trans_mat.ptr<float>();
        vector<Point> transPoints;
        for(size_t i = 0; i < points.size(); i++)
        {
            Point p = points[i];
            int x = p.x * m[0] + p.y * m[1] + m[2];
            int y = p.x * m[3] + p.y * m[4] + m[5];
            transPoints.push_back(Point(x, y));
        }
        return transPoints;
    }
    
    int main()
    {
        Mat img = imread("/data_2/everyday/1228/plane.png");
        Point pt(285,67);
        circle(img,pt,13,Scalar(0,0,255),2);
    
        float angle = 32.5;
    
    
        Mat M;
        Mat img_rot, img_roi;
        Size dst_size;
        vector<Point> rot_points;
    
        CalcRotateMatrix(img, angle, M, dst_size);
        warpAffine(img, img_rot, M, dst_size, 1, 0, 0);
    
    
        std::vector<cv::Point> points,points_rot;
        points.push_back(pt);
        points_rot = PointAffine(points, M);
        Point pt_rot = points_rot[0];
        circle(img_rot,pt_rot,13,Scalar(255,0,255),2);
    
    
        float *m = (float *)M.ptr<float>();
        int xx = (m[4]*pt_rot.x-m[2]*m[4]-m[1]*pt_rot.y+m[1]*m[5])*1.0/MAX((m[0]*m[4]-m[1]*m[3]),0.01);
        int yy = (pt_rot.y-m[5]-m[3]*xx)*1.0/MAX(m[4],0.01);
    
        circle(img,Point(xx,yy),33,Scalar(255,0,0),2);
    
        imshow("img",img);
        imshow("img_rot",img_rot);
        waitKey(0);
    
        return 0;
    }
    

  • 相关阅读:
    nginx解决Ajax跨域问题
    传入token值到下个操作
    获取token值并写入Excel文件中
    读取配置文件.ini
    js判断页面元素是否存在
    SQL Server数据库管理常用的SQL和TSQL语句
    常用聊天工具(IM)在线客服链接代码
    [转]最大概率选择到“最好女孩”的算法
    Web开发:设置复选框的只读效果
    Web开发常用边框颜色汇总
  • 原文地址:https://www.cnblogs.com/yanghailin/p/12112636.html
Copyright © 2011-2022 走看看