Merge pull request #22947 from chacha21:hasNonZero
Added cv::hasNonZero() #22947
`cv::hasNonZero()` is semantically equivalent to (`cv::countNonZero()>0`) but stops parsing the image when a non-zero value is found, for a performance gain
- [X] I agree to contribute to the project under Apache 2 License.
- [X] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [X] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
This pull request might be refused, but I submit it to know if further work is needed or if I just stop working on it.
The idea is only a performance gain vs `countNonZero()>0` at the cost of more code.
Reasons why it might be refused :
- this is just more code
- the execution time is "unfair"/"unpredictable" since it depends on the position of the first non-zero value
- the user must be aware that default search is from first row/col to last row/col and has no way to customize that, even if his use case lets him know where a non zero could be found
- the PR in its current state is using, for the ocl implementation, a mere `countNonZero()>0` ; there is not much sense in trying to break early the ocl kernel call when non-zero is encountered. So the ocl implementation does not bring any improvement.
- there is no IPP function that can help (`countNonZero()` is based in `ippCountInRange`)
- the PR in its current state might be slower than a call to `countNonZero()>0` in some cases (see "challenges" below)
Reasons why it might be accepted :
- the performance gain is huge on average, if we consider that "on average" means "non zero in the middle of the image"
- the "missing" IPP implementation is replaced by an "Open-CV universal intrinsics" implementation
- the PR in its current state is almost always faster than a call to `countNonZero()>0`, is only slightly slower in the worst cases, and not even for all matrices
**Challenges**
The worst case is either an all-zero matrix, or a non-zero at the very last position. In such a case, the `hasNonZero()` implementation will parse the whole matrix like `countNonZero()` would do. But we expect the performance to be the same in this case. And `ippCountInRange` is hard to beat !
There is also the case of very small matrices (<=32x32...) in 8b, where the SIMD can be hard to feed.
For all cases but the worse, my custom `hasNonZero()` performs better than `ippCountInRange()`
For the worst case, my custom `hasNonZero()` performs better than `ippCountInRange()` *except for large matrices of type CV_32S or CV_64F* (but surprisingly, not CV_32F).
The difference is small, but it exists (and I don't understand why).
For very small CV_8U matrices `ippCountInRange()` seems unbeatable.
Here is the code that I use to check timings
```
//test cv::hasNonZero() vs (cv::countNonZero()>0) for different matrices sizes, types, strides...
{
cv::setRNGSeed(1234);
const std::vector<cv::Size> sizes = {{32, 32}, {64, 64}, {128, 128}, {320, 240}, {512, 512}, {640, 480}, {1024, 768}, {2048, 2048}, {1031, 1000}};
const std::vector<int> types = {CV_8U, CV_16U, CV_32S, CV_32F, CV_64F};
const size_t iterations = 1000;
for(const cv::Size& size : sizes)
{
for(const int type : types)
{
for(int c = 0 ; c<2 ; ++c)
{
const bool continuous = !c;
for(int i = 0 ; i<4 ; ++i)
{
cv::Mat m = continuous ? cv::Mat::zeros(size, type) : cv::Mat(cv::Mat::zeros(cv::Size(2*size.width, size.height), type), cv::Rect(cv::Point(0, 0), size));
const bool nz = (i <= 2);
const unsigned int nzOffsetRange = 10;
const unsigned int nzOffset = cv::randu<unsigned int>()%nzOffsetRange;
const cv::Point pos =
(i == 0) ? cv::Point(nzOffset, 0) :
(i == 1) ? cv::Point(size.width/2-nzOffsetRange/2+nzOffset, size.height/2) :
(i == 2) ? cv::Point(size.width-1-nzOffset, size.height-1) :
cv::Point(0, 0);
std::cout << "============================================================" << std::endl;
std::cout << "size:" << size << " type:" << type << " continuous = " << (continuous ? "true" : "false") << " iterations:" << iterations << " nz=" << (nz ? "true" : "false");
std::cout << " pos=" << ((i == 0) ? "begin" : (i == 1) ? "middle" : (i == 2) ? "end" : "none");
std::cout << std::endl;
cv::Mat mask = cv::Mat::zeros(size, CV_8UC1);
mask.at<unsigned char>(pos) = 0xFF;
m.setTo(cv::Scalar::all(0));
m.setTo(cv::Scalar::all(nz ? 1 : 0), mask);
std::vector<bool> results;
std::vector<double> timings;
{
bool res = false;
auto ref = cv::getTickCount();
for(size_t k = 0 ; k<iterations ; ++k)
res = cv::hasNonZero(m);
auto now = cv::getTickCount();
const bool error = (res != nz);
if (error)
printf("!!ERROR!!\r\n");
results.push_back(res);
timings.push_back(1000.*(now-ref)/cv::getTickFrequency());
}
{
bool res = false;
auto ref = cv::getTickCount();
for(size_t k = 0 ; k<iterations ; ++k)
res = (cv::countNonZero(m)>0);
auto now = cv::getTickCount();
const bool error = (res != nz);
if (error)
printf("!!ERROR!!\r\n");
results.push_back(res);
timings.push_back(1000.*(now-ref)/cv::getTickFrequency());
}
const size_t bestTimingIndex = (std::min_element(timings.begin(), timings.end())-timings.begin());
if ((bestTimingIndex != 0) || (std::find_if_not(results.begin(), results.end(), [&](bool r) {return (r == nz);}) != results.end()))
{
std::cout << "cv::hasNonZero\t\t=>" << results[0] << ((results[0] != nz) ? " ERROR" : "") << " perf:" << timings[0] << "ms => " << (iterations/timings[0]*1000) << " im/s" << ((bestTimingIndex == 0) ? " * " : "") << std::endl;
std::cout << "cv::countNonZero\t=>" << results[1] << ((results[1] != nz) ? " ERROR" : "") << " perf:" << timings[1] << "ms => " << (iterations/timings[1]*1000) << " im/s" << ((bestTimingIndex == 1) ? " * " : "") << std::endl;
}
}
}
}
}
}
```
Here is a report of this benchmark (it only reports timings when `cv::countNonZero()` is faster)
My CPU is an Intel Core I7 4790 @ 3.60Ghz
```
============================================================
size:[32 x 32] type:0 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[32 x 32] type:0 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[32 x 32] type:0 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[32 x 32] type:0 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[32 x 32] type:0 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[32 x 32] type:0 continuous = false iterations:1000 nz=true pos=middle
cv::hasNonZero =>1 perf:0.353764ms => 2.82674e+06 im/s
cv::countNonZero =>1 perf:0.282044ms => 3.54555e+06 im/s *
============================================================
size:[32 x 32] type:0 continuous = false iterations:1000 nz=true pos=end
cv::hasNonZero =>1 perf:0.610478ms => 1.63806e+06 im/s
cv::countNonZero =>1 perf:0.283182ms => 3.5313e+06 im/s *
============================================================
size:[32 x 32] type:0 continuous = false iterations:1000 nz=false pos=none
cv::hasNonZero =>0 perf:0.630115ms => 1.58701e+06 im/s
cv::countNonZero =>0 perf:0.282044ms => 3.54555e+06 im/s *
============================================================
size:[32 x 32] type:2 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[32 x 32] type:2 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[32 x 32] type:2 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[32 x 32] type:2 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[32 x 32] type:2 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[32 x 32] type:2 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[32 x 32] type:2 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[32 x 32] type:2 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[32 x 32] type:4 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[32 x 32] type:4 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[32 x 32] type:4 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[32 x 32] type:4 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[32 x 32] type:4 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[32 x 32] type:4 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[32 x 32] type:4 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[32 x 32] type:4 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[32 x 32] type:5 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[32 x 32] type:5 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[32 x 32] type:5 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[32 x 32] type:5 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[32 x 32] type:5 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[32 x 32] type:5 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[32 x 32] type:5 continuous = false iterations:1000 nz=true pos=end
cv::hasNonZero =>1 perf:0.607347ms => 1.64651e+06 im/s
cv::countNonZero =>1 perf:0.467037ms => 2.14116e+06 im/s *
============================================================
size:[32 x 32] type:5 continuous = false iterations:1000 nz=false pos=none
cv::hasNonZero =>0 perf:0.618162ms => 1.6177e+06 im/s
cv::countNonZero =>0 perf:0.468175ms => 2.13595e+06 im/s *
============================================================
size:[32 x 32] type:6 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[32 x 32] type:6 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[32 x 32] type:6 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[32 x 32] type:6 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[32 x 32] type:6 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[32 x 32] type:6 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[32 x 32] type:6 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[32 x 32] type:6 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[64 x 64] type:0 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[64 x 64] type:0 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[64 x 64] type:0 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[64 x 64] type:0 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[64 x 64] type:0 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[64 x 64] type:0 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[64 x 64] type:0 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[64 x 64] type:0 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[64 x 64] type:2 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[64 x 64] type:2 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[64 x 64] type:2 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[64 x 64] type:2 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[64 x 64] type:2 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[64 x 64] type:2 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[64 x 64] type:2 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[64 x 64] type:2 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[64 x 64] type:4 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[64 x 64] type:4 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[64 x 64] type:4 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[64 x 64] type:4 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[64 x 64] type:4 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[64 x 64] type:4 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[64 x 64] type:4 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[64 x 64] type:4 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[64 x 64] type:5 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[64 x 64] type:5 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[64 x 64] type:5 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[64 x 64] type:5 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[64 x 64] type:5 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[64 x 64] type:5 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[64 x 64] type:5 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[64 x 64] type:5 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[64 x 64] type:6 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[64 x 64] type:6 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[64 x 64] type:6 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[64 x 64] type:6 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[64 x 64] type:6 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[64 x 64] type:6 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[64 x 64] type:6 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[64 x 64] type:6 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[128 x 128] type:0 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[128 x 128] type:0 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[128 x 128] type:0 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[128 x 128] type:0 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[128 x 128] type:0 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[128 x 128] type:0 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[128 x 128] type:0 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[128 x 128] type:0 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[128 x 128] type:2 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[128 x 128] type:2 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[128 x 128] type:2 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[128 x 128] type:2 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[128 x 128] type:2 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[128 x 128] type:2 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[128 x 128] type:2 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[128 x 128] type:2 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[128 x 128] type:4 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[128 x 128] type:4 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[128 x 128] type:4 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[128 x 128] type:4 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[128 x 128] type:4 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[128 x 128] type:4 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[128 x 128] type:4 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[128 x 128] type:4 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[128 x 128] type:5 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[128 x 128] type:5 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[128 x 128] type:5 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[128 x 128] type:5 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[128 x 128] type:5 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[128 x 128] type:5 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[128 x 128] type:5 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[128 x 128] type:5 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[128 x 128] type:6 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[128 x 128] type:6 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[128 x 128] type:6 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[128 x 128] type:6 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[128 x 128] type:6 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[128 x 128] type:6 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[128 x 128] type:6 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[128 x 128] type:6 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[320 x 240] type:0 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[320 x 240] type:0 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[320 x 240] type:0 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[320 x 240] type:0 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[320 x 240] type:0 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[320 x 240] type:0 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[320 x 240] type:0 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[320 x 240] type:0 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[320 x 240] type:2 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[320 x 240] type:2 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[320 x 240] type:2 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[320 x 240] type:2 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[320 x 240] type:2 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[320 x 240] type:2 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[320 x 240] type:2 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[320 x 240] type:2 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[320 x 240] type:4 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[320 x 240] type:4 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[320 x 240] type:4 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[320 x 240] type:4 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[320 x 240] type:4 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[320 x 240] type:4 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[320 x 240] type:4 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[320 x 240] type:4 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[320 x 240] type:5 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[320 x 240] type:5 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[320 x 240] type:5 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[320 x 240] type:5 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[320 x 240] type:5 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[320 x 240] type:5 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[320 x 240] type:5 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[320 x 240] type:5 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[320 x 240] type:6 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[320 x 240] type:6 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[320 x 240] type:6 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[320 x 240] type:6 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[320 x 240] type:6 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[320 x 240] type:6 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[320 x 240] type:6 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[320 x 240] type:6 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[512 x 512] type:0 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[512 x 512] type:0 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[512 x 512] type:0 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[512 x 512] type:0 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[512 x 512] type:0 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[512 x 512] type:0 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[512 x 512] type:0 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[512 x 512] type:0 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[512 x 512] type:2 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[512 x 512] type:2 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[512 x 512] type:2 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[512 x 512] type:2 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[512 x 512] type:2 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[512 x 512] type:2 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[512 x 512] type:2 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[512 x 512] type:2 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[512 x 512] type:4 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[512 x 512] type:4 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[512 x 512] type:4 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[512 x 512] type:4 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[512 x 512] type:4 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[512 x 512] type:4 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[512 x 512] type:4 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[512 x 512] type:4 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[512 x 512] type:5 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[512 x 512] type:5 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[512 x 512] type:5 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[512 x 512] type:5 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[512 x 512] type:5 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[512 x 512] type:5 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[512 x 512] type:5 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[512 x 512] type:5 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[512 x 512] type:6 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[512 x 512] type:6 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[512 x 512] type:6 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[512 x 512] type:6 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[512 x 512] type:6 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[512 x 512] type:6 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[512 x 512] type:6 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[512 x 512] type:6 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[640 x 480] type:0 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[640 x 480] type:0 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[640 x 480] type:0 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[640 x 480] type:0 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[640 x 480] type:0 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[640 x 480] type:0 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[640 x 480] type:0 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[640 x 480] type:0 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[640 x 480] type:2 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[640 x 480] type:2 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[640 x 480] type:2 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[640 x 480] type:2 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[640 x 480] type:2 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[640 x 480] type:2 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[640 x 480] type:2 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[640 x 480] type:2 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[640 x 480] type:4 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[640 x 480] type:4 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[640 x 480] type:4 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[640 x 480] type:4 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[640 x 480] type:4 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[640 x 480] type:4 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[640 x 480] type:4 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[640 x 480] type:4 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[640 x 480] type:5 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[640 x 480] type:5 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[640 x 480] type:5 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[640 x 480] type:5 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[640 x 480] type:5 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[640 x 480] type:5 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[640 x 480] type:5 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[640 x 480] type:5 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[640 x 480] type:6 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[640 x 480] type:6 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[640 x 480] type:6 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[640 x 480] type:6 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[640 x 480] type:6 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[640 x 480] type:6 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[640 x 480] type:6 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[640 x 480] type:6 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[1024 x 768] type:0 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[1024 x 768] type:0 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[1024 x 768] type:0 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[1024 x 768] type:0 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[1024 x 768] type:0 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[1024 x 768] type:0 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[1024 x 768] type:0 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[1024 x 768] type:0 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[1024 x 768] type:2 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[1024 x 768] type:2 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[1024 x 768] type:2 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[1024 x 768] type:2 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[1024 x 768] type:2 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[1024 x 768] type:2 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[1024 x 768] type:2 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[1024 x 768] type:2 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[1024 x 768] type:4 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[1024 x 768] type:4 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[1024 x 768] type:4 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[1024 x 768] type:4 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[1024 x 768] type:4 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[1024 x 768] type:4 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[1024 x 768] type:4 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[1024 x 768] type:4 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[1024 x 768] type:5 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[1024 x 768] type:5 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[1024 x 768] type:5 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[1024 x 768] type:5 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[1024 x 768] type:5 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[1024 x 768] type:5 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[1024 x 768] type:5 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[1024 x 768] type:5 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[1024 x 768] type:6 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[1024 x 768] type:6 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[1024 x 768] type:6 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[1024 x 768] type:6 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[1024 x 768] type:6 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[1024 x 768] type:6 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[1024 x 768] type:6 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[1024 x 768] type:6 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[2048 x 2048] type:0 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[2048 x 2048] type:0 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[2048 x 2048] type:0 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[2048 x 2048] type:0 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[2048 x 2048] type:0 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[2048 x 2048] type:0 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[2048 x 2048] type:0 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[2048 x 2048] type:0 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[2048 x 2048] type:2 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[2048 x 2048] type:2 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[2048 x 2048] type:2 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[2048 x 2048] type:2 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[2048 x 2048] type:2 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[2048 x 2048] type:2 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[2048 x 2048] type:2 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[2048 x 2048] type:2 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[2048 x 2048] type:4 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[2048 x 2048] type:4 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[2048 x 2048] type:4 continuous = true iterations:1000 nz=true pos=end
cv::hasNonZero =>1 perf:895.381ms => 1116.84 im/s
cv::countNonZero =>1 perf:882.569ms => 1133.06 im/s *
============================================================
size:[2048 x 2048] type:4 continuous = true iterations:1000 nz=false pos=none
cv::hasNonZero =>0 perf:899.53ms => 1111.69 im/s
cv::countNonZero =>0 perf:870.894ms => 1148.24 im/s *
============================================================
size:[2048 x 2048] type:4 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[2048 x 2048] type:4 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[2048 x 2048] type:4 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[2048 x 2048] type:4 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[2048 x 2048] type:5 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[2048 x 2048] type:5 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[2048 x 2048] type:5 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[2048 x 2048] type:5 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[2048 x 2048] type:5 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[2048 x 2048] type:5 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[2048 x 2048] type:5 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[2048 x 2048] type:5 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[2048 x 2048] type:6 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[2048 x 2048] type:6 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[2048 x 2048] type:6 continuous = true iterations:1000 nz=true pos=end
cv::hasNonZero =>1 perf:2018.92ms => 495.313 im/s
cv::countNonZero =>1 perf:1966.37ms => 508.552 im/s *
============================================================
size:[2048 x 2048] type:6 continuous = true iterations:1000 nz=false pos=none
cv::hasNonZero =>0 perf:2005.87ms => 498.537 im/s
cv::countNonZero =>0 perf:1992.78ms => 501.812 im/s *
============================================================
size:[2048 x 2048] type:6 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[2048 x 2048] type:6 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[2048 x 2048] type:6 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[2048 x 2048] type:6 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[1031 x 1000] type:0 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[1031 x 1000] type:0 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[1031 x 1000] type:0 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[1031 x 1000] type:0 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[1031 x 1000] type:0 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[1031 x 1000] type:0 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[1031 x 1000] type:0 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[1031 x 1000] type:0 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[1031 x 1000] type:2 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[1031 x 1000] type:2 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[1031 x 1000] type:2 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[1031 x 1000] type:2 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[1031 x 1000] type:2 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[1031 x 1000] type:2 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[1031 x 1000] type:2 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[1031 x 1000] type:2 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[1031 x 1000] type:4 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[1031 x 1000] type:4 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[1031 x 1000] type:4 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[1031 x 1000] type:4 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[1031 x 1000] type:4 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[1031 x 1000] type:4 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[1031 x 1000] type:4 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[1031 x 1000] type:4 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[1031 x 1000] type:5 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[1031 x 1000] type:5 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[1031 x 1000] type:5 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[1031 x 1000] type:5 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[1031 x 1000] type:5 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[1031 x 1000] type:5 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[1031 x 1000] type:5 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[1031 x 1000] type:5 continuous = false iterations:1000 nz=false pos=none
============================================================
size:[1031 x 1000] type:6 continuous = true iterations:1000 nz=true pos=begin
============================================================
size:[1031 x 1000] type:6 continuous = true iterations:1000 nz=true pos=middle
============================================================
size:[1031 x 1000] type:6 continuous = true iterations:1000 nz=true pos=end
============================================================
size:[1031 x 1000] type:6 continuous = true iterations:1000 nz=false pos=none
============================================================
size:[1031 x 1000] type:6 continuous = false iterations:1000 nz=true pos=begin
============================================================
size:[1031 x 1000] type:6 continuous = false iterations:1000 nz=true pos=middle
============================================================
size:[1031 x 1000] type:6 continuous = false iterations:1000 nz=true pos=end
============================================================
size:[1031 x 1000] type:6 continuous = false iterations:1000 nz=false pos=none
done
```
2023-06-09 18:37:20 +08:00
|
|
|
/*M///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
|
|
|
//
|
|
|
|
// By downloading, copying, installing or using the software you agree to this license.
|
|
|
|
// If you do not agree to this license, do not download, install,
|
|
|
|
// copy or use the software.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// License Agreement
|
|
|
|
// For Open Source Computer Vision Library
|
|
|
|
//
|
|
|
|
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
|
|
|
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
|
|
|
// Third party copyrights are property of their respective owners.
|
|
|
|
//
|
|
|
|
// Redistribution and use in source and binary forms, with or without modification,
|
|
|
|
// are permitted provided that the following conditions are met:
|
|
|
|
//
|
|
|
|
// * Redistribution's of source code must retain the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer.
|
|
|
|
//
|
|
|
|
// * Redistribution's in binary form must reproduce the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
|
|
// and/or other materials provided with the distribution.
|
|
|
|
//
|
|
|
|
// * The name of the copyright holders may not be used to endorse or promote products
|
|
|
|
// derived from this software without specific prior written permission.
|
|
|
|
//
|
|
|
|
// This software is provided by the copyright holders and contributors "as is" and
|
|
|
|
// any express or implied warranties, including, but not limited to, the implied
|
|
|
|
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
|
|
|
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
|
|
|
// indirect, incidental, special, exemplary, or consequential damages
|
|
|
|
// (including, but not limited to, procurement of substitute goods or services;
|
|
|
|
// loss of use, data, or profits; or business interruption) however caused
|
|
|
|
// and on any theory of liability, whether in contract, strict liability,
|
|
|
|
// or tort (including negligence or otherwise) arising in any way out of
|
|
|
|
// the use of this software, even if advised of the possibility of such damage.
|
|
|
|
//
|
|
|
|
//M*/
|
|
|
|
|
|
|
|
#include "test_precomp.hpp"
|
|
|
|
|
|
|
|
namespace opencv_test { namespace {
|
|
|
|
|
|
|
|
typedef testing::TestWithParam<std::tuple<int, Size> > HasNonZeroAllZeros;
|
|
|
|
|
|
|
|
TEST_P(HasNonZeroAllZeros, hasNonZeroAllZeros)
|
|
|
|
{
|
|
|
|
const int type = std::get<0>(GetParam());
|
|
|
|
const Size size = std::get<1>(GetParam());
|
|
|
|
|
|
|
|
Mat m = Mat::zeros(size, type);
|
|
|
|
EXPECT_FALSE(hasNonZero(m));
|
|
|
|
}
|
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(Core, HasNonZeroAllZeros,
|
|
|
|
testing::Combine(
|
|
|
|
testing::Values(CV_8UC1, CV_8SC1, CV_16UC1, CV_16SC1, CV_32SC1, CV_32FC1, CV_64FC1),
|
|
|
|
testing::Values(Size(1, 1), Size(320, 240), Size(127, 113), Size(1, 113))
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
typedef testing::TestWithParam<std::tuple<int, Size> > HasNonZeroNegZeros;
|
|
|
|
|
|
|
|
TEST_P(HasNonZeroNegZeros, hasNonZeroNegZeros)
|
|
|
|
{
|
|
|
|
const int type = std::get<0>(GetParam());
|
|
|
|
const Size size = std::get<1>(GetParam());
|
|
|
|
|
|
|
|
Mat m = Mat(size, type);
|
|
|
|
m.setTo(Scalar::all(-0.));
|
|
|
|
EXPECT_FALSE(hasNonZero(m));
|
|
|
|
}
|
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(Core, HasNonZeroNegZeros,
|
|
|
|
testing::Combine(
|
|
|
|
testing::Values(CV_32FC1, CV_64FC1),
|
|
|
|
testing::Values(Size(1, 1), Size(320, 240), Size(127, 113), Size(1, 113))
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
typedef testing::TestWithParam<std::tuple<int, Size> > HasNonZeroLimitValues;
|
|
|
|
|
|
|
|
TEST_P(HasNonZeroLimitValues, hasNonZeroLimitValues)
|
|
|
|
{
|
|
|
|
const int type = std::get<0>(GetParam());
|
|
|
|
const Size size = std::get<1>(GetParam());
|
|
|
|
|
|
|
|
Mat m = Mat(size, type);
|
|
|
|
|
|
|
|
m.setTo(Scalar::all(std::numeric_limits<double>::infinity()));
|
|
|
|
EXPECT_TRUE(hasNonZero(m));
|
|
|
|
|
|
|
|
m.setTo(Scalar::all(-std::numeric_limits<double>::infinity()));
|
|
|
|
EXPECT_TRUE(hasNonZero(m));
|
|
|
|
|
|
|
|
m.setTo(Scalar::all(std::numeric_limits<double>::quiet_NaN()));
|
|
|
|
EXPECT_TRUE(hasNonZero(m));
|
|
|
|
|
|
|
|
m.setTo((CV_MAT_DEPTH(type) == CV_64F) ? Scalar::all(std::numeric_limits<double>::epsilon()) : Scalar::all(std::numeric_limits<float>::epsilon()));
|
|
|
|
EXPECT_TRUE(hasNonZero(m));
|
|
|
|
|
|
|
|
m.setTo((CV_MAT_DEPTH(type) == CV_64F) ? Scalar::all(std::numeric_limits<double>::min()) : Scalar::all(std::numeric_limits<float>::min()));
|
|
|
|
EXPECT_TRUE(hasNonZero(m));
|
|
|
|
|
|
|
|
m.setTo((CV_MAT_DEPTH(type) == CV_64F) ? Scalar::all(std::numeric_limits<double>::denorm_min()) : Scalar::all(std::numeric_limits<float>::denorm_min()));
|
|
|
|
EXPECT_TRUE(hasNonZero(m));
|
|
|
|
}
|
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(Core, HasNonZeroLimitValues,
|
|
|
|
testing::Combine(
|
|
|
|
testing::Values(CV_32FC1, CV_64FC1),
|
|
|
|
testing::Values(Size(1, 1), Size(320, 240), Size(127, 113), Size(1, 113))
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
typedef testing::TestWithParam<std::tuple<int, Size> > HasNonZeroRandom;
|
|
|
|
|
|
|
|
TEST_P(HasNonZeroRandom, hasNonZeroRandom)
|
|
|
|
{
|
|
|
|
const int type = std::get<0>(GetParam());
|
|
|
|
const Size size = std::get<1>(GetParam());
|
|
|
|
|
|
|
|
RNG& rng = theRNG();
|
|
|
|
|
|
|
|
const size_t N = std::min(100, size.area());
|
|
|
|
for(size_t i = 0 ; i<N ; ++i)
|
|
|
|
{
|
|
|
|
const int nz_pos_x = rng.uniform(0, size.width);
|
|
|
|
const int nz_pos_y = rng.uniform(0, size.height);
|
|
|
|
Mat m = Mat::zeros(size, type);
|
|
|
|
Mat nzROI = Mat(m, Rect(nz_pos_x, nz_pos_y, 1, 1));
|
|
|
|
nzROI.setTo(Scalar::all(1));
|
|
|
|
EXPECT_TRUE(hasNonZero(m));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(Core, HasNonZeroRandom,
|
|
|
|
testing::Combine(
|
|
|
|
testing::Values(CV_8UC1, CV_8SC1, CV_16UC1, CV_16SC1, CV_32SC1, CV_32FC1, CV_64FC1),
|
|
|
|
testing::Values(Size(1, 1), Size(320, 240), Size(127, 113), Size(1, 113))
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
typedef testing::TestWithParam<tuple<int, int, bool> > HasNonZeroNd;
|
|
|
|
|
|
|
|
TEST_P(HasNonZeroNd, hasNonZeroNd)
|
|
|
|
{
|
|
|
|
const int type = get<0>(GetParam());
|
|
|
|
const int ndims = get<1>(GetParam());
|
|
|
|
const bool continuous = get<2>(GetParam());
|
|
|
|
|
|
|
|
RNG& rng = theRNG();
|
|
|
|
|
|
|
|
const size_t N = 10;
|
|
|
|
for(size_t i = 0 ; i<N ; ++i)
|
|
|
|
{
|
|
|
|
std::vector<size_t> steps(ndims);
|
|
|
|
std::vector<int> sizes(ndims);
|
|
|
|
size_t totalBytes = 1;
|
|
|
|
for(int dim = 0 ; dim<ndims ; ++dim)
|
|
|
|
{
|
|
|
|
const bool isFirstDim = (dim == 0);
|
|
|
|
const bool isLastDim = (dim+1 == ndims);
|
|
|
|
const int length = rng.uniform(1, 64);
|
|
|
|
steps[dim] = (isLastDim ? 1 : static_cast<size_t>(length))*CV_ELEM_SIZE(type);
|
|
|
|
sizes[dim] = (isFirstDim || continuous) ? length : rng.uniform(1, length);
|
|
|
|
totalBytes *= steps[dim]*static_cast<size_t>(sizes[dim]);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<unsigned char> buffer(totalBytes);
|
|
|
|
void* data = buffer.data();
|
|
|
|
|
|
|
|
Mat m = Mat(ndims, sizes.data(), type, data, steps.data());
|
|
|
|
|
|
|
|
std::vector<Range> nzRange(ndims);
|
|
|
|
for(int dim = 0 ; dim<ndims ; ++dim)
|
|
|
|
{
|
|
|
|
const int pos = rng.uniform(0, sizes[dim]);
|
|
|
|
nzRange[dim] = Range(pos, pos+1);
|
|
|
|
}
|
|
|
|
|
|
|
|
Mat nzROI = Mat(m, nzRange.data());
|
|
|
|
nzROI.setTo(Scalar::all(1));
|
|
|
|
|
|
|
|
const int nzCount = countNonZero(m);
|
|
|
|
EXPECT_EQ((nzCount>0), hasNonZero(m));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(Core, HasNonZeroNd,
|
|
|
|
testing::Combine(
|
|
|
|
testing::Values(CV_8UC1),
|
|
|
|
testing::Values(2, 3),
|
|
|
|
testing::Values(true, false)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
}} // namespace
|