OPENCV 旋转图像算法-汇总

  1 void ImgRotate(cv::Mat imgIn, float theta, cv::Mat& imgOut)
  2 {
  3     int oldWidth = imgIn.cols;
  4     int oldHeight = imgIn.rows;
  5
  6     // 源图四个角的坐标(以图像中心为坐标系原点)
  7     float fSrcX1, fSrcY1, fSrcX2, fSrcY2, fSrcX3, fSrcY3, fSrcX4, fSrcY4;
  8     fSrcX1 = (float)(-(oldWidth - 1) / 2);
  9     fSrcY1 = (float)((oldHeight - 1) / 2);
 10     fSrcX2 = (float)((oldWidth - 1) / 2);
 11     fSrcY2 = (float)((oldHeight - 1) / 2);
 12     fSrcX3 = (float)(-(oldWidth - 1) / 2);
 13     fSrcY3 = (float)(-(oldHeight - 1) / 2);
 14     fSrcX4 = (float)((oldWidth - 1) / 2);
 15     fSrcY4 = (float)(-(oldHeight - 1) / 2);
 16
 17     // 旋转后四个角的坐标(以图像中心为坐标系原点)
 18     float fDstX1, fDstY1, fDstX2, fDstY2, fDstX3, fDstY3, fDstX4, fDstY4;
 19     fDstX1 = cos(theta) * fSrcX1 + sin(theta) * fSrcY1;
 20     fDstY1 = -sin(theta) * fSrcX1 + cos(theta) * fSrcY1;
 21     fDstX2 = cos(theta) * fSrcX2 + sin(theta) * fSrcY2;
 22     fDstY2 = -sin(theta) * fSrcX2 + cos(theta) * fSrcY2;
 23     fDstX3 = cos(theta) * fSrcX3 + sin(theta) * fSrcY3;
 24     fDstY3 = -sin(theta) * fSrcX3 + cos(theta) * fSrcY3;
 25     fDstX4 = cos(theta) * fSrcX4 + sin(theta) * fSrcY4;
 26     fDstY4 = -sin(theta) * fSrcX4 + cos(theta) * fSrcY4;
 27
 28     int newWidth = (max(fabs(fDstX4 - fDstX1), fabs(fDstX3 - fDstX2)) + 0.5);
 29     int newHeight = (max(fabs(fDstY4 - fDstY1), fabs(fDstY3 - fDstY2)) + 0.5);
 30
 31     imgOut.create(newHeight, newWidth, imgIn.type());
 32
 33     float dx = -0.5*newWidth*cos(theta) - 0.5*newHeight*sin(theta) + 0.5*oldWidth;
 34     float dy = 0.5*newWidth*sin(theta) - 0.5*newHeight*cos(theta) + 0.5*oldHeight;
 35
 36     int x, y;
 37     for (int i = 0; i < newHeight; i++)
 38     {
 39         for (int j = 0; j < newWidth; j++)
 40         {
 41             x = float(j)*cos(theta) + float(i)*sin(theta) + dx;
 42             y = float(-j)*sin(theta) + float(i)*cos(theta) + dy;
 43
 44             if ((x < 0) || (x >= oldWidth) || (y < 0) || (y >= oldHeight))
 45             {
 46                 if (imgIn.channels() == 3)
 47                 {
 48                     imgOut.at<cv::Vec3b>(i, j) = cv::Vec3b(0, 0, 0);
 49                 }
 50                 else if (imgIn.channels() == 1)
 51                 {
 52                     imgOut.at<uchar>(i, j) = 0;
 53                 }
 54             }
 55             else
 56             {
 57                 if (imgIn.channels() == 3)
 58                 {
 59                     imgOut.at<cv::Vec3b>(i, j) = imgIn.at<cv::Vec3b>(y, x);
 60                 }
 61                 else if (imgIn.channels() == 1)
 62                 {
 63                     imgOut.at<uchar>(i, j) = imgIn.at<uchar>(y, x);
 64                 }
 65             }
 66         }
 67     }
 68 }
 69
 70
 71 void getAfterRotateRoi(cv::Mat& imgIn, int cols, int rows, Mat& imgOut)
 72 {
 73
 74     imgOut.create(cols, rows, imgIn.type());
 75     Point center(imgIn.cols / 2, imgIn.rows / 2);
 76
 77     imgOut = imgIn(Rect(imgIn.cols / 2 - cols / 2, imgIn.rows / 2 - rows / 2, cols,rows));
 78
 79 }
 80
 81 Mat ImageRotate2NewSize(Mat& src, const CvPoint &_center, double angle, double scale)
 82 {
 83     double angle2 = angle * CV_PI / 180;
 84     int width = src.cols;
 85     int height = src.rows;
 86
 87     double alpha = cos(angle2) * scale;
 88     double beta = sin(angle2) * scale;
 89
 90     int new_width = (int)(width * fabs(alpha) + height * fabs(beta));
 91     int new_height = (int)(width * fabs(beta) + height * fabs(alpha));
 92
 93     CvPoint2D32f center;
 94     center.x = float(width / 2);
 95     center.y = float(height / 2);
 96     //计算二维旋转的仿射变换矩阵
 97     Mat M = getRotationMatrix2D(center, angle, scale);
 98
 99     // 给计算得到的旋转矩阵添加平移
100     M.at<double>(0, 2) += (int)((new_width - width) / 2);
101     M.at<double>(1, 2) += (int)((new_height - height) / 2);
102
103     // rotate
104     Mat dst;
105     warpAffine(src, dst, M, cvSize(new_width, new_height), CV_INTER_LINEAR);
106     return dst;
107 }

