本代码可以实现在VS2010环境下的平移参数计算和后期融合
但无法在ARM平台实现
// fourier.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;
int main()
{
string name1;
string name2;
cout<<"请输入参考图象文件名"<<endl;
cin>>name1;
cout<<"请输入浮动图像文件名"<<endl;
cin>>name2;
/////////////////////////////////
double time_0=cv::getTickCount()/cv::getTickFrequency();
cv::Mat src1=cv::imread(name1,0);
cv::Mat padded=src1;
Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
Mat complexI,complexI_fft;
merge(planes, 2, complexI);
cv::dft(complexI, complexI_fft);
cv::split(complexI_fft, planes);
//////////////////////////////////
cv::Mat src2=cv::imread(name2,0);//读取输入图像
cv::Mat padded2=src2;
//cv::Mat dst2=cv::Mat::zeros(src2.size(),CV_32FC2);
Mat planes2[] = {Mat_<float>(padded2), Mat::zeros(padded2.size(), CV_32F)};
Mat complexI2,complexI2_fft;
merge(planes2, 2, complexI2);
cv::dft(complexI2, complexI2_fft);
cv::split(complexI2_fft, 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(src1.size(), CV_32F), Mat::zeros(src1.size(), CV_32F)};
for(int i=0;i<src1.rows-1;i++)
{
for(int j=0;j<src1.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;
}
}
//magnitude(planes3[0], planes3[1], planes3[0]);
//Mat complexI3=planes3[0];
//cv::Mat =cv::Mat::zeros(dst.size(),dst.type());
//cv::flip(complexI3,complexI3,-1);
Mat complexI3,complexI3_fft;
merge(planes3, 2, complexI3);
cv::dft(complexI3,complexI3_fft,CV_DXT_INV_SCALE);
cv::split(complexI3_fft,planes3);
magnitude(planes3[0], planes3[1], planes3[0]);
cv::Mat magI,magI_1,magI_log;
planes3[0].copyTo(magI);
//complexI3=planes3[0];
//cv::add(complexI3,cv::Scalar(1.0),complexI3,NULL);
//cv::log(complexI3,complexI3);
magI_1= magI+Scalar::all(1);
log(magI_1, magI_log);
cv::Mat magI_nom_1;
cv::normalize(magI_log,magI_nom_1, 0, 1, CV_MINMAX);
/*
complexI3 = complexI3(Rect(0, 0, complexI3.cols & -2, complexI3.rows & -2));
int cx = complexI3.cols/2;
int cy = complexI3.rows/2;
Mat q0(complexI3, Rect(0, 0, cx, cy)); // Top-Left - 为每一个象限创建ROI
Mat q1(complexI3, Rect(cx, 0, cx, cy)); // Top-Right
Mat q2(complexI3, Rect(0, cy, cx, cy)); // Bottom-Left
Mat q3(complexI3, Rect(cx, cy, cx, cy)); // Bottom-Right
Mat tmp; // 交换象限 (Top-Left with Bottom-Right)
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp); // 交换象限 (Top-Right with Bottom-Left)
q2.copyTo(q1);
tmp.copyTo(q2);
*/
double max=0,min=0;
cv::Point minLoc,maxLoc;
cv::minMaxLoc(magI_nom_1,&min,&max,&minLoc,&maxLoc);
//cv::imwrite("complexI3.bmp",complexI3);
double time_pingyi=cv::getTickCount()/cv::getTickFrequency()-time_0;
cout<<"max "<<max<<" min "<<min<<endl;
cout<<maxLoc.x<<" "<<maxLoc.y<<endl;
cout<<"计算平移参数所需时间为 "<<time_pingyi<<"s"<<endl;
cv::Mat matrix=cv::Mat::zeros(2,3,CV_32FC1);
matrix.at<float>(0,2)=maxLoc.x;
matrix.at<float>(1,2)=maxLoc.y;
matrix.at<float>(0,0)=1;
matrix.at<float>(1,1)=1;
//cout<<"value "<<src2.at<float>(1,14)<<endl;
cv::Mat src =cv::imread(name1,0);
cv::Mat jiaquanqian =cv::Mat::zeros(src.size(),CV_32FC1);
//src.copyTo(jiaquanqian);
cv::Mat jiaquanhou =cv::Mat::zeros(src.size(),CV_32FC1);
cv::Mat bianhuanqian=cv::imread(name2,0);
cv::Mat bianhuanhou =cv::Mat::zeros(bianhuanqian.size(),CV_32FC1);
for(int j=0;j<bianhuanhou.rows-1;j++)
{
for(int i=0;i<bianhuanhou.cols-1;i++)
{
int qian_y=i+maxLoc.x, qian_x=j+maxLoc.y;
if(qian_x<0||qian_y<0||qian_x>bianhuanqian.cols-1||qian_y>bianhuanhou.rows-1)
{
bianhuanhou.at<float>(j,i)=0;
}
else
{
int value_u=bianhuanqian.at<uchar>(qian_x,qian_y);
float value_f=(float)value_u;
bianhuanhou.at<float>(j,i)=value_f;
}
}
}
cv::imwrite("bianhuanhou.bmp",bianhuanhou);
cv::Mat bianhuanhou_nom_255;
cv::normalize(bianhuanhou,bianhuanhou_nom_255,0,255,CV_MINMAX);
cv::imwrite("bianhuanhou_nom_255.bmp",bianhuanhou_nom_255);
//cv::namedWindow("bianhuanhou");
//cv::imshow("bianhuanhou",bianhuanhou);
for(int j=0;j<bianhuanhou.rows-1;j++)
{
for(int i=0;i<bianhuanhou.cols-1;i++)
{
float tmp=src.at<uchar>(j,i);
jiaquanqian.at<float>(j,i)=tmp;
float jiaquan_value=bianhuanhou.at<float>(j,i);
if(jiaquan_value==0)
{
jiaquanhou.at<float>(j,i)=jiaquanqian.at<float>(j,i);
}
else
{
float tmp=src.at<uchar>(j,i);
jiaquanqian.at<float>(j,i)=tmp;
float aa=jiaquanqian.at<float>(j,i);
float bb=bianhuanhou.at<float>(j,i);
jiaquanhou.at<float>(j,i)=(aa+bb)/2;
}
}
}
double time_all=cv::getTickCount()/cv::getTickFrequency()-time_0;
double time_ronghe=time_all-time_pingyi;
cout<<"图像融合所需时间为 "<<time_ronghe<<"s"<<endl;
cout<<"程序运行总时间时间为 "<<time_all<<"s"<<endl;
//imgaffine(src2,src2,matrix);
cv::imwrite("jiaquanhou.bmp",jiaquanhou);
cv::Mat jiaquanhou_nom_255,jiaquanhou_nom_1;
cv::normalize(jiaquanqian,jiaquanhou_nom_255,0,255,CV_MINMAX);
cv::imwrite("jiaquanhou0-255.bmp",jiaquanhou_nom_255);
//cv::namedWindow("jiaquanqian");
//cv::imshow("jiaquanqian",src);
cv::normalize(jiaquanhou,jiaquanhou,0,1,CV_MINMAX);
cv::imwrite("jiaquanhou_nom_1.bmp",jiaquanhou_nom_1);
for(int i=0;i<510;i++)
{
for(int j=0;j<510;j++)
{
if(i%30==0&&j%30==0)
cout<<jiaquanhou_nom_255.at<float>(i,j)<<endl;
}
}
//cv::namedWindow("jiaquanhou");
//cv::imshow("jiaquanhou",jiaquanhou);
cv::waitKey();
return 0;
}