1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 15:23:05 +04:00

a part of PR #11364 (extended findNonZero & PSNR) (#11837)

* a part of https://github.com/opencv/opencv/pull/11364 by Tetragramm. Rewritten and extended findNonZero & PSNR to support more types, not just 8u.

* fixed compile & doxygen warnings

* fixed small bug in findNonZero test
This commit is contained in:
Vadim Pisarevsky
2018-06-26 17:10:00 +03:00
committed by GitHub
parent cc8db99695
commit 051b40f956
4 changed files with 106 additions and 27 deletions
+53 -18
View File
@@ -393,25 +393,60 @@ void cv::findNonZero( InputArray _src, OutputArray _idx )
CV_INSTRUMENT_REGION()
Mat src = _src.getMat();
CV_Assert( src.type() == CV_8UC1 );
int n = countNonZero(src);
if( n == 0 )
{
_idx.release();
return;
}
if( _idx.kind() == _InputArray::MAT && !_idx.getMatRef().isContinuous() )
_idx.release();
_idx.create(n, 1, CV_32SC2);
Mat idx = _idx.getMat();
CV_Assert(idx.isContinuous());
Point* idx_ptr = idx.ptr<Point>();
CV_Assert( src.channels() == 1 && src.dims == 2 );
for( int i = 0; i < src.rows; i++ )
int depth = src.depth();
std::vector<Point> idxvec;
int rows = src.rows, cols = src.cols;
AutoBuffer<int> buf_(cols + 1);
int* buf = buf_;
for( int i = 0; i < rows; i++ )
{
const uchar* bin_ptr = src.ptr(i);
for( int j = 0; j < src.cols; j++ )
if( bin_ptr[j] )
*idx_ptr++ = Point(j, i);
int j, k = 0;
const uchar* ptr8 = src.ptr(i);
if( depth == CV_8U || depth == CV_8S )
{
for( j = 0; j < cols; j++ )
if( ptr8[j] != 0 ) buf[k++] = j;
}
else if( depth == CV_16U || depth == CV_16S )
{
const ushort* ptr16 = (const ushort*)ptr8;
for( j = 0; j < cols; j++ )
if( ptr16[j] != 0 ) buf[k++] = j;
}
else if( depth == CV_32S )
{
const int* ptr32s = (const int*)ptr8;
for( j = 0; j < cols; j++ )
if( ptr32s[j] != 0 ) buf[k++] = j;
}
else if( depth == CV_32F )
{
const float* ptr32f = (const float*)ptr8;
for( j = 0; j < cols; j++ )
if( ptr32f[j] != 0 ) buf[k++] = j;
}
else
{
const double* ptr64f = (const double*)ptr8;
for( j = 0; j < cols; j++ )
if( ptr64f[j] != 0 ) buf[k++] = j;
}
if( k > 0 )
{
size_t sz = idxvec.size();
idxvec.resize(sz + k);
for( j = 0; j < k; j++ )
idxvec[sz + j] = Point(buf[j], i);
}
}
if( idxvec.empty() || (_idx.kind() == _InputArray::MAT && !_idx.getMatRef().isContinuous()) )
_idx.release();
if( !idxvec.empty() )
Mat(idxvec).copyTo(_idx);
}