Is there a simple way to set all values in a cv::Mat to a given value if they fulfill some condition. For instance, I have CV_32FC1, and I want set all values which are 0 to 20. In MATLAB I would have simply done this:
M(M == 0) = 20;
Is there a simple way to set all values in a cv::Mat to a given value if they fulfill some condition. For instance, I have CV_32FC1, and I want set all values which are 0 to 20. In MATLAB I would have simply done this:
M(M == 0) = 20;
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.
(mask > 2) & (mask < 5)
–
Adamant 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);
.
.
.
}
© 2022 - 2024 — McMap. All rights reserved.
cv::Mat newMask = mask <= 2;
but this does notcv::Mat newMask = mask > 2 && mask < 5;
– Zuckerman