opencv进行复数的乘除法运算

引言

由于opencv自身不带有复数计算功能,但我又经常需要进行复数运算,所以我只能自己写两个函数来进行复数的乘除法运算。

opencv中的复数表示

复数包含了实部和虚部,在opencv中是使用一个二通道的Mat对象来存放一个复数数组,两个通道分别存储复数的实部和虚部,图像傅里叶变换的结果就是一个使用二通道数组存放的复数数组。比如一个复数:
[ 0 + 0 j 0 + j 1 + 0 j 1 + j ] \begin{bmatrix} 0+0j&0+j\\ 1+0j&1+j \end{bmatrix} [0+0j1+0j0+j1+j]
这个复数就可以存放在Mat对象里面,存放方法如下:

Mat complex(2, 2, CV_64FC2);//二通道数组
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 2; j++) {
			complex.at<double>(i, 2 * j) = i;
			complex.at<double>(i, 2 * j + 1) = j;
		}
	}

复数乘法

两复数 a + b j a+bj a+bj c + d j c+dj c+dj相乘,公式如下:
( a + b j ) ( c + d j ) = a c − b d + ( b c + a d ) j (a+bj)(c+dj)=ac-bd+(bc+ad)j (a+bj)(c+dj)=acbd+(bc+ad)j
现在两个复数数组要想进行复数乘法运算,可以先将两个复数进行通道分离,再通过复数乘法公式进行处理即可。代码如下:

Mat Mult(Mat input1, Mat input2)
{
	if ((input1.channels() != 2) | (input2.channels() != 2)) {
		std::cout << "输入数组应该为包含实部和虚部的二通道数组" << std::endl;
		return Mat();
	}
	Mat src1 = input1.clone();
	Mat src2 = input2.clone();
	Mat F[2];//分别存放实部和虚部
	split(src1, F);//a=F[0],b=F[1]
	Mat G[2];
	split(src2, G);//c=G[0],d=G[1];
	Mat ac;
	multiply(F[0], G[0], ac);//multiply实现矩阵的点乘
	Mat bd;
	multiply(F[1], G[1], bd);
	Mat Real = ac - bd;//得到的结果的实部
	Mat ad;
	multiply(F[0], G[1], ad);
	Mat bc;
	multiply(F[1], G[0], bc);
	Mat Im = ad + bc;
	Mat value[2] = { Real,Im };
	Mat result;
	merge(value, 2, result);
	return result;
}

复数除法

两复数 a + b j a+bj a+bj c + d j c+dj c+dj相除,公式如下:
( a + b j ) / ( c + d j ) = [ a c + b d + ( b c − a d ) j ] / ( c 2 + d 2 ) (a+bj)/(c+dj)=[ac+bd+(bc-ad)j]/{(c^2+d^2)} (a+bj)/(c+dj)=[ac+bd+(bcad)j]/(c2+d2)
现在两个复数数组要想进行复数除法运算,一样的先将两个复数进行通道分离,再通过复数除法公式进行处理即可。代码如下:

Mat Div(Mat input1, Mat input2)
{
	if ((input1.channels() != 2) | (input2.channels() != 2)) {
		std::cout << "输入数组应该为包含实部和虚部的二通道数组" << std::endl;
		return Mat();
	}
	Mat src1 = input1.clone();
	Mat src2 = input2.clone();
	Mat F[2];//分别存放实部和虚部
	split(src1, F);
	Mat G[2];
	split(src2, G);
	Mat a = F[0];
	Mat b = F[1];
	Mat c = G[0];
	Mat d = G[1];
	Mat c2;
	multiply(c, c, c2);
	Mat d2;
	multiply(d, d, d2);
	Mat ac;
	multiply(a, c, ac);
	Mat bd;
	multiply(b, d, bd);
	Mat bc;
	multiply(b, c, bc);
	Mat ad;
	multiply(a, d, ad);
	Mat real;
	divide(ac + bd, c2 + d2, real);
	Mat im;
	divide(bc - ad, c2 + d2, im);
	Mat value[2] = { real,im };
	Mat result;
	merge(value, 2, result);
	return result;
}

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值