男女做那个是的视频网站,青岛即墨网站建设,wordpress多板块,十大装饰公司排行榜目录原理源码RotateImage主函数效果完整源码速度优化源码优化效果平台#xff1a;Windows 10 20H2 Visual Studio 2015 OpenCV 4.5.3 本文算法改进自图形算法与实战#xff1a;6.图像运动专题#xff08;5#xff09;图像旋转-基于近邻插值的图像旋转 —— 进击的CV
原理…
目录原理源码RotateImage主函数效果完整源码速度优化源码优化效果平台Windows 10 20H2 Visual Studio 2015 OpenCV 4.5.3 本文算法改进自图形算法与实战6.图像运动专题5图像旋转-基于近邻插值的图像旋转 —— 进击的CV
原理 将旋转后图像的像素点映射回原图像找到它的采样点即旋转的逆变换。映射的结果不会都是整数像素点那么旋转后的点的像素值由与采样点最邻近的像素值表示这就是最近邻插值。
改变尺寸的图像旋转 这种旋转是将旋转后的图像内容完全显示出来所以要确定新的图像的尺寸。
源码
RotateImage
Mat RotateImage(Mat src, double angle)
{int x0, y0, x1, y1;angle angle * 3.1415926535897932384626433832795 / 180;int dx abs((int)src.cols*cos(angle)) abs((int)src.rows*sin(angle));int dy abs((int)src.cols*sin(angle)) abs((int)src.rows*cos(angle));Mat dst(dy, dx, CV_8UC3, Scalar(0)); //创建新图像for (x1 0; x1 dst.cols; x1){for (y1 0; y1 dst.rows; y1){double fx0, fy0;double fx1, fy1;double R;double sita, sita0, sita1;//将图片中点设为坐标原点fx1 x1 - dst.cols / 2;fy1 y1 - dst.rows / 2;R sqrt(fx1 * fx1 fy1 * fy1); //极径sita angle;sita1 atan2(fy1, fx1); //新点极角sita0 sita1 sita; //旧点极角//旧点直角坐标(中点为坐标原点)fx0 R * cos(sita0); fy0 R * sin(sita0);//旧点直角坐标(坐标原点在角上)x0 fx0 src.cols / 2 0.5;y0 fy0 src.rows / 2 0.5;if (x0 0 x0 src.cols y0 0 y0 src.rows){dst.atVec3b(Point(x1, y1)) src.atVec3b(Point(x0, y0));}elsedst.atVec3b(Point(x1, y1)) 0;}}return dst;
}主函数
int main(int argc, char * argv[])
{Mat src;src imread(D:\\Work\\OpenCV\\Workplace\\Test_1\\4.jpg);imshow(原图, src);for (short i -360; i 360; i){imshow(输出, RotateImage(src, i));waitKey(1);}waitKey(0);return 0;
}效果 完整源码
#include opencv2\opencv.hpp
#include iostreamusing namespace cv;
using namespace std;Mat RotateImage(Mat src, double angle)
{int x0, y0, x1, y1;angle angle * 3.1415926535897932384626433832795 / 180;int dx abs((int)src.cols*cos(angle)) abs((int)src.rows*sin(angle));int dy abs((int)src.cols*sin(angle)) abs((int)src.rows*cos(angle));Mat dst(dy, dx, CV_8UC3, Scalar(0)); //创建新图像for (x1 0; x1 dst.cols; x1){for (y1 0; y1 dst.rows; y1){double fx0, fy0;double fx1, fy1;double R;double sita, sita0, sita1;//将图片中点设为坐标原点fx1 x1 - dst.cols / 2;fy1 y1 - dst.rows / 2;R sqrt(fx1 * fx1 fy1 * fy1); //极径sita angle;sita1 atan2(fy1, fx1); //新点极角sita0 sita1 sita; //旧点极角//旧点直角坐标(中点为坐标原点)fx0 R * cos(sita0);fy0 R * sin(sita0);//旧点直角坐标(坐标原点在角上)x0 fx0 src.cols / 2 0.5;y0 fy0 src.rows / 2 0.5;if (x0 0 x0 src.cols y0 0 y0 src.rows){dst.atVec3b(Point(x1, y1)) src.atVec3b(Point(x0, y0));}elsedst.atVec3b(Point(x1, y1)) 0;}}return dst;
}int main(int argc, char * argv[])
{Mat src;src imread(D:\\Work\\OpenCV\\Workplace\\Test_1\\4.jpg);imshow(原图, src);for (short i -360; i 360; i){imshow(输出, RotateImage(src, i));waitKey(1);}waitKey(0);return 0;
}速度优化
源码
Mat RotateImage(Mat src, float angle)
{int x0, y0, x1, y1;angle angle * 3.1415926535897932384626433832795 / 180;float sin_sita sin(angle), cos_sita cos(angle);Mat dst(abs((int)src.cols*sin_sita) abs((int)src.rows*cos_sita), abs((int)src.cols*cos_sita) abs((int)src.rows*sin_sita), CV_8UC3, Scalar(0)); //创建新图像for (x1 0; x1 dst.cols; x1){for (y1 0; y1 dst.rows; y1){float fx1, fy1;//将图片中点设为坐标原点fx1 x1 - dst.cols / 2;fy1 y1 - dst.rows / 2;//旧点直角坐标(坐标原点在角上)x0 fx1*cos_sita - fy1*sin_sita src.cols / 2 0.5;y0 fx1*sin_sita fy1*cos_sita src.rows / 2 0.5;if (x0 0 x0 src.cols y0 0 y0 src.rows){dst.atVec3b(Point(x1, y1)) src.atVec3b(Point(x0, y0));}elsedst.atVec3b(Point(x1, y1)) 0;}}return dst;
}优化效果
旋转一幅1200×562的图像 用时几乎是原来的1/2