参考:http://www.tuicool.com/articles/RZz2Eb

时间: 2024-12-13 06:58:59

OPENCV 旋转图像算法-汇总的相关文章

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

OpenCV——旋转模糊 (二)

// define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED #include <iostream> #include <string> #include "cv.h" #include "highgui.h" #include "cxmat.hpp" #include "cxcore.hpp&quo

Excel2010数据透视表1

“透视”作为一个动词,意思是旋转.如果将数据看成是一个物体,数据透视表允许旋转数据汇总,从不同角度或观点来看它.数据透视表能够轻松地移动字段,交换字段位置,设置创建项目的特定组. 如果给出一个陌生的物体让你鉴定,你可能会从不同的角度观察它来得出答案.处理数据透视表与研究一个陌生的物体类似.此时,物体就是你自己的数据.数据透视表需要多次试验,所以要旋转并控制数据透视表直到你满意为止.最后得到的结果会让你感到惊讶. 数据透视表是一种让用户可以根据不同的分类.不同的汇总方式.快速查看各种形式的数据汇总

matlab、opencv、halcon双目标定汇总

相机的标定对于测距和重建还是很重要的,特把用过的工具和方法进行一次汇总,以便查阅.分析和讨论(本人扣扣1256635840) ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— 1.MATLAB camera calib

Opencv图像识别从零到精通(7)----图像平移、旋转、镜像

根据vc6.0c++的学习经验,如果可以很好的自己编程,让图像进行平移旋转这些操作,那么就好像能够清楚的看见图像的内部结构当然这里你怎么访问像素,这个可以自己选一种适合的,最多的是ptr指针,at也是挺多的.看着很简单的变换,可以对图像处理上手的更快,当然对于旋转可能就稍微i难了一点,不过opencv提供了resize(0,remap()等这样的函数,可以方便的让我们进行学习-特别是旋转的时候,有很多的变换,你可以任意旋转一个角度,也可能一直旋转,当然还可以保持图像大小不变的旋转和大小变换的旋转

opencv图像原地(不开辟新空间)顺时旋转90度

前一阵朋友碰到这么一道题:将图像原地顺时针旋转90度,不开辟新空间.此题看似平易(题目简短),仔细研究发现着实不容易.经过一番探索后,终于找到了正确的算法,但是当使用opencv实现时,有碰到了困难而且费了一番周折才找到问题所在. 首先,解决这个问题,先简化成原地90度旋转一M×N的矩阵A(注意不是N×N方阵).对于2×3的矩阵A = {1,2,3;4,5,6},其目标为矩阵B = {4,1;5,2;6,3}.因为是原地旋转,这里A和B应指向同一大小为6的内存空间. 这里有这样一个重要的导出公式

使用OpenCL+OpenCV实现图像旋转(一)

[题外话]近期申请了一个微信公众号:平凡程式人生.有兴趣的朋友可以关注,那里将会涉及更多更新OpenCL+OpenCV以及图像处理方面的文章. 最近在学习<OPENCL异构计算>,其中有一个实例是使用OpenCL实现图像旋转.这个实例中并没有涉及读取.保存.显示图像等操作,其中也存在一些小bug.在学习OpenCL之初,完整地实现这个实例还是很有意义的事情. 1.图像旋转原理 所谓图像旋转是指图像以某一点为中心旋转一定的角度,形成一幅新的图像的过程.这个点通常就是图像的中心. 由于是按照中心旋

【OpenCV】图像旋转详解,边缘用黑色填充

项目要用到图像旋转,OpenCV里面居然没有专门封装好的函数,只好自己写了.根据<learnning OpenCV>发现效果不是很理想,旋转后图像大小不变,可是图像却被裁减了. 例子如下: int main( int argc, char** argv ) { IplImage* src=cvLoadImage("C:\\Users\\Liu\\Desktop\\bridge.bmp",1); IplImage* dst = cvCloneImage( src ); int

【OPENCV】图像的预处理(灰度图、二值化、字符矫正(旋转))

1.首先加载原始图片: 2.cvCvtColor(img, source, CV_BGR2GRAY);转化成灰度图像: 3.cvThreshold(source,source_gray,100,255,CV_THRESH_BINARY );进行二值化处理. 由于原始的图片会有一定的角度,需要进行旋转,而旋转的话可以使用OPENCV提供的函数实现,本文中采用的是自己编写的,即通过旋转360,并记录旋转某个角度的时候使得在x轴方向的投影最大化. 如图,经过处理的图片效果如下所示: 完整的工程已经上传