added cv::calcHist to T-API (only for CV_8UC1 with 256 bins)

This commit is contained in:
Ilya Lavrenov 2014-01-29 20:19:15 +04:00
parent fff5a6c058
commit 384a28622d
3 changed files with 146 additions and 41 deletions

View File

@ -1650,6 +1650,16 @@ int _InputArray::dims(int i) const
return vv[i].dims;
}
if( k == STD_VECTOR_UMAT )
{
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
if( i < 0 )
return 1;
CV_Assert( i < (int)vv.size() );
return vv[i].dims;
}
if( k == OPENGL_BUFFER )
{
CV_Assert( i < 0 );
@ -1701,6 +1711,16 @@ size_t _InputArray::total(int i) const
return vv[i].total();
}
if( k == STD_VECTOR_UMAT )
{
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
if( i < 0 )
return vv.size();
CV_Assert( i < (int)vv.size() );
return vv[i].total();
}
return size(i).area();
}
@ -1723,6 +1743,18 @@ int _InputArray::type(int i) const
if( k == NONE )
return -1;
if( k == STD_VECTOR_UMAT )
{
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
if( vv.empty() )
{
CV_Assert((flags & FIXED_TYPE) != 0);
return CV_MAT_TYPE(flags);
}
CV_Assert( i < (int)vv.size() );
return vv[i >= 0 ? i : 0].type();
}
if( k == STD_VECTOR_MAT )
{
const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
@ -1793,6 +1825,12 @@ bool _InputArray::empty() const
return vv.empty();
}
if( k == STD_VECTOR_UMAT )
{
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
return vv.empty();
}
if( k == OPENGL_BUFFER )
return ((const ogl::Buffer*)obj)->empty();

View File

