From 2bd35c4358400657b0b6b1a47905152410e01628 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Mon, 15 Oct 2012 21:55:57 +0400 Subject: [PATCH] add support for precomputed integrals --- modules/gpu/perf/perf_softcascade.cpp | 56 ++++++++++++++++++++++++++++++++--- modules/gpu/src/softcascade.cpp | 15 +++++++--- modules/gpu/test/test_softcascade.cpp | 33 +++++++++++++++++++++ 3 files changed, 96 insertions(+), 8 deletions(-) diff --git a/modules/gpu/perf/perf_softcascade.cpp b/modules/gpu/perf/perf_softcascade.cpp index d379d7f..582561c 100644 --- a/modules/gpu/perf/perf_softcascade.cpp +++ b/modules/gpu/perf/perf_softcascade.cpp @@ -9,7 +9,7 @@ virtual void __gpu();\ virtual void PerfTestBody();\ };\ - TEST_P(fixture##_##name, name /*perf*/){ RunPerfTestBody(); if (runOnGpu) __gpu(); else __cpu();}\ + TEST_P(fixture##_##name, name /*perf*/){ RunPerfTestBody(); if (PERF_RUN_GPU()) __gpu(); else __cpu();}\ INSTANTIATE_TEST_CASE_P(/*none*/, fixture##_##name, params);\ void fixture##_##name::PerfTestBody() @@ -19,7 +19,7 @@ #define RUN_GPU(fixture, name)\ void fixture##_##name::__gpu() -#define FAIL_NO_CPU(fixture, name)\ +#define NO_CPU(fixture, name)\ void fixture##_##name::__cpu() { FAIL() << "No such CPU implementation analogy";} namespace { @@ -184,7 +184,7 @@ RUN_GPU(SoftCascadeTestRoi, detectInRoi) SANITY_CHECK(sortDetections(curr)); } -FAIL_NO_CPU(SoftCascadeTestRoi, detectInRoi) +NO_CPU(SoftCascadeTestRoi, detectInRoi) GPU_PERF_TEST_P(SoftCascadeTestRoi, detectEachRoi, @@ -226,4 +226,52 @@ RUN_GPU(SoftCascadeTestRoi, detectEachRoi) SANITY_CHECK(sortDetections(curr)); } -FAIL_NO_CPU(SoftCascadeTestRoi, detectEachRoi) +NO_CPU(SoftCascadeTestRoi, detectEachRoi) + +GPU_PERF_TEST_P(SoftCascadeTest, detectOnIntegral, + testing::Combine( + testing::Values(std::string("cv/cascadeandhog/sc_cvpr_2012_to_opencv.xml")), + testing::Values(std::string("cv/cascadeandhog/integrals.xml")))) +{ } + + static std::string itoa(long i) + { + static char s[65]; + sprintf(s, "%ld", i); + return std::string(s); + } + +RUN_GPU(SoftCascadeTest, detectOnIntegral) +{ + cv::FileStorage fs(perf::TestBase::getDataPath(GET_PARAM(1)), cv::FileStorage::READ); + ASSERT_TRUE(fs.isOpened()); + + cv::gpu::GpuMat hogluv(121 * 10, 161, CV_32SC1); + for (int i = 0; i < 10; ++i) + { + cv::Mat channel; + fs[std::string("channel") + itoa(i)] >> channel; + cv::gpu::GpuMat gchannel(hogluv, cv::Rect(0, 121 * i, 161, 121)); + gchannel.upload(channel); + } + + cv::gpu::SoftCascade cascade; + ASSERT_TRUE(cascade.load(perf::TestBase::getDataPath(GET_PARAM(0)))); + + cv::gpu::GpuMat objectBoxes(1, 10000 * sizeof(cv::gpu::SoftCascade::Detection), CV_8UC1), rois(cascade.getRoiSize(), CV_8UC1), trois; + rois.setTo(1); + cv::gpu::transpose(rois, trois); + + cv::gpu::GpuMat curr = objectBoxes; + cascade.detectMultiScale(hogluv, trois, curr); + + TEST_CYCLE() + { + curr = objectBoxes; + cascade.detectMultiScale(hogluv, trois, curr); + } + + SANITY_CHECK(sortDetections(curr)); +} + +NO_CPU(SoftCascadeTest, detectOnIntegral) \ No newline at end of file diff --git a/modules/gpu/src/softcascade.cpp b/modules/gpu/src/softcascade.cpp index 560c251..d9519e8 100644 --- a/modules/gpu/src/softcascade.cpp +++ b/modules/gpu/src/softcascade.cpp @@ -526,17 +526,24 @@ void cv::gpu::SoftCascade::detectMultiScale(const GpuMat& colored, const GpuMat& GpuMat& objects, const int /*rejectfactor*/, int specificScale) const { // only color images are supperted - CV_Assert(colored.type() == CV_8UC3); + CV_Assert(colored.type() == CV_8UC3 || colored.type() == CV_32SC1); // we guess user knows about shrincage CV_Assert((rois.size().width == getRoiSize().height) && (rois.type() == CV_8UC1)); - // only this window size allowed - CV_Assert(colored.cols == Filds::FRAME_WIDTH && colored.rows == Filds::FRAME_HEIGHT); Filds& flds = *filds; - flds.preprocess(colored); + if (colored.type() == CV_8UC3) + { + // only this window size allowed + CV_Assert(colored.cols == Filds::FRAME_WIDTH && colored.rows == Filds::FRAME_HEIGHT); + flds.preprocess(colored); + } + else + { + colored.copyTo(flds.hogluv); + } flds.detect(specificScale, rois, objects, 0); diff --git a/modules/gpu/test/test_softcascade.cpp b/modules/gpu/test/test_softcascade.cpp index 04c3855..bf88029 100644 --- a/modules/gpu/test/test_softcascade.cpp +++ b/modules/gpu/test/test_softcascade.cpp @@ -262,4 +262,37 @@ TEST(SoftCascadeTest, detect) cv::Mat detections(objectBoxes); ASSERT_EQ(detections.cols / sizeof(Detection) ,3670U); } + +TEST(SoftCascadeTest, detectOnIntegral) +{ + std::string xml = cvtest::TS::ptr()->get_data_path() + "../cv/cascadeandhog/sc_cvpr_2012_to_opencv.xml"; + cv::gpu::SoftCascade cascade; + ASSERT_TRUE(cascade.load(xml)); + + std::string intPath = cvtest::TS::ptr()->get_data_path() + "../cv/cascadeandhog/integrals.xml"; + cv::FileStorage fs(intPath, cv::FileStorage::READ); + ASSERT_TRUE(fs.isOpened()); + + GpuMat hogluv(121 * 10, 161, CV_32SC1); + for (int i = 0; i < 10; ++i) + { + cv::Mat channel; + fs[std::string("channel") + SoftCascadeTest::itoa(i)] >> channel; + GpuMat gchannel(hogluv, cv::Rect(0, 121 * i, 161, 121)); + gchannel.upload(channel); + } + + GpuMat objectBoxes(1, 100000, CV_8UC1), rois(cascade.getRoiSize(), CV_8UC1); + rois.setTo(1); + + cv::gpu::GpuMat trois; + cv::gpu::transpose(rois, trois); + + cascade.detectMultiScale(hogluv, trois, objectBoxes); + + typedef cv::gpu::SoftCascade::Detection Detection; + cv::Mat detections(objectBoxes); + + ASSERT_EQ(detections.cols / sizeof(Detection) ,2042U); +} #endif \ No newline at end of file -- 2.7.4