Reputation: 193
I am attempting to implement a complex-valued matrix equation in OpenCV. I've prototyped in MATLAB which works fine. Starting off with the equation (exact MATLAB implementation):
kernel = exp(1i .* k .* Circ3D) .* z ./ (1i .* lambda .* Circ3D .* Circ3D)
In which
1i = complex number
k = constant (float)
Circ3D = real-valued matrix of known size
lambda = constant (float)
.* = element-wise multiplication
./ = element-wise division
The result is a complex-valued matrix. I succeeded in generating the necessary Circ3D matrix as a CV_32F, however the multiplication by the complex number i is giving me trouble. From the OpenCV documentation I understand that a complex matrix is simply a two-channel matrix (CV_32FC2).
The real trouble comes from how to define i. I've tried several options, among which defining i as
cv::Vec2d complex = cv::Vec2d(0,1);
and then multiplying by the matrix
kernel = complex * Circ3D
But this doesn't work (although I didn't expect it to). I suspect I need to do something with std::complex but I have no idea what (http://docs.opencv.org/modules/core/doc/basic_structures.html).
Thanks in advance for any help.
Edit: Just after writing this post I did make some progress, by defining i as follows:
std::complex<float> complex(0,1)
I am then able to assign complex values as follows:
kernel.at<std::complex<float>>(i,j) = cv::exp(complex * k * Circ3D.at<float>(i,j)) * ...
z / (complex * lambda * pow(Circ3D.at<float>(i,j),2));
However, this works in a loop, which makes the procedure incredibly slow. Any way to do it in one go?
Upvotes: 2
Views: 5913
Reputation: 4378
There is also the function mulSpectrums, which lets you do element wise multiplication of complex matrices. So if K is your kernel matrix and I is some complex matrix, that is, CV_32FC2 (float two channel) you can do the following to compute the element wise multiplication,
// Make K a complex matrix
cv::Mat Ktmp[] = {cv::Mat_<float>(K), cv::Mat::zeros(K.size(), CV_32FC1)};
cv::Mat Kc;
cv::merge(Ktmp,2,Kc);
// Do matrix multiplication
cv::mulSpectrums(Kc,I,I,0);
Upvotes: 3
Reputation: 21749
OpenCV treats std::complex
just like the simple pair of numbers (see example in the documentation). No special rules on arithmetic operations are applied. You overcome this by multiplying std::complex
directly. So basically, this is simple: you either chose automatic complex arithmetic (as you are doing now), or automatic vectorization (when using OpenCV functions on matrices).
I think, in your case you should carry all the complex arithmetic by yourself. Store matrix of complex values C{ai + b}
as two matrices A{a}
and B{b}
. Implement exponentiation by yourself. Multiplication on scalars and addition shouldn't be a problem.
Upvotes: 3