@ -1399,6 +1399,57 @@ static void calcHist( const Mat* images, int nimages, const int* channels,
}
}
enum
{
BINS = 256
};
static bool ocl_calcHist1(InputArrayOfArrays _src, OutputArray _hist, int ddepth = CV_32S)
{
int compunits = ocl::Device::getDefault().maxComputeUnits();
size_t wgs = ocl::Device::getDefault().maxWorkGroupSize();
ocl::Kernel k1("calculate_histogram", ocl::imgproc::histogram_oclsrc,
format("-D BINS=%d -D HISTS_COUNT=%d -D WGS=%d", BINS, compunits, wgs));
if (k1.empty())
return false;
_hist.create(1, BINS, ddepth);
UMat src = _src.getUMat(), ghist(1, BINS * compunits, CV_32SC1),
hist = ddepth == CV_32S ? _hist.getUMat() : UMat(BINS, 1, CV_32SC1);
k1.args(ocl::KernelArg::ReadOnly(src), ocl::KernelArg::PtrWriteOnly(ghist),
(int)src.total());
size_t globalsize = compunits * wgs;
if (!k1.run(1, &globalsize, &wgs, false))
return false;
ocl::Kernel k2("merge_histogram", ocl::imgproc::histogram_oclsrc,
format("-D BINS=%d -D HISTS_COUNT=%d -D WGS=%d", BINS, compunits, (int)wgs));
if (k2.empty())
return false;
k2.args(ocl::KernelArg::PtrReadOnly(ghist), ocl::KernelArg::PtrWriteOnly(hist));
if (!k2.run(1, &wgs, &wgs, false))
return false;
if (hist.depth() != ddepth)
hist.convertTo(_hist, ddepth);
else
_hist.getUMatRef() = hist;
return true;
}
static bool ocl_calcHist(InputArrayOfArrays images, OutputArray hist)
{
std::vector<UMat> v;
images.getUMatVector(v);
return ocl_calcHist1(v[0], hist, CV_32F);
}
}
void cv::calcHist( const Mat* images, int nimages, const int* channels,
@ -1417,6 +1468,12 @@ void cv::calcHist( InputArrayOfArrays images, const std::vector<int>& channels,
const std::vector<float>& ranges,
bool accumulate )
{
CV_OCL_RUN(images.total() == 1 && channels.size() == 1 && images.channels(0) == 1 &&
channels[0] == 0 && images.isUMatVector() && mask.empty() && !accumulate &&
histSize.size() == 1 && histSize[0] == BINS && ranges.size() == 2 &&
ranges[0] == 0 && ranges[1] == 256,
ocl_calcHist(images, hist))
int i, dims = (int)histSize.size(), rsz = (int)ranges.size(), csz = (int)channels.size();
int nimages = (int)images.total();
@ -3290,47 +3347,13 @@ CV_IMPL void cvEqualizeHist( const CvArr* srcarr, CvArr* dstarr )
namespace cv {
enum
{
BINS = 256
};
static bool ocl_calcHist(InputArray _src, OutputArray _hist)
{
int compunits = ocl::Device::getDefault().maxComputeUnits();
size_t wgs = ocl::Device::getDefault().maxWorkGroupSize();
ocl::Kernel k1("calculate_histogram", ocl::imgproc::histogram_oclsrc,
format("-D BINS=%d -D HISTS_COUNT=%d -D WGS=%d", BINS, compunits, wgs));
if (k1.empty())
return false;
_hist.create(1, BINS, CV_32SC1);
UMat src = _src.getUMat(), hist = _hist.getUMat(), ghist(1, BINS * compunits, CV_32SC1);
k1.args(ocl::KernelArg::ReadOnly(src), ocl::KernelArg::PtrWriteOnly(ghist),
(int)src.total());
size_t globalsize = compunits * wgs;
if (!k1.run(1, &globalsize, &wgs, false))
return false;
ocl::Kernel k2("merge_histogram", ocl::imgproc::histogram_oclsrc,
format("-D BINS=%d -D HISTS_COUNT=%d -D WGS=%d", BINS, compunits, (int)wgs));
if (k2.empty())
return false;
k2.args(ocl::KernelArg::PtrReadOnly(ghist), ocl::KernelArg::PtrWriteOnly(hist));
return k2.run(1, &wgs, &wgs, false);
}
static bool ocl_equalizeHist(InputArray _src, OutputArray _dst)
{
size_t wgs = std::min<size_t>(ocl::Device::getDefault().maxWorkGroupSize(), BINS);
// calculation of histogram
UMat hist;
if (!ocl_calcHist(_src, hist))
if (!ocl_calcHist1(_src, hist))
return false;
UMat lut(1, 256, CV_8UC1);

View File

@ -144,11 +144,6 @@ PARAM_TEST_CASE(CalcBackProject, MatDepth, int, bool)
scale = randomDouble(0.1, 1);
}
void Near()
{
OCL_EXPECT_MATS_NEAR(dst, 0.0)
}
};
//////////////////////////////// CalcBackProject //////////////////////////////////////////////
@ -162,13 +157,62 @@ OCL_TEST_P(CalcBackProject, Mat)
OCL_OFF(cv::calcBackProject(images_roi, channels, hist_roi, dst_roi, ranges, scale));
OCL_ON(cv::calcBackProject(uimages_roi, channels, uhist_roi, udst_roi, ranges, scale));
Near();
OCL_EXPECT_MATS_NEAR(dst, 0.0)
}
}
//////////////////////////////// CalcHist //////////////////////////////////////////////
PARAM_TEST_CASE(CalcHist, bool)
{
bool useRoi;
TEST_DECLARE_INPUT_PARAMETER(src)
TEST_DECLARE_OUTPUT_PARAMETER(hist)
virtual void SetUp()
{
useRoi = GET_PARAM(0);
}
virtual void random_roi()
{
Size roiSize = randomSize(1, MAX_VALUE);
Border srcBorder = randomBorder(0, useRoi ? MAX_VALUE : 0);
randomSubMat(src, src_roi, roiSize, srcBorder, CV_8UC1, 0, 256);
Border histBorder = randomBorder(0, useRoi ? MAX_VALUE : 0);
randomSubMat(hist, hist_roi, Size(1, 256), histBorder, CV_32SC1, 0, MAX_VALUE);
UMAT_UPLOAD_INPUT_PARAMETER(src)
UMAT_UPLOAD_OUTPUT_PARAMETER(hist)
}
};
OCL_TEST_P(CalcHist, Mat)
{
const std::vector<int> channels(1, 0);
std::vector<float> ranges(2);
std::vector<int> histSize(1, 256);
ranges[0] = 0;
ranges[1] = 256;
for (int j = 0; j < test_loop_times; j++)
{
random_roi();
OCL_OFF(cv::calcHist(std::vector<Mat>(1, src_roi), channels, noArray(), hist_roi, histSize, ranges, false));
OCL_ON(cv::calcHist(std::vector<UMat>(1, usrc_roi), channels, noArray(), uhist_roi, histSize, ranges, false));
OCL_EXPECT_MATS_NEAR(hist, 0.0)
}
}
/////////////////////////////////////////////////////////////////////////////////////
OCL_INSTANTIATE_TEST_CASE_P(Imgproc, CalcBackProject, Combine(Values((MatDepth)CV_8U), Values(1, 2), Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Imgproc, CalcHist, Values(true, false));
} } // namespace cvtest::ocl