|
|
|
@ -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") |
|
|
|
|
{ |
|
|
|
|