OpenCV cv :: Mat set if

Is there an easy way to set all the values ​​in cv :: Mat to a given value if they fulfill some condition. For example, I have CV_32FC1, and I want to set all values ​​from 0 to 20. In MATLAB, I would just do this:

M(M == 0) = 20; 
+6
source share
3 answers

you can use

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

However, it involves using additional memory to create a mask, but the solution using the opencv API can therefore be applied to all types of matrices. If you are considering performance issues, you can always refer directly to Mat :: data to optimize this solution for a particular type of matrix.

+11
source

This is a classic case for a lookup table . It is fast, simple, and can reassign multiple values ​​at the same time.

+3
source

Thanks to the comments of @marol, I settled on the implementation below. I use C ++ 11 lambda functions to determine which values ​​need to be changed. To demonstrate my power, my condition is to set the DEFAULT_VAL value 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); . . . } 
+2
source

All Articles