怎么在OpenCV中利用c++实现一个图片旋转效果

  介绍

本篇文章为大家展示了怎么在OpenCV中利用c++实现一个图片旋转效果,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

图片旋转,本质上是对旋转后的图片中每个像素点计算在原图的位置,然后照搬过来就好。

图形图像课上一般会介绍旋转变换矩阵,其中t为需要旋转的角度,[x # 39;;y # 39;]是变换后坐标(其中分号表示上下关系):

怎么在OpenCV中利用c++实现一个图片旋转效果

即表示为:[x # 39;;y # 39;]=[cos (t) sin (t);sin (t) cost] [x;y)

因为我个人兴趣爱好(放p就是老师逼的…),不允许使用OpenCV封装好的旋转函数。只能自己实现,我开始的想法是:先求变换矩阵逆矩阵,然后将一张全黑图中每个点一一对应插值到原图中。

结果发现转换后图片全黑了……

后来发现原点设置不对。用OpenCV中的垫格式存储(或二维数组)的图片,原点在左上角。但是想要实现的旋转原点在图片中心。

同时,垫格式存储(或二维数组)的坐标系中y轴正方向向下。这样人类视觉上的顺时针旋转,在二维数组的坐标系中是逆时针旋转。

最重要的一点,也是二维数组操作中极易忽略的一点:数组操作的是数组下标,不是坐标系(数组的行数行是矩形的宽宽度,列数关口是矩形的长长度)。比如坐标系(此时为了更贴近数组布的局,我们假设y轴坐标系是向下的)中,矩形顶点是:

怎么在OpenCV中利用c++实现一个图片旋转效果

但是在数组中,因为是行优先,所以四个点的下标取值为:

怎么在OpenCV中利用c++实现一个图片旋转效果

有没有发现,两种坐标是相反的!

总结下来,我们的图片旋转需要注意以下几点:

<李>

变换后图片中的每个像素点(我;j),需要平移到相对旋转中心的新坐标,即(i - Mat.rows/2;j - Mat.cols/2)计算完成之后,需要再次还原到相对左上角原点的旧坐标;

<李>

本来需要变换后图片乘以原图变换矩阵的逆矩阵对应到原图中坐标。但是因为y轴方向向下,所以变换后图片乘以原图变换矩阵(无需逆矩阵)即可对应到原图中坐标(顺时针旋转50度,还原操作是逆时针旋转50度),

<李>

矩阵下标与原图变换矩阵相乘之前,需要将矩阵下标两值互换。相乘之后,需要再次互换下标值还原成矩阵下标。

因此对于一个经过旋转t度之后数组下标为(m, n # 39;]的像素值,还原成原图中的数组下标(m;n]计算为:

[cos (t) sin (t);sint cost]([猴# 39;;n # 39;] - [Mat.rows/2;Mat.cols/2]=[m;n]之处;[Mat.rows/2;Mat.cols/2)

源代码附上:

Mat  nearestNeighRotate(简历::Mat  img, float 角)   {   int  len =, (int) (sqrtf(战俘(img.rows, 2), +,战俘(img.cols, 2)), +, - 0.5);      Mat  retMat =,垫::0(兰,兰,,CV_8UC3);   float  anglePI =, angle  *, CV_PI /, 180;   int  xSm, ySm;      (int 小姐:=,0;,小姐:& lt;, retMat.rows;,我+ +)   (int  j =, 0;, j  & lt;, retMat.cols;, j + +)   {   xSm =, (int) ((i-retMat.rows/2) * cos (anglePI),安康;罪(j-retMat.cols/2) * (anglePI), +, - 0.5);   ySm =, (int) ((i-retMat.rows/2) * sin (anglePI), +, (j-retMat.cols/2) * cos (anglePI), +, - 0.5);   +=xSm  img.rows /, 2;   +=ySm  img.cols /, 2;      如果(xSm 祝辞=,img.rows  | |, ySm 祝辞=,img.cols  | |, xSm  & lt;=, 0, | |, ySm  & lt;=, 0) {   retMat.at (i, j),=, Vec3b (0, 0);   }   其他{   retMat.at (i, j),=, img.at (xSm, ySm);   }   }      return  retMat;   }

好,我们来测试看看:

int 主要(),   {,   Mat  img =, imread (“. ./HelloWorld.png");   时间=retImg  nearestNeighRotate (img, -20. f);   namedWindow (“nearNeigh", CV_WINDOW_AUTOSIZE);   imshow (“nearNeigh", retImg);      waitKey (),,   cvDestroyAllWindows ();   return  0,   }

上述内容就是怎么在OpenCV中利用c++实现一个图片旋转效果,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。

怎么在OpenCV中利用c++实现一个图片旋转效果