opencv-图像的融合

本文介绍了一种在VS2010环境下利用OpenCV库进行图像平移参数计算的方法,并实现了图像后期融合。通过输入两幅图像,程序能够计算出平移参数并完成图像融合,但此方法不适用于ARM平台。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本代码可以实现在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;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值