Ask Your Question
0

Complex conjugate

asked 2013-10-29 09:41:06 -0600

lapis gravatar image

updated 2013-11-02 05:54:47 -0600

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?

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
1

answered 2013-10-29 11:14:36 -0600

stereomatching gravatar image

updated 2013-10-29 16:22:00 -0600

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.

edit flag offensive delete link more

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 ( 2013-10-29 12:13:05 -0600 )edit

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

lapis gravatar imagelapis ( 2013-10-29 13:56:33 -0600 )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 ( 2013-10-29 14:04:00 -0600 )edit
0

answered 2013-11-01 13:41:17 -0600

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.

edit flag offensive delete link more

Question Tools

Stats

Asked: 2013-10-29 09:41:06 -0600

Seen: 3,921 times

Last updated: Nov 01 '13