First time here? Check out the FAQ!

Ask Your Question
0

Complex conjugate

asked Oct 29 '13

lapis gravatar image

updated Nov 2 '13

berak gravatar image

Is there no function to get a complex conjugate of a Mat? It's rather easy to implement myself but is it such a rare problem?

Preview: (hide)

2 answers

Sort by » oldest newest most voted
1

answered Oct 29 '13

stereomatching gravatar image

updated Oct 29 '13

please give

cv::Mat_<std::complex<int>> mat;

a try.

doc

using CP = std::complex<int>;

cv::Mat_<CP> mat(2, 2);
mat.at<CP>(0, 0) = CP(3, 5);
mat.at<CP>(0, 1) = CP(3, 6);
mat.at<CP>(1, 0) = CP(3, 7);
mat.at<CP>(1, 1) = CP(3, 8);
std::cout<<mat<<std::endl;
mat.at<CP>(0, 0) = std::conj(mat.at<CP>(0, 0));
std::cout<<mat<<std::endl;

//Make all of the mat become conjugate
OCV::for_each_channels<CP>(mat, [](CP &a)
{
      a = std::conj(a);
} );
std::cout<<mat<<std::endl;

implementation of for each

/**
 *@brief apply stl like for_each algorithm on a channel
 *
 * @param T : the type of the channel(ex, uchar, float, double and so on)
 * @param func : Unary function that accepts an element in the range as argument
 *
 *@return :
 *  return func
 */
template<typename T, typename UnaryFunc, typename Mat>
UnaryFunc for_each_channels(Mat &&input, UnaryFunc func)
{
    int rows = input.rows;
    int cols = input.cols;

    if(input.isContinuous()){
        cols = input.total() * input.channels();
        rows = 1;
    }

    for(int row = 0; row != rows; ++row){
        auto begin = input.template ptr<T>(row);
        auto end = begin + cols;
        while(begin != end){
            func(*begin);
            ++begin;
        }
    }

    return func;
}

std::complex support many operations, you could use the generic for_each loop to implement your codes

template<typename T>
inline void conj_mat(cv::Mat_<std::complex<T>> &mat)
{
  for_each_channels<std::complex<T>>(mat, [](std::complex<T> &a){ a = std::conj(a); });
}

If you need more speed, take a look on this post.

Preview: (hide)

Comments

Thanks for the reminder of this usage but it doesn't solve the problem. I think I've found a solution so I'll post it as an answer (when I'm allowed to...).

lapis gravatar imagelapis (Oct 29 '13)edit

The extended answer does solve it, thank you. Although it will take some rewriting if C++11 is not available.

lapis gravatar imagelapis (Oct 29 '13)edit

Everything are easy to fall back to c++98, 03 except of rvalue reference.I use rvalue reference because it could accept const& and & cv::Mat.Without &&, I have to do some overloading on the function(write two times), or wrap the cv::Mat by something like std::ref(boost::ref), std::cref(boost::cref).c++11 do make c++ become easier to write and learn.

stereomatching gravatar imagestereomatching (Oct 29 '13)edit
0

answered Nov 1 '13

lapis gravatar image

Seems like OpenCV only supports one usage of complex conjugates, though the most common one: calculation of correlation in the frequency space. See mulSpectrums, the conjB parameter.

Preview: (hide)

Question Tools

Stats

Asked: Oct 29 '13

Seen: 4,087 times

Last updated: Nov 01 '13