OpenCV中的cv::Mat如何进行设置?

13

如果满足某些条件,是否有一种简单的方法将cv :: Mat中的所有值设置为给定值。例如,我有一个CV_32FC1矩阵,并且我想将所有值为0的值设置为20。在MATLAB中,我会这样做:

M(M == 0) = 20;
3个回答

21

你可以使用

cv::Mat mask = M == 0;
M.setTo(0.5, mask);

然而,这种方法需要使用额外的内存来创建掩码,但由于使用了opencv API,因此可以应用于所有矩阵类型。如果考虑性能问题,您可以直接参考Mat::data,以针对具体的矩阵类型对该解决方案进行优化。


1
这太强大了!只需使表达式的第二部分更复杂,就可以用于阈值处理等。似乎在文档或教程中找不到这个。我们应该推广这篇文章,让人们知道如何使用它!不幸的是,它似乎不能与复合表达式一起使用——即这个可以:cv::Mat newMask = mask <= 2;但这个不行:cv::Mat newMask = mask > 2 && mask < 5; - David Doria
@DavidDoria,我现在想到的方法是使用两个额外的临时掩模,即cv::Mat maskGreaterThan2 = M > 2; cv::Mat maskLessThan5 = M < 5; cv::Mat mask = massGreaterThan2 & maskLessThan5。不幸的是,与我们在这里实现的生产力收益相比,这真的很耗费内存和时间。 - marol
@DavidDoria 试试这个:(mask > 2) & (mask < 5) - rob3c

3
这是一个典型的应用 查找表 的案例。它快速、简单,可以同时重新映射多个值。

2

感谢@marol的评论,我采用了下面的实现。我使用C++11 lambda函数来条件判断哪些值需要更改。为了展示其威力,我的条件是当值超出范围[MIN_VAL, MAX_VAL]时设置为DEFAULT_VAL

#include <functional>

#define MatType float
#define MatCmpFunc std::function<bool(const MatType&)>
.
.
.
// function which accepts lambda function to condition values which need to
// be changed
void MatSetIf(cv::Mat& inputmat, const MatType& newval, MatCmpFunc func) {
  float* pmat = (float*)inputmat.data;
  // iterate and set only values which fulfill the criteria
  for (int idx = 0; idx < inputmat.total(); ++idx) {
    if (func(pmat[idx])) {
      pmat[idx] = newval;
    }
  }
}
.
.
.
void main() {
  cv::Mat mymat(100,100,CV_32FC1);
  const float MIN_VAL = 10;
  const float MAX_VAL = 1000;
  const float DEFAULT_VAL = -1;
  .
  .
  .
  // declare lambda function which returns true when mat value out of range
  MatCmpFunc func = [&](const DepthMatType& val) -> bool {
    return (val < MIN_VAL || val > MAX_VAL) ? true : false;
  };
  // use lambda func above to set all out of range values to 50
  Mat32FSetIf(mymat, DEFAULT_VAL, func);
  .
  .
  .
}

3
这部分是我所说的直接访问Mat::data。在调试模式下使用at()肯定比setTo()慢,因此如果你决定使用这种解决方案,并且你有特定的矩阵类型,我建议不要制作通用模板函数,而是制作直接操作Mat::data的具体函数(正如OpenCV文档所说,“在优化方面,没有什么能够超越C数组操作符[]”)。 - marol
谢谢@marol...两条评论都非常有帮助 :) - ahmadh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接