Added threaded versions (enabled only for Tegra at the moment) of threshold, erode/dilate. Slighlty restructured the code of medianBlur.
This commit is contained in:
parent
40c70d127d
commit
694ea8e0c8
@ -1049,6 +1049,61 @@ cv::Mat cv::getStructuringElement(int shape, Size ksize, Point anchor)
|
|||||||
namespace cv
|
namespace cv
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class MorphologyRunner
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MorphologyRunner(Mat _src, Mat _dst, int _nStripes, int _iterations,
|
||||||
|
int _op, Mat _kernel, Point _anchor,
|
||||||
|
int _rowBorderType, int _columnBorderType, const Scalar& _borderValue) :
|
||||||
|
borderValue(_borderValue)
|
||||||
|
{
|
||||||
|
src = _src;
|
||||||
|
dst = _dst;
|
||||||
|
|
||||||
|
nStripes = _nStripes;
|
||||||
|
iterations = _iterations;
|
||||||
|
|
||||||
|
op = _op;
|
||||||
|
kernel = _kernel;
|
||||||
|
anchor = _anchor;
|
||||||
|
rowBorderType = _rowBorderType;
|
||||||
|
columnBorderType = _columnBorderType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () ( const BlockedRange& range ) const
|
||||||
|
{
|
||||||
|
int row0 = min(cvRound(range.begin() * src.rows / nStripes), src.rows);
|
||||||
|
int row1 = min(cvRound(range.end() * src.rows / nStripes), src.rows);
|
||||||
|
|
||||||
|
if(0)
|
||||||
|
printf("Size = (%d, %d), range[%d,%d), row0 = %d, row1 = %d\n",
|
||||||
|
src.rows, src.cols, range.begin(), range.end(), row0, row1);
|
||||||
|
|
||||||
|
Mat srcStripe = src.rowRange(row0, row1);
|
||||||
|
Mat dstStripe = dst.rowRange(row0, row1);
|
||||||
|
|
||||||
|
Ptr<FilterEngine> f = createMorphologyFilter(op, src.type(), kernel, anchor,
|
||||||
|
rowBorderType, columnBorderType, borderValue );
|
||||||
|
|
||||||
|
f->apply( srcStripe, dstStripe );
|
||||||
|
for( int i = 1; i < iterations; i++ )
|
||||||
|
f->apply( dstStripe, dstStripe );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Mat src;
|
||||||
|
Mat dst;
|
||||||
|
int nStripes;
|
||||||
|
int iterations;
|
||||||
|
|
||||||
|
int op;
|
||||||
|
Mat kernel;
|
||||||
|
Point anchor;
|
||||||
|
int rowBorderType;
|
||||||
|
int columnBorderType;
|
||||||
|
const Scalar& borderValue;
|
||||||
|
};
|
||||||
|
|
||||||
static void morphOp( int op, InputArray _src, OutputArray _dst,
|
static void morphOp( int op, InputArray _src, OutputArray _dst,
|
||||||
InputArray _kernel,
|
InputArray _kernel,
|
||||||
Point anchor, int iterations,
|
Point anchor, int iterations,
|
||||||
@ -1085,12 +1140,23 @@ static void morphOp( int op, InputArray _src, OutputArray _dst,
|
|||||||
iterations = 1;
|
iterations = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ptr<FilterEngine> f = createMorphologyFilter(op, src.type(),
|
int nStripes = 1;
|
||||||
kernel, anchor, borderType, borderType, borderValue );
|
#if defined HAVE_TBB && defined HAVE_TEGRA_OPTIMIZATION
|
||||||
|
if (src.data != dst.data && iterations == 1 && //NOTE: threads are not used for inplace processing
|
||||||
|
(borderType & BORDER_ISOLATED) == 0 && //TODO: check border types
|
||||||
|
src.rows >= 64 ) //NOTE: just heuristics
|
||||||
|
nStripes = 4;
|
||||||
|
#endif
|
||||||
|
|
||||||
f->apply( src, dst );
|
parallel_for(BlockedRange(0, nStripes),
|
||||||
for( int i = 1; i < iterations; i++ )
|
MorphologyRunner(src, dst, nStripes, iterations, op, kernel, anchor, borderType, borderType, borderValue));
|
||||||
f->apply( dst, dst );
|
|
||||||
|
//Ptr<FilterEngine> f = createMorphologyFilter(op, src.type(),
|
||||||
|
// kernel, anchor, borderType, borderType, borderValue );
|
||||||
|
|
||||||
|
//f->apply( src, dst );
|
||||||
|
//for( int i = 1; i < iterations; i++ )
|
||||||
|
// f->apply( dst, dst );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> void Ptr<IplConvKernel>::delete_obj()
|
template<> void Ptr<IplConvKernel>::delete_obj()
|
||||||
|
@ -1244,8 +1244,6 @@ void cv::medianBlur( InputArray _src0, OutputArray _dst, int ksize )
|
|||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Size size = src0.size();
|
|
||||||
int cn = src0.channels();
|
|
||||||
bool useSortNet = ksize == 3 || (ksize == 5
|
bool useSortNet = ksize == 3 || (ksize == 5
|
||||||
#if !CV_SSE2
|
#if !CV_SSE2
|
||||||
&& src0.depth() > CV_8U
|
&& src0.depth() > CV_8U
|
||||||
@ -1259,12 +1257,7 @@ void cv::medianBlur( InputArray _src0, OutputArray _dst, int ksize )
|
|||||||
src = src0;
|
src = src0;
|
||||||
else
|
else
|
||||||
src0.copyTo(src);
|
src0.copyTo(src);
|
||||||
}
|
|
||||||
else
|
|
||||||
cv::copyMakeBorder( src0, src, 0, 0, ksize/2, ksize/2, BORDER_REPLICATE );
|
|
||||||
|
|
||||||
if( useSortNet )
|
|
||||||
{
|
|
||||||
if( src.depth() == CV_8U )
|
if( src.depth() == CV_8U )
|
||||||
medianBlur_SortNet<MinMax8u, MinMaxVec8u>( src, dst, ksize );
|
medianBlur_SortNet<MinMax8u, MinMaxVec8u>( src, dst, ksize );
|
||||||
else if( src.depth() == CV_16U )
|
else if( src.depth() == CV_16U )
|
||||||
@ -1275,16 +1268,22 @@ void cv::medianBlur( InputArray _src0, OutputArray _dst, int ksize )
|
|||||||
medianBlur_SortNet<MinMax32f, MinMaxVec32f>( src, dst, ksize );
|
medianBlur_SortNet<MinMax32f, MinMaxVec32f>( src, dst, ksize );
|
||||||
else
|
else
|
||||||
CV_Error(CV_StsUnsupportedFormat, "");
|
CV_Error(CV_StsUnsupportedFormat, "");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CV_Assert( src.depth() == CV_8U && (cn == 1 || cn == 3 || cn == 4) );
|
|
||||||
|
|
||||||
double img_size_mp = (double)(size.width*size.height)/(1 << 20);
|
|
||||||
if( ksize <= 3 + (img_size_mp < 1 ? 12 : img_size_mp < 4 ? 6 : 2)*(MEDIAN_HAVE_SIMD && checkHardwareSupport(CV_CPU_SSE2) ? 1 : 3))
|
|
||||||
medianBlur_8u_Om( src, dst, ksize );
|
|
||||||
else
|
else
|
||||||
medianBlur_8u_O1( src, dst, ksize );
|
{
|
||||||
|
cv::copyMakeBorder( src0, src, 0, 0, ksize/2, ksize/2, BORDER_REPLICATE );
|
||||||
|
|
||||||
|
int cn = src0.channels();
|
||||||
|
CV_Assert( src.depth() == CV_8U && (cn == 1 || cn == 3 || cn == 4) );
|
||||||
|
|
||||||
|
double img_size_mp = (double)(src0.total())/(1 << 20);
|
||||||
|
if( ksize <= 3 + (img_size_mp < 1 ? 12 : img_size_mp < 4 ? 6 : 2)*(MEDIAN_HAVE_SIMD && checkHardwareSupport(CV_CPU_SSE2) ? 1 : 3))
|
||||||
|
medianBlur_8u_Om( src, dst, ksize );
|
||||||
|
else
|
||||||
|
medianBlur_8u_O1( src, dst, ksize );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************\
|
/****************************************************************************************\
|
||||||
|
@ -663,6 +663,57 @@ getThreshVal_Otsu_8u( const Mat& _src )
|
|||||||
return max_val;
|
return max_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ThresholdRunner
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ThresholdRunner(Mat _src, Mat _dst, int _nStripes, double _thresh, double _maxval, int _thresholdType)
|
||||||
|
{
|
||||||
|
src = _src;
|
||||||
|
dst = _dst;
|
||||||
|
|
||||||
|
nStripes = _nStripes;
|
||||||
|
|
||||||
|
thresh = _thresh;
|
||||||
|
maxval = _maxval;
|
||||||
|
thresholdType = _thresholdType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () ( const BlockedRange& range ) const
|
||||||
|
{
|
||||||
|
int row0 = std::min(cvRound(range.begin() * src.rows / nStripes), src.rows);
|
||||||
|
int row1 = std::min(cvRound(range.end() * src.rows / nStripes), src.rows);
|
||||||
|
|
||||||
|
if(0)
|
||||||
|
printf("Size = (%d, %d), range[%d,%d), row0 = %d, row1 = %d\n",
|
||||||
|
src.rows, src.cols, range.begin(), range.end(), row0, row1);
|
||||||
|
|
||||||
|
Mat srcStripe = src.rowRange(row0, row1);
|
||||||
|
Mat dstStripe = dst.rowRange(row0, row1);
|
||||||
|
|
||||||
|
if (srcStripe.depth() == CV_8U)
|
||||||
|
{
|
||||||
|
thresh_8u( srcStripe, dstStripe, (uchar)thresh, (uchar)maxval, thresholdType );
|
||||||
|
}
|
||||||
|
else if( srcStripe.depth() == CV_16S )
|
||||||
|
{
|
||||||
|
thresh_16s( srcStripe, dstStripe, (short)thresh, (short)maxval, thresholdType );
|
||||||
|
}
|
||||||
|
else if( srcStripe.depth() == CV_32F )
|
||||||
|
{
|
||||||
|
thresh_32f( srcStripe, dstStripe, (float)thresh, (float)maxval, thresholdType );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Mat src;
|
||||||
|
Mat dst;
|
||||||
|
int nStripes;
|
||||||
|
|
||||||
|
double thresh;
|
||||||
|
double maxval;
|
||||||
|
int thresholdType;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double maxval, int type )
|
double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double maxval, int type )
|
||||||
@ -680,6 +731,11 @@ double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double m
|
|||||||
_dst.create( src.size(), src.type() );
|
_dst.create( src.size(), src.type() );
|
||||||
Mat dst = _dst.getMat();
|
Mat dst = _dst.getMat();
|
||||||
|
|
||||||
|
int nStripes = 1;
|
||||||
|
#if defined HAVE_TBB && defined HAVE_TEGRA_OPTIMIZATION
|
||||||
|
nStripes = 4;
|
||||||
|
#endif
|
||||||
|
|
||||||
if( src.depth() == CV_8U )
|
if( src.depth() == CV_8U )
|
||||||
{
|
{
|
||||||
int ithresh = cvFloor(thresh);
|
int ithresh = cvFloor(thresh);
|
||||||
@ -704,7 +760,11 @@ double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double m
|
|||||||
src.copyTo(dst);
|
src.copyTo(dst);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
thresh_8u( src, dst, (uchar)ithresh, (uchar)imaxval, type );
|
{
|
||||||
|
//thresh_8u( src, dst, (uchar)ithresh, (uchar)imaxval, type );
|
||||||
|
parallel_for(BlockedRange(0, nStripes),
|
||||||
|
ThresholdRunner(src, dst, nStripes, (uchar)ithresh, (uchar)imaxval, type));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( src.depth() == CV_16S )
|
else if( src.depth() == CV_16S )
|
||||||
{
|
{
|
||||||
@ -730,10 +790,18 @@ double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double m
|
|||||||
src.copyTo(dst);
|
src.copyTo(dst);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
thresh_16s( src, dst, (short)ithresh, (short)imaxval, type );
|
{
|
||||||
|
//thresh_16s( src, dst, (short)ithresh, (short)imaxval, type );
|
||||||
|
parallel_for(BlockedRange(0, nStripes),
|
||||||
|
ThresholdRunner(src, dst, nStripes, (short)ithresh, (short)imaxval, type));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( src.depth() == CV_32F )
|
else if( src.depth() == CV_32F )
|
||||||
thresh_32f( src, dst, (float)thresh, (float)maxval, type );
|
{
|
||||||
|
//thresh_32f( src, dst, (float)thresh, (float)maxval, type );
|
||||||
|
parallel_for(BlockedRange(0, nStripes),
|
||||||
|
ThresholdRunner(src, dst, nStripes, (float)thresh, (float)maxval, type));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
CV_Error( CV_StsUnsupportedFormat, "" );
|
CV_Error( CV_StsUnsupportedFormat, "" );
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user