图像旋转的MATLAB和OpenCV源码
图像处理开发需求、图像处理接私活挣零花钱,请加微信/QQ 2487872782
图像处理开发资料、图像处理技术交流请加QQ群,群号 271891601
源码中用到的lena.jpg、lena_gray.png、pool.jpg图像的下载链接分别为:
lena.jpg_免费高速下载|百度网盘-分享无限制
http://pan.baidu.com/s/1bo5zC2F
pool.jpg_免费高速下载|百度网盘-分享无限制
先要说明的是,MATLAB得出的图像和OpenCV得出的源码在数据上是有差别的,但是都是对的!
先上MATLAB处理灰度图像的源码:
clear all;
close all;
clc;
a=imread('lena.jpg');
a=rgb2gray(a);
a1=imrotate(a,30,'bilinear');%%旋转函数,30为旋转角度,bilinear为旋转后不是整数点的像素值 通过双线性插值得到。当旋转角度为正时,逆时针旋转;当旋转角度为负时,顺时针旋转。
figure,imshow(a);
figure,imshow(a1);
再上MATLAB处理彩色图像的源码:
clear all;
close all;
clc;
a=imread('lena.jpg');R=a(:,:,1);
G=a(:,:,2);
B=a(:,:,3);R_r=imrotate(R,30,'bilinear');%旋转函数,30为旋转角度,bilinear为旋转后不是整数点的像素值 通过双线性插值得到。当旋转角度为正时,逆时针旋转;当旋转角度为负时,顺时针旋转。
G_r=imrotate(G,30,'bilinear');
B_r=imrotate(B,30,'bilinear');a1(:,:,1)=R_r;
a1(:,:,2)=G_r;
a1(:,:,3)=B_r;figure,imshow(a);
figure,imshow(a1);
再上OpenCV处理灰度级图像旋转的C源码(不使用MAT类):
#include <opencv2/opencv.hpp>
#include <opencv2/legacy/compat.hpp>
#include <fstream>
using namespace std;
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") IplImage *FitRotate (IplImage* Img_old, double angle,int method) //使用透视变换实现图像的旋转{IplImage* Img_tmp = NULL; double anglerad = (CV_PI* (angle/180)) ;//把角度制化为弧度制//计算旋转之后图片的新高度和宽度int newheight =int (fabs(( sin(anglerad)*Img_old->width )) + fabs(( cos(anglerad)*Img_old->height )) );int newwidth =int (fabs(( sin(anglerad)*Img_old->height)) + fabs(( cos(anglerad)*Img_old->width)) );Img_tmp = cvCreateImage(cvSize(newwidth,newheight), IPL_DEPTH_8U, 1);cvFillImage(Img_tmp,0);//如果return Img_tmp;则旋转后的图像与输入图像大小不一致IplImage* dst = cvCloneImage( Img_old );//如果return dst;则旋转后的图像与输入图像大小一致float m[6]; CvMat M = cvMat( 2, 3, CV_32F, m );//从这里开始是核心算法CvPoint2D32f src_point[4];CvPoint2D32f dst_point[4];src_point[0].x=0.0; src_point[0].y=0.0;src_point[1].x=0.0; src_point[1].y=(float) Img_old->height; src_point[2].x=(float) Img_old->width; src_point[2].y=(float) Img_old->height;src_point[3].x=(float) Img_old->width; src_point[3].y=0.0;dst_point[0].x=0; dst_point[0].y=(float) fabs(( sin(anglerad)*Img_old->width ));dst_point[1].x=(float) fabs(( sin(anglerad)*Img_old->height)); dst_point[1].y=(float) fabs(( sin(anglerad)*Img_old->width ))+(float) fabs(( cos(anglerad)*Img_old->height));dst_point[2].x=(float) fabs(( sin(anglerad)*Img_old->height))+(float) fabs(( cos(anglerad)*Img_old->width));dst_point[2].y=(float) fabs(( cos(anglerad)*Img_old->height));dst_point[3].x=(float) fabs(( cos(anglerad)*Img_old->width));dst_point[3].y=0;float newm[9]; CvMat newM = cvMat( 3, 3, CV_32F, newm );cvWarpPerspectiveQMatrix(src_point,dst_point,&newM);cvWarpPerspective(Img_old,dst,&newM,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0) );cvWarpPerspective(Img_old,Img_tmp,&newM,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0) );return Img_tmp;//return dst;}int main()
{IplImage *pSrcImage = cvLoadImage("lena.png", CV_LOAD_IMAGE_UNCHANGED); //IplImage *pOutImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U,1);IplImage *pOutImage = NULL;pOutImage=FitRotate(pSrcImage,70,1);cvSaveImage("pOutImage_lena.png",pOutImage); const char *pstrWindowsATitle = "原图"; const char *pstrWindowsBTitle = "变换后的图"; //创建窗口 cvNamedWindow(pstrWindowsATitle, CV_WINDOW_AUTOSIZE); cvNamedWindow(pstrWindowsBTitle, CV_WINDOW_AUTOSIZE);//在指定窗口中显示图像 cvShowImage(pstrWindowsATitle, pSrcImage); cvShowImage(pstrWindowsBTitle, pOutImage); //等待按键事件 cvWaitKey(); cvDestroyWindow(pstrWindowsATitle); cvDestroyWindow(pstrWindowsBTitle); cvReleaseImage(&pSrcImage); cvReleaseImage(&pOutImage); return 0;
}
再上OpenCV处理RGB图像旋转的C源码(不使用MAT类):
#include <opencv2/opencv.hpp>
#include <opencv2/legacy/compat.hpp>
#include <fstream>
using namespace std;
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") int main()
{ double degree = 30; // rotate 30 degree double angle = degree * CV_PI / 180.; // angle in radian double a = sin(angle), b = cos(angle); // sine and cosine of angle // Load source image as you wish IplImage *imgSrc = cvLoadImage("lena.jpg"); int w_src = imgSrc->width; int h_src = imgSrc->height; cvNamedWindow ("src", 1); cvShowImage ("src", imgSrc); // Make w_dst and h_dst to fit the output image int w_dst = int(h_src * fabs(a) + w_src * fabs(b)); int h_dst = int(w_src * fabs(a) + h_src * fabs(b)); // map matrix for WarpAffine, stored in statck array double map[6]; CvMat map_matrix = cvMat(2, 3, CV_64FC1, map); // Rotation center needed for cv2DRotationMatrix CvPoint2D32f pt = cvPoint2D32f(w_src / 2, h_src / 2); cv2DRotationMatrix(pt, degree, 1.0, &map_matrix); // Adjust rotation center to dst's center, // otherwise you will get only part of the result map[2] += (w_dst - w_src) / 2; map[5] += (h_dst - h_src) / 2; // We need a destination image IplImage *imgDst = cvCreateImage(cvSize(w_dst, h_dst), 8, 3); //按我的想像,如果把3改成1就能处理灰度图像才对,但要报错cvWarpAffine( imgSrc, imgDst, &map_matrix, CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, cvScalarAll(0) ); //cvSaveImage("lena_gray_rotation.png",imgDst); //将图像保存到硬盘// Don't forget to release imgSrc and imgDst if you no longer need them cvNamedWindow( "dst_big", 1 ); cvShowImage( "dst_big", imgDst); cvWaitKey(0); cvReleaseImage(&imgSrc); cvReleaseImage(&imgDst); return 0;
}
需要说明的是,按理在OpenCV处理RGB图像旋转的源码中,把语句 IplImage *imgDst = cvCreateImage(cvSize(w_dst, h_dst), 8, 3); 中的3改成1,应该就可以处理灰度图像才对,但我试了,报错,不知道怎么回事!我的源图像是灰度图像也报错!
结果如下图所示:
MATLAB的结果:
OpenCV的结果:
再上OpenCV的C++源码(使用MAT类,并且RGB和灰度图像都能处理)
//OpenCV版本2.4.9
//交流QQ2487872782 #include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <cmath>
using namespace cv;
using namespace std;
cv::Mat angelRotate(cv::Mat& src, int angle)
{// 角度转换float alpha = float(angle * CV_PI / 180);// 构造旋转矩阵float rotateMat[3][3] = { {cos(alpha), -sin(alpha), 0},{sin(alpha), cos(alpha), 0}, {0, 0, 1} };int nSrcRows = src.rows;int nSrcCols = src.cols;// 计算旋转后图像矩阵各个顶点位置float a1 = nSrcCols * rotateMat[0][0] ;float b1 = nSrcCols * rotateMat[1][0] ;float a2 = nSrcCols * rotateMat[0][0] + nSrcRows * rotateMat[0][1];float b2 = nSrcCols * rotateMat[1][0] +nSrcRows * rotateMat[1][1];float a3 = nSrcRows * rotateMat[0][1];float b3 = nSrcRows * rotateMat[1][1];// 计算出极值点float kxMin = min( min( min(0.0f,a1), a2 ), a3);float kxMax = max( max( max(0.0f,a1), a2 ), a3);float kyMin = min( min( min(0.0f,b1), b2 ), b3);float kyMax = max( max( max(0.0f,b1), b2 ), b3);// 计算输出矩阵的尺寸int nRows = int(abs(kxMax - kxMin));int nCols = int(abs(kyMax - kyMin));cv::Mat dst(nRows, nCols, src.type(),cv::Scalar::all(0)); for( int i = 0; i < nRows; ++i){ for (int j = 0; j < nCols; ++j){// 旋转坐标转换int x = (j + kxMin) * rotateMat[0][0] -(i + kyMin) * rotateMat[0][1] ;int y = -(j + kxMin) * rotateMat[1][0] + (i + kyMin) * rotateMat[1][1] ;if( (x >= 0) && (x < nSrcCols) && (y >= 0) && (y < nSrcRows) ) { dst.at<cv::Vec3b>(i,j) = src.at<cv::Vec3b>(y,x);}}}return dst;
}
int main()
{/*cv::Mat srcImage = cv::imread("pool.jpg"); */cv::Mat srcImage = cv::imread("lena_gray.png"); if(!srcImage.data) return -1;cv::imshow("srcImage", srcImage); int angle = 30;cv::Mat resultImage = angelRotate(srcImage, angle);imshow("resultImage", resultImage);cv::waitKey(0);return 0;
}
运行结果如下图所示:
图像处理开发需求、图像处理接私活挣零花钱,请加微信/QQ 2487872782
图像处理开发资料、图像处理技术交流请加QQ群,群号 271891601
图像旋转的MATLAB和OpenCV源码相关推荐
- 图像转置的MATLAB和OpenCV源码
图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 注意,图像转置和图像旋转是两回事,图像转置只是把 ...
- 【Matlab图像加密】正交拉丁方置乱算法图像加解密【含GUI源码 182期】
一.代码运行视频(哔哩哔哩) [Matlab图像加密]正交拉丁方置乱算法图像加解密[含GUI源码 182期] 二.matlab版本及参考文献 一.代码运行视频(哔哩哔哩) [Matlab图像处理]自动 ...
- OpenCV源码中Haar训练及特征提取的代码说明
//针对大小为winsize的图,计算所有HaarFeature的rect,存入features返回,即获取所有特征坐标 CvIntHaarFeatures* icvCreateIntHaarFeat ...
- 修改并编译OpenCV源码提升霍夫变换线检测效果
在做图像处理的时候,经常需要用到MATLAB验证与OpenCV实现共同进行,本文动手动机就是:OpenCV提供的Hough线检测不能满足我的要求,故需要对OpenCV源码进行修改.本人菜鸟,才学C++ ...
- 双目相机标定OpenCV源码讲解
双目相机标定OpenCV源码讲解 背景介绍 所述内容 参考资料 摄像机标定部分代码 代码思路 代码中的其他函数 找角点&求内参 求外参 求矫正映射矩阵 后记 背景介绍 暑假接近两个月的时间做了 ...
- opencv源码解析之(6):hog源码分析
一.网上一些参考资料 在博客目标检测学习_1(用opencv自带hog实现行人检测) 中已经使用了opencv自带的函数detectMultiScale()实现了对行人的检测,当然了,该算法采 ...
- python opencv源码_caffegpu源码编译
软硬件环境 ubuntu 18.04 64bit NVidia GTX 1070Ti anaconda with python 3.7 CUDA 10.1 cuDNN 7.6 opencv 3.4.2 ...
- java求sobel算子代码_sobel算子原理及opencv源码实现
sobel算子原理及opencv源码实现 简要描述 sobel算子主要用于获得数字图像的一阶梯度,常见的应用和物理意义是边缘检测. 原理 算子使用两个33的矩阵(图1)算子使用两个33的矩阵(图1)去 ...
- windows+vscode+opencv源码安装配置
一.参考资料 VScode搭建OpenCV环境 OpenCV使用CMake和MinGW-w64的编译安装 win10下VSCode配置opencv4.4.0(超详细教程,亲测有效) VSCODE中配置 ...
最新文章
- JAVA 线上故障排查完整套路,从 CPU、磁盘、内存、网络、GC 一条龙!
- linux 线程--内核线程、用户线程实现方法
- 雷电2接口_地表最强?代替电脑的所有接口,雷电3或有望一统接口江湖
- 安装最新版本的ReSharper导致原生全局搜索工具的消失问题
- JAVA多线程之wait/notify
- Spring总结四:IOC和DI 注解方式
- 国科大prml14-独立于算法的机器学习(boosting/
- python与机器学习(二)Numpy / Pandas /矩阵相乘速度对比
- vector二维的长度
- NSIS制作安装包实例
- size ar objdump readelf binutils
- 物联网工业串口转WiFi模块 无线路由WiFi模块的选型
- 公众号网课搜题系统-掘光者题库
- 巴比特 | 元宇宙每日必读:HTC 宣布推出首款元宇宙手机,售价约2700元人民币,都有哪些新玩法?...
- notebook jupyter, can not assign ip adress
- 有哪些比较好的pdf阅读器?思路提供
- Dragon slayer
- 【c++】string模拟实现(三大基本成员函数)
- Micro-SIM卡与Mini-SIM卡
- 从前后端的角度分析options预检请求——打破前后端联调的理解障碍
热门文章
- 精通python-轻松打造11周精通python计划(完结) | 软件库
- python映射类型-python映射类型的相关介绍
- python批量下载网页文件-超简单超详细python小文件、大文件、批量下载教程
- python基础语法有哪些-Python基础语法知识有哪些?
- python怎么读文件里的某一行-python如何读取文件中的某几行
- python利器的使用-PPython:PHP 拥抱 Python 的利器
- python常用内置函数总结-python常见的内置函数
- python怎样画立体图形-用python来画出高光谱遥感影像的3D立体图
- python语音播报-Python实现有道翻译+语音播报
- python的快速入门-Python如何快速入门的基础知识