OpenCV cv::Mat set if

二次信任 提交于 2019-11-29 09:39:36

You can use

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

However, it includes using additional memory for creating mask, but is a solution using opencv API therefore can be applied to all matrix types. If you consider performance issues, you can always refer directly to Mat::data to optimize this solution for concrete matrix type.

This is a classic case for look-up table. It is fast, simple, and can remap multiple values at same time.

Thanks to @marol 's comments, I settled for the implementation below. I am using C++11 lambda functions to condition which values need to be changed. To demonstrate its power, my condition is to set to DEFAULT_VAL when the value is out of the range [MIN_VAL, MAX_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);
  .
  .
  .
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!