mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
Enable state initialization params via compile_args
This commit is contained in:
@@ -8,6 +8,33 @@
|
||||
#include <opencv2/gapi/cpu/core.hpp>
|
||||
#include <opencv2/gapi/streaming/cap.hpp>
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/core/cvstd.hpp>
|
||||
#include <opencv2/video.hpp>
|
||||
|
||||
|
||||
namespace opencv_test
|
||||
{
|
||||
struct BackSubStateParams
|
||||
{
|
||||
std::string method;
|
||||
};
|
||||
}
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<> struct CompileArgTag<opencv_test::BackSubStateParams>
|
||||
{
|
||||
static const char* tag()
|
||||
{
|
||||
return "org.opencv.test..background_substractor_state_params";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace opencv_test
|
||||
{
|
||||
//TODO: test OT, Background Subtractor, Kalman with 3rd version of API
|
||||
@@ -56,8 +83,7 @@ namespace
|
||||
|
||||
GAPI_OCV_KERNEL_ST(GOCVIsStateUpToDate, GIsStateUpToDate, cv::Size)
|
||||
{
|
||||
static void setup(const cv::GMatDesc &in,
|
||||
std::shared_ptr<cv::Size> &state)
|
||||
static void setup(const cv::GMatDesc &in, std::shared_ptr<cv::Size> &state)
|
||||
{
|
||||
state.reset(new cv::Size(in.size));
|
||||
}
|
||||
@@ -68,7 +94,8 @@ namespace
|
||||
}
|
||||
};
|
||||
|
||||
G_TYPED_KERNEL(GStInvalidResize, <GMat(GMat,Size,double,double,int)>, "org.opencv.test.st_invalid_resize")
|
||||
G_TYPED_KERNEL(GStInvalidResize, <GMat(GMat,Size,double,double,int)>,
|
||||
"org.opencv.test.st_invalid_resize")
|
||||
{
|
||||
static GMatDesc outMeta(GMatDesc in, Size, double, double, int) { return in; }
|
||||
};
|
||||
@@ -85,6 +112,34 @@ namespace
|
||||
cv::resize(in, out, sz, fx, fy, interp);
|
||||
}
|
||||
};
|
||||
|
||||
G_TYPED_KERNEL(GBackSub, <GMat(GMat)>, "org.opencv.test.background_substractor")
|
||||
{
|
||||
static GMatDesc outMeta(GMatDesc in) { return in.withType(CV_8U, 1); }
|
||||
};
|
||||
|
||||
GAPI_OCV_KERNEL_ST(GOCVBackSub, GBackSub, cv::BackgroundSubtractor)
|
||||
{
|
||||
static void setup(const cv::GMatDesc &/* desc */,
|
||||
std::shared_ptr<BackgroundSubtractor> &state,
|
||||
const cv::GCompileArgs &compileArgs)
|
||||
{
|
||||
auto sbParams = cv::gapi::getCompileArg<BackSubStateParams>(compileArgs)
|
||||
.value_or(BackSubStateParams { });
|
||||
|
||||
if (sbParams.method == "knn")
|
||||
state = createBackgroundSubtractorKNN();
|
||||
else if (sbParams.method == "mog2")
|
||||
state = createBackgroundSubtractorMOG2();
|
||||
|
||||
GAPI_Assert(state);
|
||||
}
|
||||
|
||||
static void run(const cv::Mat& in, cv::Mat &out, BackgroundSubtractor& state)
|
||||
{
|
||||
state.apply(in, out, -1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
TEST(StatefulKernel, StateIsMutableInRuntime)
|
||||
@@ -126,7 +181,7 @@ TEST(StatefulKernel, StateIsAutoResetForNewStream)
|
||||
initTestDataPath();
|
||||
|
||||
cv::GMat in;
|
||||
GOpaque<bool> out = GIsStateUpToDate::on(in);
|
||||
cv::GOpaque<bool> out = GIsStateUpToDate::on(in);
|
||||
cv::GComputation c(cv::GIn(in), cv::GOut(out));
|
||||
|
||||
const auto pkg = cv::gapi::kernels<GOCVIsStateUpToDate>();
|
||||
@@ -167,7 +222,123 @@ TEST(StatefulKernel, InvalidReallocatingKernel)
|
||||
cv::GComputation comp(cv::GIn(in), cv::GOut(out));
|
||||
|
||||
EXPECT_THROW(comp.apply(in_mat, out_mat, cv::compile_args(pkg)), std::logic_error);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void compareBackSubResults(const cv::Mat &actual, const cv::Mat &expected,
|
||||
const int diffPercent)
|
||||
{
|
||||
GAPI_Assert(actual.size() == expected.size());
|
||||
int allowedNumDiffPixels = actual.size().area() * diffPercent / 100;
|
||||
|
||||
cv::Mat diff;
|
||||
cv::absdiff(actual, expected, diff);
|
||||
|
||||
cv::Mat hist(256, 1, CV_32FC1, cv::Scalar(0));
|
||||
const float range[] { 0, 256 };
|
||||
const float *histRange { range };
|
||||
calcHist(&diff, 1, 0, Mat(), hist, 1, &hist.rows, &histRange, true, false);
|
||||
for (int i = 2; i < hist.rows; ++i)
|
||||
{
|
||||
hist.at<float>(i) += hist.at<float>(i - 1);
|
||||
}
|
||||
|
||||
int numDiffPixels = static_cast<int>(hist.at<float>(255));
|
||||
|
||||
EXPECT_GT(allowedNumDiffPixels, numDiffPixels);
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
TEST(StatefulKernel, StateIsInitViaCompArgs)
|
||||
{
|
||||
cv::Mat frame(1080, 1920, CV_8UC3),
|
||||
gapiForeground,
|
||||
ocvForeground;
|
||||
|
||||
cv::randu(frame, cv::Scalar(0, 0, 0), cv::Scalar(255, 255, 255));
|
||||
|
||||
// G-API code
|
||||
cv::GMat in;
|
||||
cv::GMat out = GBackSub::on(in);
|
||||
cv::GComputation c(cv::GIn(in), cv::GOut(out));
|
||||
|
||||
const auto pkg = cv::gapi::kernels<GOCVBackSub>();
|
||||
|
||||
auto gapiBackSub = c.compile(cv::descr_of(frame),
|
||||
cv::compile_args(pkg, BackSubStateParams { "knn" }));
|
||||
|
||||
gapiBackSub(cv::gin(frame), cv::gout(gapiForeground));
|
||||
|
||||
// OpenCV code
|
||||
auto pOcvBackSub = createBackgroundSubtractorKNN();
|
||||
pOcvBackSub->apply(frame, ocvForeground);
|
||||
|
||||
// Comparison
|
||||
// Allowing 1% difference of all pixels between G-API and OpenCV results
|
||||
compareBackSubResults(gapiForeground, ocvForeground, 1);
|
||||
|
||||
// Additionally, test the case where state is resetted
|
||||
gapiBackSub.prepareForNewStream();
|
||||
gapiBackSub(cv::gin(frame), cv::gout(gapiForeground));
|
||||
pOcvBackSub->apply(frame, ocvForeground);
|
||||
compareBackSubResults(gapiForeground, ocvForeground, 1);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void testBackSubInStreaming(cv::GStreamingCompiled gapiBackSub, const int diffPercent)
|
||||
{
|
||||
cv::Mat frame,
|
||||
gapiForeground,
|
||||
ocvForeground;
|
||||
|
||||
gapiBackSub.start();
|
||||
EXPECT_TRUE(gapiBackSub.running());
|
||||
|
||||
// OpenCV reference substractor
|
||||
auto pOCVBackSub = createBackgroundSubtractorKNN();
|
||||
|
||||
// Comparison of G-API and OpenCV substractors
|
||||
std::size_t frames = 0u;
|
||||
while (gapiBackSub.pull(cv::gout(frame, gapiForeground))) {
|
||||
pOCVBackSub->apply(frame, ocvForeground, -1);
|
||||
|
||||
compareBackSubResults(gapiForeground, ocvForeground, diffPercent);
|
||||
|
||||
frames++;
|
||||
}
|
||||
EXPECT_LT(0u, frames);
|
||||
EXPECT_FALSE(gapiBackSub.running());
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
TEST(StatefulKernel, StateIsInitViaCompArgsInStreaming)
|
||||
{
|
||||
initTestDataPath();
|
||||
|
||||
// G-API graph declaration
|
||||
cv::GMat in;
|
||||
cv::GMat out = GBackSub::on(in);
|
||||
// Preserving 'in' in output to have possibility to compare with OpenCV reference
|
||||
cv::GComputation c(cv::GIn(in), cv::GOut(cv::gapi::copy(in), out));
|
||||
|
||||
// G-API compilation of graph for streaming mode
|
||||
const auto pkg = cv::gapi::kernels<GOCVBackSub>();
|
||||
auto gapiBackSub = c.compileStreaming(
|
||||
cv::compile_args(pkg, BackSubStateParams { "knn" }));
|
||||
|
||||
// Testing G-API Background Substractor in streaming mode
|
||||
gapiBackSub.setSource(gapi::wip::make_src<cv::gapi::wip::GCaptureSource>
|
||||
(findDataFile("cv/video/768x576.avi")));
|
||||
// Allowing 1% difference of all pixels between G-API and reference OpenCV results
|
||||
testBackSubInStreaming(gapiBackSub, 1);
|
||||
|
||||
// Additionally, test the case when the new stream happens
|
||||
gapiBackSub.setSource(gapi::wip::make_src<cv::gapi::wip::GCaptureSource>
|
||||
(findDataFile("cv/video/1920x1080.avi")));
|
||||
// Allowing 5% difference of all pixels between G-API and reference OpenCV results
|
||||
testBackSubInStreaming(gapiBackSub, 5);
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -179,7 +350,7 @@ template<typename Tuple>
|
||||
struct SetupStateTypedTest : public ::testing::Test
|
||||
{
|
||||
using StateT = typename std::tuple_element<0, Tuple>::type;
|
||||
using SetupT = typename std::tuple_element<1, Tuple>::type;
|
||||
using SetupT = typename std::tuple_element<1, Tuple>::type;
|
||||
|
||||
G_TYPED_KERNEL(GReturnState, <cv::GOpaque<StateT>(GMat)>, "org.opencv.test.return_state")
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user