图像处理开发需求、图像处理接私活挣零花钱,请加微信/QQ 2487872782
图像处理开发资料、图像处理技术交流请加QQ群,群号 271891601
本文依次给出以下5个源码:
①MATLAB对灰度图像进行旋转处理的源码;
②MATLAB对RGB彩色图像进行旋转处理的源码;
③OpenCV1.x对灰度图像作旋转处理的C源码(不使用MAT类);
④OpenCV1.x对RGB图像作旋转处理的C源码(不使用MAT类);
⑤OpenCV2.x对灰度图像和RGB彩色图像进行旋转处理的C++源码(使用MAT类)。
源码中用到的lena.jpg、lena_gray.png、pool.jpg图像的下载链接分别为
http://pan.baidu.com/s/1sl1jEKt
http://pan.baidu.com/s/1bo5zC2F
http://pan.baidu.com/s/1dFv2MM9
首先要说明的是,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对RGB彩色图像进行旋转处理的源码:
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);
运行结果如下图所示:
③OpenCV1.x对灰度图像作旋转处理的C源码(不使用MAT类):
#include
#include
#include
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;
}
运行结果如下图所示:
④OpenCV1.x对RGB图像作旋转处理的C源码(不使用MAT类):
#include
#include
#include
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;
}
运行结果如下图所示:
⑤OpenCV2.x对灰度图像和RGB彩色图像进行旋转处理的C++源码(使用MAT类)
//OpenCV版本2.4.9
//交流QQ2487872782
#include
#include
#include
#include
#include
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(i,j) =
src.at(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