Opencv矩阵每元素操作

时间:2014-06-17 09:16:04

标签: c++ opencv matrix

我有一个cv::Mat,我想做一些每元素操作。例如,我有一个像cv::Mat m(100,100, CV_64F);这样的浮点矩阵。我有另一个功能如下:

double fun(double elem);

如何将此函数应用于矩阵,该矩阵可以执行每个元素的操作。

4 个答案:

答案 0 :(得分:5)

你可以这样做:

double func(double x)
{
    return(sin(x));
}

int main(void)
{
    Mat M=Mat::eye(3,3,CV_64FC1);
    std::transform(M.begin<double>(),M.end<double>(),M.begin<double>(),func);
    cout << M;
    getchar();
    return 0;
}

答案 1 :(得分:2)

1)检查你的垫子是否连续

if(mat.isContinuous())

2)访问行数据指针并将其转换为double

double* buffer = (double*)mat.data; 
// or
double* buffer = mat.ptr<double>(0);
double *bufferEnd = (double*)mat.end;

3)在缓冲区的每个元素上调用你的函数,例如

 for (; buffer != bufferEnd; ++buffer)
        *buffer = fun(*buffer)

答案 2 :(得分:1)

简单循环怎么样?

cv::Mat m(100, 100, CV_64F);
for(int x=0;x<m.cols;x++)
    for(int y=0;y<m.rows;y++)
        m.at<double>(y,x) = fun(m.at<double>(y,x));

如果您使用opencv库的发行版,这个速度非常快。如果您可以更改有趣的函数源,它会更改参数本身而不是从函数返回它:

void fun(double &elem);

然后您可以在()调用中省略一个:

cv::Mat m(100, 100, CV_64F);
for(int x=0;x<m.cols;x++)
    for(int y=0;y<m.rows;y++)
        fun(m.at<double>(y,x));

答案 3 :(得分:0)

为矩阵设计通用的for循环

/**
 *@brief apply stl like for_each algorithm on every channels
 *
 * @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;
}

按以下方式使用

cv::Mat m(100, 100, CV_64F);
//......initialize m
for_each_channels<double>(m, [](double &a)
{
    a = std::sin(a) * 2.14168;;
});

您也可以将api扩展为支持向量类型

for_each<cv::vec3d>(m, [](cv::vec3d& a)
{
    a = ..... //do something
});

我已经设计了一些通用api,我将它们放在github