Commit ba2eee9c authored by Andrey Pavlenko's avatar Andrey Pavlenko Committed by OpenCV Buildbot

Merge pull request #2522 from ilya-lavrenov:tapi_canny

parents 9c574538 6ba60a1e
......@@ -100,19 +100,29 @@ static bool ocl_Canny(InputArray _src, OutputArray _dst, float low_thresh, float
low_thresh = std::min(32767.0f, low_thresh);
high_thresh = std::min(32767.0f, high_thresh);
if (low_thresh > 0) low_thresh *= low_thresh;
if (high_thresh > 0) high_thresh *= high_thresh;
if (low_thresh > 0)
low_thresh *= low_thresh;
if (high_thresh > 0)
high_thresh *= high_thresh;
}
int low = cvFloor(low_thresh), high = cvFloor(high_thresh);
Size esize(size.width + 2, size.height + 2);
UMat mag;
size_t globalsize[2] = { size.width * cn, size.height }, localsize[2] = { 16, 16 };
size_t globalsize[2] = { size.width, size.height }, localsize[2] = { 16, 16 };
if (aperture_size == 3 && !_src.isSubmatrix())
{
// Sobel calculation
ocl::Kernel calcSobelRowPassKernel("calcSobelRowPass", ocl::imgproc::canny_oclsrc);
char cvt[2][40];
ocl::Kernel calcSobelRowPassKernel("calcSobelRowPass", ocl::imgproc::canny_oclsrc,
format("-D OP_SOBEL -D cn=%d -D shortT=%s -D ucharT=%s"
" -D convertToIntT=%s -D intT=%s -D convertToShortT=%s", cn,
ocl::typeToStr(CV_16SC(cn)),
ocl::typeToStr(CV_8UC(cn)),
ocl::convertTypeStr(CV_8U, CV_32S, cn, cvt[0]),
ocl::typeToStr(CV_32SC(cn)),
ocl::convertTypeStr(CV_32S, CV_16S, cn, cvt[1])));
if (calcSobelRowPassKernel.empty())
return false;
......@@ -126,58 +136,62 @@ static bool ocl_Canny(InputArray _src, OutputArray _dst, float low_thresh, float
// magnitude calculation
ocl::Kernel magnitudeKernel("calcMagnitude_buf", ocl::imgproc::canny_oclsrc,
L2gradient ? " -D L2GRAD" : "");
format("-D cn=%d%s -D OP_MAG_BUF -D shortT=%s -D convertToIntT=%s -D intT=%s",
cn, L2gradient ? " -D L2GRAD" : "",
ocl::typeToStr(CV_16SC(cn)),
ocl::convertTypeStr(CV_16S, CV_32S, cn, cvt[0]),
ocl::typeToStr(CV_32SC(cn))));
if (magnitudeKernel.empty())
return false;
mag = UMat(esize, CV_32SC(cn), Scalar::all(0));
mag = UMat(esize, CV_32SC1, Scalar::all(0));
dx.create(size, CV_16SC(cn));
dy.create(size, CV_16SC(cn));
magnitudeKernel.args(ocl::KernelArg::ReadOnlyNoSize(dxBuf), ocl::KernelArg::ReadOnlyNoSize(dyBuf),
ocl::KernelArg::WriteOnlyNoSize(dx), ocl::KernelArg::WriteOnlyNoSize(dy),
ocl::KernelArg::WriteOnlyNoSize(mag, cn), size.height, size.width);
ocl::KernelArg::WriteOnlyNoSize(mag), size.height, size.width);
if (!magnitudeKernel.run(2, globalsize, localsize, false))
return false;
}
else
{
dx.create(size, CV_16SC(cn));
dy.create(size, CV_16SC(cn));
Sobel(_src, dx, CV_16SC1, 1, 0, aperture_size, 1, 0, BORDER_REPLICATE);
Sobel(_src, dy, CV_16SC1, 0, 1, aperture_size, 1, 0, BORDER_REPLICATE);
Sobel(_src, dx, CV_16S, 1, 0, aperture_size, 1, 0, BORDER_REPLICATE);
Sobel(_src, dy, CV_16S, 0, 1, aperture_size, 1, 0, BORDER_REPLICATE);
// magnitude calculation
ocl::Kernel magnitudeKernel("calcMagnitude", ocl::imgproc::canny_oclsrc,
L2gradient ? " -D L2GRAD" : "");
format("-D OP_MAG -D cn=%d%s -D intT=int -D shortT=short -D convertToIntT=convert_int_sat",
cn, L2gradient ? " -D L2GRAD" : ""));
if (magnitudeKernel.empty())
return false;
mag = UMat(esize, CV_32SC(cn), Scalar::all(0));
mag = UMat(esize, CV_32SC1, Scalar::all(0));
magnitudeKernel.args(ocl::KernelArg::ReadOnlyNoSize(dx), ocl::KernelArg::ReadOnlyNoSize(dy),
ocl::KernelArg::WriteOnlyNoSize(mag, cn), size.height, size.width);
ocl::KernelArg::WriteOnlyNoSize(mag), size.height, size.width);
if (!magnitudeKernel.run(2, globalsize, NULL, false))
return false;
}
// map calculation
ocl::Kernel calcMapKernel("calcMap", ocl::imgproc::canny_oclsrc);
ocl::Kernel calcMapKernel("calcMap", ocl::imgproc::canny_oclsrc,
format("-D OP_MAP -D cn=%d", cn));
if (calcMapKernel.empty())
return false;
UMat map(esize, CV_32SC(cn));
UMat map(esize, CV_32SC1);
calcMapKernel.args(ocl::KernelArg::ReadOnlyNoSize(dx), ocl::KernelArg::ReadOnlyNoSize(dy),
ocl::KernelArg::ReadOnlyNoSize(mag), ocl::KernelArg::WriteOnlyNoSize(map, cn),
ocl::KernelArg::ReadOnlyNoSize(mag), ocl::KernelArg::WriteOnlyNoSize(map),
size.height, size.width, low, high);
if (!calcMapKernel.run(2, globalsize, localsize, false))
return false;
// local hysteresis thresholding
ocl::Kernel edgesHysteresisLocalKernel("edgesHysteresisLocal", ocl::imgproc::canny_oclsrc);
ocl::Kernel edgesHysteresisLocalKernel("edgesHysteresisLocal", ocl::imgproc::canny_oclsrc,
"-D OP_HYST_LOCAL");
if (edgesHysteresisLocalKernel.empty())
return false;
......@@ -193,7 +207,8 @@ static bool ocl_Canny(InputArray _src, OutputArray _dst, float low_thresh, float
for ( ; ; )
{
ocl::Kernel edgesHysteresisGlobalKernel("edgesHysteresisGlobal", ocl::imgproc::canny_oclsrc);
ocl::Kernel edgesHysteresisGlobalKernel("edgesHysteresisGlobal", ocl::imgproc::canny_oclsrc,
"-D OP_HYST_GLOBAL");
if (edgesHysteresisGlobalKernel.empty())
return false;
......@@ -221,14 +236,15 @@ static bool ocl_Canny(InputArray _src, OutputArray _dst, float low_thresh, float
}
// get edges
ocl::Kernel getEdgesKernel("getEdges", ocl::imgproc::canny_oclsrc);
ocl::Kernel getEdgesKernel("getEdges", ocl::imgproc::canny_oclsrc, "-D OP_EDGES");
if (getEdgesKernel.empty())
return false;
_dst.create(size, CV_8UC(cn));
_dst.create(size, CV_8UC1);
UMat dst = _dst.getUMat();
getEdgesKernel.args(ocl::KernelArg::ReadOnlyNoSize(map), ocl::KernelArg::WriteOnly(dst));
return getEdgesKernel.run(2, globalsize, NULL, false);
}
......@@ -254,12 +270,12 @@ void cv::Canny( InputArray _src, OutputArray _dst,
}
if ((aperture_size & 1) == 0 || (aperture_size != -1 && (aperture_size < 3 || aperture_size > 7)))
CV_Error(CV_StsBadFlag, "");
CV_Error(CV_StsBadFlag, "Aperture size should be odd");
if (low_thresh > high_thresh)
std::swap(low_thresh, high_thresh);
CV_OCL_RUN(_dst.isUMat() && cn == 1,
CV_OCL_RUN(_dst.isUMat() && (cn == 1 || cn == 3),
ocl_Canny(_src, _dst, (float)low_thresh, (float)high_thresh, aperture_size, L2gradient, cn, size))
Mat src = _src.getMat(), dst = _dst.getMat();
......
This diff is collapsed.
......@@ -58,9 +58,9 @@ IMPLEMENT_PARAM_CLASS(AppertureSize, int)
IMPLEMENT_PARAM_CLASS(L2gradient, bool)
IMPLEMENT_PARAM_CLASS(UseRoi, bool)
PARAM_TEST_CASE(Canny, AppertureSize, L2gradient, UseRoi)
PARAM_TEST_CASE(Canny, Channels, AppertureSize, L2gradient, UseRoi)
{
int apperture_size;
int cn, apperture_size;
bool useL2gradient, use_roi;
TEST_DECLARE_INPUT_PARAMETER(src);
......@@ -68,19 +68,19 @@ PARAM_TEST_CASE(Canny, AppertureSize, L2gradient, UseRoi)
virtual void SetUp()
{
apperture_size = GET_PARAM(0);
useL2gradient = GET_PARAM(1);
use_roi = GET_PARAM(2);
cn = GET_PARAM(0);
apperture_size = GET_PARAM(1);
useL2gradient = GET_PARAM(2);
use_roi = GET_PARAM(3);
}
void generateTestData()
{
Mat img = readImage("shared/fruits.png", IMREAD_GRAYSCALE);
Mat img = readImageType("shared/fruits.png", CV_8UC(cn));
ASSERT_FALSE(img.empty()) << "cann't load shared/fruits.png";
Size roiSize = img.size();
int type = img.type();
ASSERT_EQ(CV_8UC1, type);
Border srcBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src, src_roi, roiSize, srcBorder, type, 2, 100);
......@@ -108,6 +108,7 @@ OCL_TEST_P(Canny, Accuracy)
}
OCL_INSTANTIATE_TEST_CASE_P(ImgProc, Canny, testing::Combine(
testing::Values(1, 3),
testing::Values(AppertureSize(3), AppertureSize(5)),
testing::Values(L2gradient(false), L2gradient(true)),
testing::Values(UseRoi(false), UseRoi(true))));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment