opencv----计算图像旋转参数

来源:互联网 发布:类似知轩藏书 编辑:程序博客网 时间:2024/04/28 14:07

弄这个弄了好几天,一直想的复杂了

其实很简单,其实并不难

先上代码吧,不过里面有很多多余的函数,不过之后计算平移+旋转的时候会用到

// xuanzhuan.cpp : 定义控制台应用程序的入口点。//#include "StdAfx.h"#include <opencv2/opencv.hpp>#include <opencv2/core/core.hpp>#include <opencv2/features2d/features2d.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/legacy/legacy.hpp>#include <iostream>#include <vector>using namespace cv;using namespace std;void fourier(cv::Mat in,cv::Mat &out_re,cv::Mat &out_im);//计算傅里叶变换,分别输出变换后结果的实部和虚部void gonglvpu(cv::Mat in1,cv::Mat in2,cv::Mat out);//计算傅里叶变换后的功率谱void pingyi(cv::Mat in_1,cv::Mat in_2,int &x,int &y);void cart2polar(cv::Mat in,cv::Mat &out);void polar2cart(cv::Mat in,cv::Mat out);void fft2(IplImage *src, IplImage *dst);void fft2shift(IplImage *src, IplImage *dst);void test(cv::Mat in,cv::Mat out);//本函数可以实现计算图像傅里叶变换后功率谱的功能int _tmain(int argc, _TCHAR* argv[]){cv::Mat image1=cv::imread("lena.bmp");cv::Mat image2=cv::imread("5du.bmp");cv::cvtColor(image1,image1,CV_RGB2GRAY);cv::cvtColor(image2,image2,CV_RGB2GRAY);cart2polar(image1,image1);//image1=image1(cv::Rect(0,0,200,200));cart2polar(image2,image2);//image2=image2(cv::Rect(0,0,200,200));cv::namedWindow("www");cv::imshow("www",image2);int xx=0,yy=0;pingyi(image1,image2,xx,yy);cout<<xx<<"     "<<yy<<endl;int theta=((double)(yy+1)/image1.rows)*360;cout<<"theta  "<<theta<<endl;cv::waitKey();/*cv::Mat src1s[]={Mat_<float>(image1),cv::Mat::zeros(image1.size(),CV_32FC1)};cv::Mat FA1;cv::merge(src1s,2,FA1);//cv::dft(FA1,FA1);cv::split(FA1,src1s);cv::magnitude(src1s[0],src1s[1],src1s[0]);src1s[0]=src1s[0](cv::Rect(100,100,400,400));cart2polar(src1s[0],src1s[0]);//polar2cart(src1s[0],src1s[0]);src1s[0]=src1s[0](cv::Rect(0,0,200,200));cv::normalize(src1s[0],src1s[0],0,1,CV_MINMAX);cv::Mat src2s[]={Mat_<float>(image2),cv::Mat::zeros(image2.size(),CV_32FC1)};cv::Mat FA2;cv::merge(src2s,2,FA2);//cv::dft(FA2,FA2);cv::split(FA2,src2s);cv::magnitude(src2s[0],src2s[1],src2s[0]);src2s[0]=src2s[0](cv::Rect(100,100,400,400));cart2polar(src2s[0],src2s[0]);src2s[0]=src2s[0](cv::Rect(0,0,200,200));cv::normalize(src2s[0],src2s[0],0,1,CV_MINMAX);//cv::normalize(src2s[0],src2s[0],0,1,CV_MINMAX);cv::namedWindow("test");cv::imshow("test",src2s[0]);cv::waitKey();int xx=0,yy=0;pingyi(src1s[0],src2s[0],xx,yy);cout<<xx<<"     "<<yy<<endl;*/return 0;}void test(cv::Mat in,cv::Mat out){IplImage ss=in;IplImage tt=in;IplImage *src=&in.operator IplImage();          //源图像IplImage *Image=&out.operator IplImage();IplImage *Fourier;   //傅里叶系数IplImage *dst ;IplImage *ImageRe;IplImage *ImageIm;IplImage *ImageIm1;IplImage *ImageDst;double m,M;double scale;double shift;//src = cvLoadImage("lena.bmp",0);   //加载源图像,第二个参数表示将输入的图片转为单信道 Fourier = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,2);dst = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,2);ImageRe = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,1);ImageIm = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,1);ImageIm1 = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,1);//Image = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);ImageDst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);fft2(src,Fourier);                  //傅里叶变换fft2shift(Fourier, Image);          //中心化//cvDFT(Fourier,dst,CV_DXT_INV_SCALE);//实现傅里叶逆变换,并对结果进行缩放cvSplit(dst,ImageRe,ImageIm,0,0);//cvNamedWindow("源图像",0);//cvShowImage("源图像",src);             //对数组每个元素平方并存储在第二个参数中cvPow(ImageRe,ImageRe,2);               cvPow(ImageIm,ImageIm1,2);cvAdd(ImageRe,ImageIm1,ImageRe,NULL);cvPow(ImageRe,ImageRe,0.5);cvMinMaxLoc(ImageRe,&m,&M,NULL,NULL);scale = 255/(M - m);shift = -m * scale;//将shift加在ImageRe各元素按比例缩放的结果上,存储为ImageDstcvConvertScale(ImageRe,ImageDst,scale,shift);cvNormalize(ImageIm,ImageIm, 0, 1, CV_MINMAX);//cvNamedWindow("傅里叶谱",0);//cvShowImage("傅里叶谱",Image);//cvNamedWindow("傅里叶逆变换",0);//cvShowImage("傅里叶逆变换",ImageDst);//cvNamedWindow("test",0);//cvShowImage("test",ImageIm);cvWaitKey(0);//cvReleaseImage(&src);//cvReleaseImage(&Image);cvReleaseImage(&ImageIm);cvReleaseImage(&ImageRe);cvReleaseImage(&Fourier);cvReleaseImage(&dst);cvReleaseImage(&ImageDst);    //    cvDestroyAllWindows();}void fourier(cv::Mat in,cv::Mat &out_re,cv::Mat &out_im){Mat planes[] = {Mat_<float>(in), Mat::zeros(in.size(), CV_32FC1)};Mat complexI;merge(planes, 2, complexI); cv::dft(complexI, complexI);cv::split(complexI, planes);out_re=planes[0];out_im=planes[1];}void gonglvpu(cv::Mat in1,cv::Mat in2,cv::Mat out){cv::magnitude(in1,in2,out);/*IplImage data_1=in1;IplImage data_2=in2;IplImage data_3=out;IplImage* pI1  = &in1.operator IplImage();IplImage* pI2  = &in2.operator IplImage();IplImage* pI3  = &out.operator IplImage();cvPow(pI1,pI1,2);cvPow(pI2,pI2,2);cvAdd(pI1,pI2,pI3);cvPow(pI3,pI3,0.5);*/}void pingyi(cv::Mat in_1,cv::Mat in_2,int &x,int &y){cv::Mat padded=in_1;Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};Mat complexI;merge(planes, 2, complexI); cv::dft(complexI, complexI);cv::split(complexI, planes);//////////////////////////////////cv::Mat padded2=in_2;Mat planes2[] = {Mat_<float>(padded2), Mat::zeros(padded2.size(), CV_32F)};Mat complexI2;merge(planes2, 2, complexI2); cv::dft(complexI2, complexI2);cv::split(complexI2, planes2);//cv::normalize(planes[1],planes[1], 0, 1, CV_MINMAX);//////////////////////////////////////////////////////////src1变换后实部 planes[0]   虚部planes[1]//src2变换后实部 planes2[0]  虚部planes2[1]//互功率谱存放矩阵 实部  planes3[0]   虚部planes3[1]//////////////////////////////////////////////////////////Mat planes3[] = {Mat::zeros(in_1.size(), CV_32F), Mat::zeros(in_1.size(), CV_32F)};for(int i=0;i<in_1.rows-1;i++){for(int j=0;j<in_1.cols-1;j++){double r1=planes[0].at<float>(j,i);//获取像素值double i1=planes[1].at<float>(j,i);double r2=planes2[0].at<float>(j,i);double i2=planes2[1].at<float>(j,i);double r3    =r1*r2+i1*i2;//计算互功率谱的值 double i3    =r1*i2-r2*i1;double abs   =sqrt((r3*r3)+(i3*i3));double r_exp =r3/abs;double i_exp =i3/abs;planes3[0].at<float>(j,i)=r_exp;planes3[1].at<float>(j,i)=i_exp;}}Mat complexI3;merge(planes3, 2, complexI3);cv::dft(complexI3,complexI3,CV_DXT_INV_SCALE);cv::split(complexI3,planes3);magnitude(planes3[0], planes3[1], planes3[0]);complexI3=planes3[0];complexI3 += Scalar::all(1); log(complexI3, complexI3);cv::normalize(complexI3,complexI3, 0, 1, CV_MINMAX);double max=0,min=0;cv::Point minLoc,maxLoc;cv::minMaxLoc(complexI3,&min,&max,&minLoc,&maxLoc);//cv::imwrite("complexI3.bmp",complexI3);x=maxLoc.x;y=maxLoc.y;cout<<min<<"   "<<max<<endl;cout<<complexI3.at<float>(maxLoc)<<endl;}void cart2polar(cv::Mat in,cv::Mat &out){IplImage tmp1=in;IplImage* pI1  = &in.operator IplImage();IplImage tmp2=out;IplImage* pI2  = &out.operator IplImage();cvLogPolar( pI1, pI2, cvPoint2D32f(pI1->width/2,pI1->height/2), 40, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS );//cvReleaseImage(&pI1);//cvReleaseImage(&pI2);}void polar2cart(cv::Mat in,cv::Mat out){IplImage tmp1=in;IplImage* pI1  = &in.operator IplImage();IplImage tmp2=out;IplImage* pI2  = &out.operator IplImage();cvLogPolar( pI1, pI2, cvPoint2D32f(pI1->width/2,pI1->height/2), 40, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS+CV_WARP_INVERSE_MAP );}void fft2(IplImage *src, IplImage *dst){  IplImage *image_Re = 0, *image_Im = 0, *Fourier = 0; //实部、虚部image_Re = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);  //实部image_Im = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);  //虚部Fourier = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 2);//2 channels (image_Re, image_Im)cvConvertScale(src, image_Re, 1, 0);// Real part conversion from u8 to 64f (double)cvZero(image_Im);// Imaginary part (zeros)cvMerge(image_Re, image_Im, 0, 0, Fourier);// Join real and imaginary parts and stock them in Fourier imagecvDFT(Fourier, dst, CV_DXT_FORWARD);// Application of the forward Fourier transformcvReleaseImage(&image_Re);cvReleaseImage(&image_Im);cvReleaseImage(&Fourier);}void fft2shift(IplImage *src, IplImage *dst){IplImage *image_Re = 0, *image_Im = 0;int nRow, nCol, i, j, cy, cx;double scale, shift, tmp13, tmp24;image_Re = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);image_Im = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);cvSplit( src, image_Re, image_Im, 0, 0 );//具体原理见冈萨雷斯数字图像处理p123// Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)//计算傅里叶谱cvPow( image_Re, image_Re, 2.0);cvPow( image_Im, image_Im, 2.0);cvAdd( image_Re, image_Im, image_Re);cvPow( image_Re, image_Re, 0.5 );//对数变换以增强灰度级细节(这种变换使以窄带低灰度输入图像值映射一宽带输出值,具体可见冈萨雷斯数字图像处理p62)// Compute log(1 + Mag);cvAddS( image_Re, cvScalar(1.0), image_Re ); // 1 + MagcvLog( image_Re, image_Re ); // log(1 + Mag)//Rearrange the quadrants of Fourier image so that the origin is at the image centernRow = src->height; nCol = src->width;cx = nCol/2; cy = nRow/2; // image center//CV_IMAGE_ELEM为OpenCV定义的宏,用来读取图像的像素值,这一部分就是进行中心变换for( j = 0; j < cy; j++ ){for( i = 0; i < cx; i++ ){//中心化,将整体份成四块进行对角交换tmp13 = CV_IMAGE_ELEM( image_Re, double, j, i);CV_IMAGE_ELEM( image_Re, double, j, i) = CV_IMAGE_ELEM(image_Re, double, j+cy, i+cx);CV_IMAGE_ELEM( image_Re, double, j+cy, i+cx) = tmp13;tmp24 = CV_IMAGE_ELEM( image_Re, double, j, i+cx);CV_IMAGE_ELEM( image_Re, double, j, i+cx) =CV_IMAGE_ELEM( image_Re, double, j+cy, i);CV_IMAGE_ELEM( image_Re, double, j+cy, i) = tmp24;}}//归一化处理将矩阵的元素值归一为[0,255]//[(f(x,y)-minVal)/(maxVal-minVal)]*255double minVal = 0, maxVal = 0;// Localize minimum and maximum valuescvMinMaxLoc( image_Re, &minVal, &maxVal );// Normalize image (0 - 255) to be observed as an u8 imagescale = 255/(maxVal - minVal);shift = -minVal * scale;cvConvertScale(image_Re, dst, scale, shift);cvReleaseImage(&image_Re);cvReleaseImage(&image_Im);}/*for(int i=0;i<500;i++){for(int j=0;j<500;j++){if(i%20==0&&j%20==0)cout<<src1_f_re.at<float>(i,j)<<endl;}}*//*string name1="lena.bmp";string name2="90du.bmp";cv::Mat src1=imread(name1);if(src1.channels()!=1)cv::cvtColor(src1,src1,CV_RGB2GRAY);cv::Mat src1_f_re   =cv::Mat::zeros(src1.size(),CV_32FC1);cv::Mat src1_f_im   =cv::Mat::zeros(src1.size(),CV_32FC1);cv::Mat src1_gonglv =cv::Mat::zeros(src1.size(),CV_32FC1);cv::Mat src1_g_log  =cv::Mat::zeros(src1.size(),CV_32FC1);fourier(src1,src1_f_re,src1_f_im);gonglvpu(src1_f_re,src1_f_im,src1_gonglv);cart2polar(src1_gonglv,src1_g_log);cv::normalize(src1_g_log,src1_g_log, 0, 1, CV_MINMAX);cv::Mat src2=imread(name2);if(src2.channels()!=1)cv::cvtColor(src2,src2,CV_RGB2GRAY);cv::Mat src2_f_re   =cv::Mat::zeros(src2.size(),CV_32FC1);cv::Mat src2_f_im   =cv::Mat::zeros(src2.size(),CV_32FC1);cv::Mat src2_gonglv =cv::Mat::zeros(src2.size(),CV_32FC1);cv::Mat src2_g_log  =cv::Mat::zeros(src2.size(),CV_32FC1);fourier(src2,src2_f_re,src2_f_im);gonglvpu(src2_f_re,src2_f_im,src2_gonglv);cart2polar(src2_gonglv,src2_g_log);cv::normalize(src2_g_log,src2_g_log, 0, 1, CV_MINMAX);int gx=0,gy=0;pingyi(src1_gonglv,src2_gonglv,gx,gy);//cout<<"max  "<<max<<"  min  "<<min<<endl;cout<<gx<<"   "<<gy<<endl;//pingyi(src1,src2,gx,gy);*/


0 0
原创粉丝点击