Reputation: 187
I have a matrix cv::mat A
.
Is there an easy way to check if all elements of this matrix are positive or equal to 0, and return a True boolean if this condition is true?
Upvotes: 3
Views: 2527
Reputation: 6465
@francesco answer is nice in terms of C++, but not really effective nor functional tho.
More effective method is using OpenCV built-in operation called checkRange(), it also provides position of first invalid element and support for multi-channel array.
Example usage:
cv::Point *pos;
bool is_ok = cv::checkRange( A, pos, 0, DBL_MAX );
As @MarkSetchell suggested in comments, you might also find minimum value in matrix and see if it is non-negative. There is one OpenCV operation on array called minMaxLoc()
which unfortunately doesn't work with multi-channel arrays, so you would have to reinterper whole array as single channel, first.
double min;
cv::minMaxLoc( A.reshape(1), &min );
To make francescos solution work, you have to specify cv::Mat
type to iterators, eg. for CV_8U
type of matrix
bool is_all_positive = (std::find_if(m.begin<uchar>(), m.end<uchar>(),
[](auto x) { return (x < 0); }) == m.end<uchar>());
As I previously said, this is not effective approach and would be (in my opinion) more useable than checkRange()
just in case we would like to compare values of specific channels - e.g. checking only for values of blue color in BGR image
bool is_all_positive = (std::find_if(m.begin<cv::Vec3b>(), m.end<cv::Vec3b>(),
[](auto x) { return (x[0] < 0); }) == m.end<cv::Vec3b>());
Upvotes: 2
Reputation: 7539
To have an efficient method, rather than using procedures that iterate over all elements of the matrix, you should use a method that stops as soon as a condition is found. You can use std::find_if
#include <algorithm>
bool is_all_positive = (std::find_if(A.begin(), A.end(),
[](auto x) { return (x < 0); }) == A.end());
Upvotes: 1