diff --git a/modules/gpu/perf/perf_imgproc.cpp b/modules/gpu/perf/perf_imgproc.cpp index b5c986d22..77f607452 100644 --- a/modules/gpu/perf/perf_imgproc.cpp +++ b/modules/gpu/perf/perf_imgproc.cpp @@ -1331,4 +1331,45 @@ INSTANTIATE_TEST_CASE_P(ImgProc, ImagePyramid_getLayer, testing::Combine( MatType(CV_16UC1), MatType(CV_16UC3), MatType(CV_16UC4), MatType(CV_32FC1), MatType(CV_32FC3), MatType(CV_32FC4)))); +////////////////////////////////////////////////////////////////////// +// HoughLines + +GPU_PERF_TEST(HoughLines, cv::gpu::DeviceInfo, std::string) +{ + const cv::gpu::DeviceInfo devInfo = GET_PARAM(0); + cv::gpu::setDevice(devInfo.deviceID()); + const std::string fileName = GET_PARAM(1); + + const float rho = 1.0f; + const float theta = CV_PI / 180.0f; + const int threshold = 300; + + cv::Mat img_base = readImage(fileName, cv::IMREAD_GRAYSCALE); + ASSERT_FALSE(img_base.empty()); + + cv::Mat img; + cv::resize(img_base, img, cv::Size(1920, 1080)); + + cv::Mat edges; + cv::Canny(img, edges, 50, 200); + + cv::gpu::GpuMat d_edges(edges); + cv::gpu::GpuMat d_lines; + cv::gpu::GpuMat d_accum; + cv::gpu::HoughLines(d_edges, d_lines, d_accum, rho, theta, threshold); + + TEST_CYCLE() + { + cv::gpu::HoughLines(d_edges, d_lines, d_accum, rho, theta, threshold); + } +} + +INSTANTIATE_TEST_CASE_P(ImgProc, HoughLines, testing::Combine( + ALL_DEVICES, + testing::Values(std::string("cv/shared/pic1.png"), + std::string("cv/shared/pic3.png"), + std::string("cv/shared/pic4.png"), + std::string("cv/shared/pic5.png"), + std::string("cv/shared/pic6.png")))); + #endif diff --git a/modules/gpu/perf_cpu/perf_imgproc.cpp b/modules/gpu/perf_cpu/perf_imgproc.cpp index b6686b7ed..bc7764683 100644 --- a/modules/gpu/perf_cpu/perf_imgproc.cpp +++ b/modules/gpu/perf_cpu/perf_imgproc.cpp @@ -727,4 +727,41 @@ INSTANTIATE_TEST_CASE_P(ImgProc, CvtColor, testing::Combine( CvtColorInfo(1, 3, cv::COLOR_BayerGR2BGR), CvtColorInfo(4, 4, cv::COLOR_RGBA2mRGBA)))); +////////////////////////////////////////////////////////////////////// +// HoughLines + +GPU_PERF_TEST(HoughLines, cv::gpu::DeviceInfo, std::string) +{ + const std::string fileName = GET_PARAM(1); + + const float rho = 1.0f; + const float theta = CV_PI / 180.0f; + const int threshold = 300; + + cv::Mat img_base = readImage(fileName, cv::IMREAD_GRAYSCALE); + ASSERT_FALSE(img_base.empty()); + + cv::Mat img; + cv::resize(img_base, img, cv::Size(1920, 1080)); + + cv::Mat edges; + cv::Canny(img, edges, 50, 200); + + std::vector lines; + cv::HoughLines(edges, lines, rho, theta, threshold); + + TEST_CYCLE() + { + cv::HoughLines(edges, lines, rho, theta, threshold); + } +} + +INSTANTIATE_TEST_CASE_P(ImgProc, HoughLines, testing::Combine( + ALL_DEVICES, + testing::Values(std::string("cv/shared/pic1.png"), + std::string("cv/shared/pic3.png"), + std::string("cv/shared/pic4.png"), + std::string("cv/shared/pic5.png"), + std::string("cv/shared/pic6.png")))); + #endif diff --git a/modules/gpu/src/hough.cpp b/modules/gpu/src/hough.cpp index 888c02724..721e6802a 100644 --- a/modules/gpu/src/hough.cpp +++ b/modules/gpu/src/hough.cpp @@ -74,7 +74,12 @@ void cv::gpu::HoughLinesGet(const GpuMat& accum, GpuMat& lines, float rho, float CV_Assert(accum.type() == CV_32SC1); lines.create(2, maxLines, CV_32FC2); - lines.cols = hough::linesGetResult_gpu(accum, lines.ptr(0), lines.ptr(1), maxLines, threshold, theta, rho, doSort); + int count = hough::linesGetResult_gpu(accum, lines.ptr(0), lines.ptr(1), maxLines, threshold, theta, rho, doSort); + + if (count > 0) + lines.cols = std::min(count, maxLines); + else + lines.release(); } void cv::gpu::HoughLines(const GpuMat& src, GpuMat& lines, float rho, float theta, int threshold, bool doSort, int maxLines) @@ -91,6 +96,16 @@ void cv::gpu::HoughLines(const GpuMat& src, GpuMat& lines, GpuMat& accum, float void cv::gpu::HoughLinesDownload(const GpuMat& d_lines, OutputArray h_lines_, OutputArray h_voices_) { + if (d_lines.empty()) + { + h_lines_.release(); + if (h_voices_.needed()) + h_voices_.release(); + return; + } + + CV_Assert(d_lines.rows == 2 && d_lines.type() == CV_32FC2); + h_lines_.create(1, d_lines.cols, CV_32FC2); cv::Mat h_lines = h_lines_.getMat(); d_lines.row(0).download(h_lines); diff --git a/modules/gpu/test/test_imgproc.cpp b/modules/gpu/test/test_imgproc.cpp index 388badf45..b0e587e4a 100644 --- a/modules/gpu/test/test_imgproc.cpp +++ b/modules/gpu/test/test_imgproc.cpp @@ -1124,4 +1124,66 @@ INSTANTIATE_TEST_CASE_P(GPU_ImgProc, CornerMinEigen, testing::Combine( testing::Values(BlockSize(3), BlockSize(5), BlockSize(7)), testing::Values(ApertureSize(0), ApertureSize(3), ApertureSize(5), ApertureSize(7)))); +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// HoughLines + +PARAM_TEST_CASE(HoughLines, cv::gpu::DeviceInfo, std::string) +{ +}; + +void drawLines(cv::Mat& dst, const std::vector& lines) +{ + for (size_t i = 0; i < lines.size(); ++i) + { + float rho = lines[i][0], theta = lines[i][1]; + cv::Point pt1, pt2; + double a = std::cos(theta), b = std::sin(theta); + double x0 = a*rho, y0 = b*rho; + pt1.x = cvRound(x0 + 1000*(-b)); + pt1.y = cvRound(y0 + 1000*(a)); + pt2.x = cvRound(x0 - 1000*(-b)); + pt2.y = cvRound(y0 - 1000*(a)); + cv::line(dst, pt1, pt2, cv::Scalar::all(255)); + } +} + +TEST_P(HoughLines, Accuracy) +{ + const cv::gpu::DeviceInfo devInfo = GET_PARAM(0); + cv::gpu::setDevice(devInfo.deviceID()); + const std::string fileName = GET_PARAM(1); + + const float rho = 1.0f; + const float theta = CV_PI / 180.0f; + const int threshold = 300; + + cv::Mat img = readImage(fileName, cv::IMREAD_GRAYSCALE); + ASSERT_FALSE(img.empty()); + + cv::Mat edges; + cv::Canny(img, edges, 50, 200); + + cv::gpu::GpuMat d_lines; + cv::gpu::HoughLines(loadMat(edges), d_lines, rho, theta, threshold); + std::vector lines; + cv::gpu::HoughLinesDownload(d_lines, lines); + cv::Mat dst(img.size(), CV_8UC1, cv::Scalar::all(0)); + drawLines(dst, lines); + + std::vector lines_gold; + cv::HoughLines(edges, lines_gold, rho, theta, threshold); + cv::Mat dst_gold(img.size(), CV_8UC1, cv::Scalar::all(0)); + drawLines(dst_gold, lines_gold); + + ASSERT_MAT_NEAR(dst_gold, dst, 0.0); +} + +INSTANTIATE_TEST_CASE_P(GPU_ImgProc, HoughLines, testing::Combine( + ALL_DEVICES, + testing::Values(std::string("../cv/shared/pic1.png"), + std::string("../cv/shared/pic3.png"), + std::string("../cv/shared/pic4.png"), + std::string("../cv/shared/pic5.png"), + std::string("../cv/shared/pic6.png")))); + } // namespace