Opencv矩阵的每元素操作
Opencv matrix per-element operation
我有一个cv::Mat
,我想对每个元素做一些操作。例如,我有一个像cv::Mat m(100,100, CV_64F);
这样的浮点矩阵。我有另一个函数,如下所示:
double fun(double elem);
如何将此函数应用于矩阵,该矩阵可以执行逐元素操作
你可以这样做:
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)检查你的垫子是否连续
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)
简单的循环呢?
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));
如果你使用openv库的发布版本,这是相当快的。如果你可以改变源函数它会改变参数本身而不是以函数的形式返回
void fun(double &elem);
可以省略一个at()调用:
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));
为矩阵设计一个通用的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
相关文章:
- 对字符数组中的元素执行逐位操作
- 对 Vector 元素 (C++) 的push_back操作
- 使用现代C++在 Eigen3 矩阵上使用 for 循环进行元素操作的优雅方式
- Qt,操作缓慢时不要冻结GUI输入元素
- blaze-lib 的元素操作是否自动并行?
- 为什么用于阈值矩阵元素的 Matlab 逻辑索引操作在性能上优于 mex 实现?
- 根据堆栈操作 c++ 计算元素的最大数量
- 如何在C 对向量的第二个元素上执行较低的操作
- 阵列操作,复制最后一个元素
- 向量元素数据损坏了Find()操作
- 数组A中最大的元素数量可以通过使用操作最多可将其降低至1
- 如何在语义操作中访问元组的元素
- 在remove_if删除元素之前,我可以滥用谓词对元素执行操作吗
- 使用对其他枚举值的操作定义枚举元素值
- 在 CUDA / 推力中,如何在每个操作期间访问矢量元素的邻居?
- C++ 特征 - 如何将广播和元素操作结合起来
- C++中的元素操作
- 关于 boost::ubla 中的逐元素操作
- 无循环的特征元素操作
- Opencv矩阵的每元素操作