| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007 |
- // This file is part of OpenCV project.
- // It is subject to the license terms in the LICENSE file found in the top-level directory
- // of this distribution and at http://opencv.org/license.html.
- //
- // Copyright (C) 2023 Intel Corporation
- #if defined HAVE_INF_ENGINE && INF_ENGINE_RELEASE >= 2022010000
- #include "../test_precomp.hpp"
- #include "backends/ov/util.hpp"
- #include <opencv2/gapi/infer/ov.hpp>
- #include <openvino/openvino.hpp>
- namespace opencv_test
- {
- namespace {
- // FIXME: taken from DNN module
- void initDLDTDataPath()
- {
- #ifndef WINRT
- static bool initialized = false;
- if (!initialized)
- {
- cvtest::addDataSearchEnv("OPENCV_OPEN_MODEL_ZOO_DATA_PATH");
- const std::string dnnDataPath = cv::utils::getConfigurationParameterString("OPENCV_DNN_TEST_DATA_PATH");
- if (!dnnDataPath.empty()) {
- // Add the dnnDataPath itself - G-API is using some images there directly
- cvtest::addDataSearchPath(dnnDataPath);
- cvtest::addDataSearchPath(dnnDataPath + std::string("/omz_intel_models"));
- }
- initialized = true;
- }
- #endif // WINRT
- }
- static const std::string SUBDIR = "intel/age-gender-recognition-retail-0013/FP32/";
- // FIXME: taken from the DNN module
- void normAssert(cv::InputArray ref, cv::InputArray test,
- const char *comment /*= ""*/,
- double l1 = 0.00001, double lInf = 0.0001) {
- double normL1 = cvtest::norm(ref, test, cv::NORM_L1) / ref.getMat().total();
- EXPECT_LE(normL1, l1) << comment;
- double normInf = cvtest::norm(ref, test, cv::NORM_INF);
- EXPECT_LE(normInf, lInf) << comment;
- }
- // TODO: AGNetGenComp, AGNetTypedComp, AGNetOVComp, AGNetOVCompiled
- // can be generalized to work with any model and used as parameters for tests.
- struct AGNetGenParams {
- static constexpr const char* tag = "age-gender-generic";
- using Params = cv::gapi::ov::Params<cv::gapi::Generic>;
- static Params params(const std::string &xml,
- const std::string &bin,
- const std::string &device) {
- return {tag, xml, bin, device};
- }
- static Params params(const std::string &blob_path,
- const std::string &device) {
- return {tag, blob_path, device};
- }
- };
- struct AGNetTypedParams {
- using AGInfo = std::tuple<cv::GMat, cv::GMat>;
- G_API_NET(AgeGender, <AGInfo(cv::GMat)>, "typed-age-gender");
- using Params = cv::gapi::ov::Params<AgeGender>;
- static Params params(const std::string &xml_path,
- const std::string &bin_path,
- const std::string &device) {
- return Params {
- xml_path, bin_path, device
- }.cfgOutputLayers({ "age_conv3", "prob" });
- }
- };
- struct AGNetTypedComp : AGNetTypedParams {
- static cv::GComputation create() {
- cv::GMat in;
- cv::GMat age, gender;
- std::tie(age, gender) = cv::gapi::infer<AgeGender>(in);
- return cv::GComputation{cv::GIn(in), cv::GOut(age, gender)};
- }
- };
- struct AGNetGenComp : public AGNetGenParams {
- static cv::GComputation create() {
- cv::GMat in;
- GInferInputs inputs;
- inputs["data"] = in;
- auto outputs = cv::gapi::infer<cv::gapi::Generic>(tag, inputs);
- auto age = outputs.at("age_conv3");
- auto gender = outputs.at("prob");
- return cv::GComputation{cv::GIn(in), cv::GOut(age, gender)};
- }
- };
- struct AGNetROIGenComp : AGNetGenParams {
- static cv::GComputation create() {
- cv::GMat in;
- cv::GOpaque<cv::Rect> roi;
- GInferInputs inputs;
- inputs["data"] = in;
- auto outputs = cv::gapi::infer<cv::gapi::Generic>(tag, roi, inputs);
- auto age = outputs.at("age_conv3");
- auto gender = outputs.at("prob");
- return cv::GComputation{cv::GIn(in, roi), cv::GOut(age, gender)};
- }
- };
- struct AGNetListGenComp : AGNetGenParams {
- static cv::GComputation create() {
- cv::GMat in;
- cv::GArray<cv::Rect> rois;
- GInferInputs inputs;
- inputs["data"] = in;
- auto outputs = cv::gapi::infer<cv::gapi::Generic>(tag, rois, inputs);
- auto age = outputs.at("age_conv3");
- auto gender = outputs.at("prob");
- return cv::GComputation{cv::GIn(in, rois), cv::GOut(age, gender)};
- }
- };
- struct AGNetList2GenComp : AGNetGenParams {
- static cv::GComputation create() {
- cv::GMat in;
- cv::GArray<cv::Rect> rois;
- GInferListInputs list;
- list["data"] = rois;
- auto outputs = cv::gapi::infer2<cv::gapi::Generic>(tag, in, list);
- auto age = outputs.at("age_conv3");
- auto gender = outputs.at("prob");
- return cv::GComputation{cv::GIn(in, rois), cv::GOut(age, gender)};
- }
- };
- class AGNetOVCompiled {
- public:
- AGNetOVCompiled(ov::CompiledModel &&compiled_model)
- : m_compiled_model(std::move(compiled_model)),
- m_infer_request(m_compiled_model.create_infer_request()) {
- }
- void operator()(const cv::Mat &in_mat,
- const cv::Rect &roi,
- cv::Mat &age_mat,
- cv::Mat &gender_mat) {
- // FIXME: W & H could be extracted from model shape
- // but it's anyway used only for Age Gender model.
- // (Well won't work in case of reshape)
- const int W = 62;
- const int H = 62;
- cv::Mat resized_roi;
- cv::resize(in_mat(roi), resized_roi, cv::Size(W, H));
- (*this)(resized_roi, age_mat, gender_mat);
- }
- void operator()(const cv::Mat &in_mat,
- const std::vector<cv::Rect> &rois,
- std::vector<cv::Mat> &age_mats,
- std::vector<cv::Mat> &gender_mats) {
- for (size_t i = 0; i < rois.size(); ++i) {
- (*this)(in_mat, rois[i], age_mats[i], gender_mats[i]);
- }
- }
- void operator()(const cv::Mat &in_mat,
- cv::Mat &age_mat,
- cv::Mat &gender_mat) {
- auto input_tensor = m_infer_request.get_input_tensor();
- cv::gapi::ov::util::to_ov(in_mat, input_tensor);
- m_infer_request.infer();
- auto age_tensor = m_infer_request.get_tensor("age_conv3");
- age_mat.create(cv::gapi::ov::util::to_ocv(age_tensor.get_shape()),
- cv::gapi::ov::util::to_ocv(age_tensor.get_element_type()));
- cv::gapi::ov::util::to_ocv(age_tensor, age_mat);
- auto gender_tensor = m_infer_request.get_tensor("prob");
- gender_mat.create(cv::gapi::ov::util::to_ocv(gender_tensor.get_shape()),
- cv::gapi::ov::util::to_ocv(gender_tensor.get_element_type()));
- cv::gapi::ov::util::to_ocv(gender_tensor, gender_mat);
- }
- void export_model(const std::string &outpath) {
- std::ofstream file{outpath, std::ios::out | std::ios::binary};
- GAPI_Assert(file.is_open());
- m_compiled_model.export_model(file);
- }
- private:
- ov::CompiledModel m_compiled_model;
- ov::InferRequest m_infer_request;
- };
- struct ImageInputPreproc {
- void operator()(ov::preprocess::PrePostProcessor &ppp) {
- ppp.input().tensor().set_layout(ov::Layout("NHWC"))
- .set_element_type(ov::element::u8)
- .set_shape({1, size.height, size.width, 3});
- ppp.input().model().set_layout(ov::Layout("NCHW"));
- ppp.input().preprocess().resize(::ov::preprocess::ResizeAlgorithm::RESIZE_LINEAR);
- }
- cv::Size size;
- };
- class AGNetOVComp {
- public:
- AGNetOVComp(const std::string &xml_path,
- const std::string &bin_path,
- const std::string &device)
- : m_device(device) {
- m_model = cv::gapi::ov::wrap::getCore()
- .read_model(xml_path, bin_path);
- }
- using PrePostProcessF = std::function<void(ov::preprocess::PrePostProcessor&)>;
- void cfgPrePostProcessing(PrePostProcessF f) {
- ov::preprocess::PrePostProcessor ppp(m_model);
- f(ppp);
- m_model = ppp.build();
- }
- AGNetOVCompiled compile() {
- auto compiled_model = cv::gapi::ov::wrap::getCore()
- .compile_model(m_model, m_device);
- return {std::move(compiled_model)};
- }
- void apply(const cv::Mat &in_mat,
- cv::Mat &age_mat,
- cv::Mat &gender_mat) {
- compile()(in_mat, age_mat, gender_mat);
- }
- private:
- std::string m_device;
- std::shared_ptr<ov::Model> m_model;
- };
- struct BaseAgeGenderOV: public ::testing::Test {
- BaseAgeGenderOV() {
- initDLDTDataPath();
- xml_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.xml", false);
- bin_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.bin", false);
- device = "CPU";
- blob_path = "age-gender-recognition-retail-0013.blob";
- }
- cv::Mat getRandomImage(const cv::Size &sz) {
- cv::Mat image(sz, CV_8UC3);
- cv::randu(image, 0, 255);
- return image;
- }
- cv::Mat getRandomTensor(const std::vector<int> &dims,
- const int depth) {
- cv::Mat tensor(dims, depth);
- cv::randu(tensor, -1, 1);
- return tensor;
- }
- std::string xml_path;
- std::string bin_path;
- std::string blob_path;
- std::string device;
- };
- struct TestAgeGenderOV : public BaseAgeGenderOV {
- cv::Mat ov_age, ov_gender, gapi_age, gapi_gender;
- void validate() {
- normAssert(ov_age, gapi_age, "Test age output" );
- normAssert(ov_gender, gapi_gender, "Test gender output");
- }
- };
- struct TestAgeGenderListOV : public BaseAgeGenderOV {
- std::vector<cv::Mat> ov_age, ov_gender,
- gapi_age, gapi_gender;
- std::vector<cv::Rect> roi_list = {
- cv::Rect(cv::Point{64, 60}, cv::Size{ 96, 96}),
- cv::Rect(cv::Point{50, 32}, cv::Size{128, 160}),
- };
- TestAgeGenderListOV() {
- ov_age.resize(roi_list.size());
- ov_gender.resize(roi_list.size());
- gapi_age.resize(roi_list.size());
- gapi_gender.resize(roi_list.size());
- }
- void validate() {
- ASSERT_EQ(ov_age.size(), ov_gender.size());
- ASSERT_EQ(ov_age.size(), gapi_age.size());
- ASSERT_EQ(ov_gender.size(), gapi_gender.size());
- for (size_t i = 0; i < ov_age.size(); ++i) {
- normAssert(ov_age[i], gapi_age[i], "Test age output");
- normAssert(ov_gender[i], gapi_gender[i], "Test gender output");
- }
- }
- };
- class TestMediaBGR final: public cv::MediaFrame::IAdapter {
- cv::Mat m_mat;
- using Cb = cv::MediaFrame::View::Callback;
- Cb m_cb;
- public:
- explicit TestMediaBGR(cv::Mat m, Cb cb = [](){})
- : m_mat(m), m_cb(cb) {
- }
- cv::GFrameDesc meta() const override {
- return cv::GFrameDesc{cv::MediaFormat::BGR, cv::Size(m_mat.cols, m_mat.rows)};
- }
- cv::MediaFrame::View access(cv::MediaFrame::Access) override {
- cv::MediaFrame::View::Ptrs pp = { m_mat.ptr(), nullptr, nullptr, nullptr };
- cv::MediaFrame::View::Strides ss = { m_mat.step, 0u, 0u, 0u };
- return cv::MediaFrame::View(std::move(pp), std::move(ss), Cb{m_cb});
- }
- };
- struct MediaFrameTestAgeGenderOV: public ::testing::Test {
- MediaFrameTestAgeGenderOV() {
- initDLDTDataPath();
- xml_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.xml", false);
- bin_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.bin", false);
- device = "CPU";
- blob_path = "age-gender-recognition-retail-0013.blob";
- cv::Size sz{62, 62};
- m_in_mat = cv::Mat(sz, CV_8UC3);
- cv::resize(m_in_mat, m_in_mat, sz);
- m_in_y = cv::Mat{sz, CV_8UC1};
- cv::randu(m_in_y, 0, 255);
- m_in_uv = cv::Mat{sz / 2, CV_8UC2};
- cv::randu(m_in_uv, 0, 255);
- }
- cv::Mat m_in_y;
- cv::Mat m_in_uv;
- cv::Mat m_in_mat;
- cv::Mat m_out_ov_age;
- cv::Mat m_out_ov_gender;
- cv::Mat m_out_gapi_age;
- cv::Mat m_out_gapi_gender;
- std::string xml_path;
- std::string bin_path;
- std::string blob_path;
- std::string device;
- std::string image_path;
- using AGInfo = std::tuple<cv::GMat, cv::GMat>;
- G_API_NET(AgeGender, <AGInfo(cv::GMat)>, "typed-age-gender");
- void validate() {
- normAssert(m_out_ov_age, m_out_gapi_age, "0: Test age output");
- normAssert(m_out_ov_gender, m_out_gapi_gender, "0: Test gender output");
- }
- }; // MediaFrameTestAgeGenderOV
- } // anonymous namespace
- TEST_F(MediaFrameTestAgeGenderOV, InferMediaInputBGR)
- {
- // OpenVINO
- AGNetOVComp ref(xml_path, bin_path, device);
- ref.cfgPrePostProcessing([](ov::preprocess::PrePostProcessor &ppp) {
- ppp.input().tensor().set_element_type(ov::element::u8);
- ppp.input().tensor().set_layout("NHWC");
- });
- ref.compile()(m_in_mat, m_out_ov_age, m_out_ov_gender);
- // G-API
- cv::GFrame in;
- cv::GMat age, gender;
- std::tie(age, gender) = cv::gapi::infer<AgeGender>(in);
- cv::GComputation comp{cv::GIn(in), cv::GOut(age, gender)};
- auto frame = MediaFrame::Create<TestMediaBGR>(m_in_mat);
- auto pp = cv::gapi::ov::Params<AgeGender> {
- xml_path, bin_path, device
- }.cfgOutputLayers({ "age_conv3", "prob" });
- comp.apply(cv::gin(frame),
- cv::gout(m_out_gapi_age, m_out_gapi_gender),
- cv::compile_args(cv::gapi::networks(pp)));
- validate();
- }
- TEST_F(MediaFrameTestAgeGenderOV, InferROIGenericMediaInputBGR) {
- // OpenVINO
- cv::Rect roi(cv::Rect(cv::Point{20, 25}, cv::Size{16, 16}));
- auto frame = MediaFrame::Create<TestMediaBGR>(m_in_mat);
- static constexpr const char* tag = "age-gender-generic";
- // OpenVINO
- AGNetOVComp ref(xml_path, bin_path, device);
- ref.cfgPrePostProcessing([](ov::preprocess::PrePostProcessor &ppp) {
- ppp.input().tensor().set_element_type(ov::element::u8);
- ppp.input().tensor().set_layout("NHWC");
- });
- ref.compile()(m_in_mat, roi, m_out_ov_age, m_out_ov_gender);
- // G-API
- cv::GFrame in;
- cv::GOpaque<cv::Rect> rr;
- GInferInputs inputs;
- inputs["data"] = in;
- auto outputs = cv::gapi::infer<cv::gapi::Generic>(tag, rr, inputs);
- auto age = outputs.at("age_conv3");
- auto gender = outputs.at("prob");
- cv::GComputation comp{cv::GIn(in, rr), cv::GOut(age, gender)};
- auto pp = AGNetROIGenComp::params(xml_path, bin_path, device);
- comp.apply(cv::gin(frame, roi), cv::gout(m_out_gapi_age, m_out_gapi_gender),
- cv::compile_args(cv::gapi::networks(pp)));
- validate();
- }
- class TestMediaNV12 final: public cv::MediaFrame::IAdapter {
- cv::Mat m_y;
- cv::Mat m_uv;
- public:
- TestMediaNV12(cv::Mat y, cv::Mat uv) : m_y(y), m_uv(uv) {
- }
- cv::GFrameDesc meta() const override {
- return cv::GFrameDesc{cv::MediaFormat::NV12, cv::Size(m_y.cols, m_y.rows)};
- }
- cv::MediaFrame::View access(cv::MediaFrame::Access) override {
- cv::MediaFrame::View::Ptrs pp = {
- m_y.ptr(), m_uv.ptr(), nullptr, nullptr
- };
- cv::MediaFrame::View::Strides ss = {
- m_y.step, m_uv.step, 0u, 0u
- };
- return cv::MediaFrame::View(std::move(pp), std::move(ss));
- }
- };
- TEST_F(MediaFrameTestAgeGenderOV, TestMediaNV12AgeGenderOV)
- {
- cv::GFrame in;
- cv::GOpaque<cv::Rect> rr;
- GInferInputs inputs;
- inputs["data"] = in;
- static constexpr const char* tag = "age-gender-generic";
- auto outputs = cv::gapi::infer<cv::gapi::Generic>(tag, rr, inputs);
- auto age = outputs.at("age_conv3");
- auto gender = outputs.at("prob");
- cv::GComputation comp{cv::GIn(in, rr), cv::GOut(age, gender)};
- auto frame = MediaFrame::Create<TestMediaNV12>(m_in_y, m_in_uv);
- auto pp = AGNetROIGenComp::params(xml_path, bin_path, device);
- cv::Rect roi(cv::Rect(cv::Point{20, 25}, cv::Size{16, 16}));
- EXPECT_NO_THROW(comp.apply(cv::gin(frame, roi),
- cv::gout(m_out_gapi_age, m_out_gapi_gender),
- cv::compile_args(cv::gapi::networks(pp))));
- }
- // TODO: Make all of tests below parmetrized to avoid code duplication
- TEST_F(TestAgeGenderOV, Infer_Tensor) {
- const auto in_mat = getRandomTensor({1, 3, 62, 62}, CV_32F);
- // OpenVINO
- AGNetOVComp ref(xml_path, bin_path, device);
- ref.apply(in_mat, ov_age, ov_gender);
- // G-API
- auto comp = AGNetTypedComp::create();
- auto pp = AGNetTypedComp::params(xml_path, bin_path, device);
- comp.apply(cv::gin(in_mat), cv::gout(gapi_age, gapi_gender),
- cv::compile_args(cv::gapi::networks(pp)));
- // Assert
- validate();
- }
- TEST_F(TestAgeGenderOV, Infer_Image) {
- const auto in_mat = getRandomImage({300, 300});
- // OpenVINO
- AGNetOVComp ref(xml_path, bin_path, device);
- ref.cfgPrePostProcessing(ImageInputPreproc{in_mat.size()});
- ref.apply(in_mat, ov_age, ov_gender);
- // G-API
- auto comp = AGNetTypedComp::create();
- auto pp = AGNetTypedComp::params(xml_path, bin_path, device);
- comp.apply(cv::gin(in_mat), cv::gout(gapi_age, gapi_gender),
- cv::compile_args(cv::gapi::networks(pp)));
- // Assert
- validate();
- }
- TEST_F(TestAgeGenderOV, InferGeneric_Tensor) {
- const auto in_mat = getRandomTensor({1, 3, 62, 62}, CV_32F);
- // OpenVINO
- AGNetOVComp ref(xml_path, bin_path, device);
- ref.apply(in_mat, ov_age, ov_gender);
- // G-API
- auto comp = AGNetGenComp::create();
- auto pp = AGNetGenComp::params(xml_path, bin_path, device);
- comp.apply(cv::gin(in_mat), cv::gout(gapi_age, gapi_gender),
- cv::compile_args(cv::gapi::networks(pp)));
- // Assert
- validate();
- }
- TEST_F(TestAgeGenderOV, InferGenericImage) {
- const auto in_mat = getRandomImage({300, 300});
- // OpenVINO
- AGNetOVComp ref(xml_path, bin_path, device);
- ref.cfgPrePostProcessing(ImageInputPreproc{in_mat.size()});
- ref.apply(in_mat, ov_age, ov_gender);
- // G-API
- auto comp = AGNetGenComp::create();
- auto pp = AGNetGenComp::params(xml_path, bin_path, device);
- comp.apply(cv::gin(in_mat), cv::gout(gapi_age, gapi_gender),
- cv::compile_args(cv::gapi::networks(pp)));
- // Assert
- validate();
- }
- TEST_F(TestAgeGenderOV, InferGeneric_ImageBlob) {
- const auto in_mat = getRandomImage({300, 300});
- // OpenVINO
- AGNetOVComp ref(xml_path, bin_path, device);
- ref.cfgPrePostProcessing(ImageInputPreproc{in_mat.size()});
- auto cc_ref = ref.compile();
- // NB: Output blob will contain preprocessing inside.
- cc_ref.export_model(blob_path);
- cc_ref(in_mat, ov_age, ov_gender);
- // G-API
- auto comp = AGNetGenComp::create();
- auto pp = AGNetGenComp::params(blob_path, device);
- comp.apply(cv::gin(in_mat), cv::gout(gapi_age, gapi_gender),
- cv::compile_args(cv::gapi::networks(pp)));
- // Assert
- validate();
- }
- TEST_F(TestAgeGenderOV, InferGeneric_TensorBlob) {
- const auto in_mat = getRandomTensor({1, 3, 62, 62}, CV_32F);
- // OpenVINO
- AGNetOVComp ref(xml_path, bin_path, device);
- auto cc_ref = ref.compile();
- cc_ref.export_model(blob_path);
- cc_ref(in_mat, ov_age, ov_gender);
- // G-API
- auto comp = AGNetGenComp::create();
- auto pp = AGNetGenComp::params(blob_path, device);
- comp.apply(cv::gin(in_mat), cv::gout(gapi_age, gapi_gender),
- cv::compile_args(cv::gapi::networks(pp)));
- // Assert
- validate();
- }
- TEST_F(TestAgeGenderOV, InferGeneric_BothOutputsFP16) {
- const auto in_mat = getRandomTensor({1, 3, 62, 62}, CV_32F);
- // OpenVINO
- AGNetOVComp ref(xml_path, bin_path, device);
- ref.cfgPrePostProcessing([](ov::preprocess::PrePostProcessor &ppp){
- ppp.output(0).tensor().set_element_type(ov::element::f16);
- ppp.output(1).tensor().set_element_type(ov::element::f16);
- });
- ref.apply(in_mat, ov_age, ov_gender);
- // G-API
- auto comp = AGNetGenComp::create();
- auto pp = AGNetGenComp::params(xml_path, bin_path, device);
- pp.cfgOutputTensorPrecision(CV_16F);
- comp.apply(cv::gin(in_mat), cv::gout(gapi_age, gapi_gender),
- cv::compile_args(cv::gapi::networks(pp)));
- // Assert
- validate();
- }
- TEST_F(TestAgeGenderOV, InferGeneric_OneOutputFP16) {
- const auto in_mat = getRandomTensor({1, 3, 62, 62}, CV_32F);
- // OpenVINO
- const std::string fp16_output_name = "prob";
- AGNetOVComp ref(xml_path, bin_path, device);
- ref.cfgPrePostProcessing([&](ov::preprocess::PrePostProcessor &ppp){
- ppp.output(fp16_output_name).tensor().set_element_type(ov::element::f16);
- });
- ref.apply(in_mat, ov_age, ov_gender);
- // G-API
- auto comp = AGNetGenComp::create();
- auto pp = AGNetGenComp::params(xml_path, bin_path, device);
- pp.cfgOutputTensorPrecision({{fp16_output_name, CV_16F}});
- comp.apply(cv::gin(in_mat), cv::gout(gapi_age, gapi_gender),
- cv::compile_args(cv::gapi::networks(pp)));
- // Assert
- validate();
- }
- TEST_F(TestAgeGenderOV, InferGeneric_ThrowCfgOutputPrecForBlob) {
- // OpenVINO (Just for blob compilation)
- AGNetOVComp ref(xml_path, bin_path, device);
- auto cc_ref = ref.compile();
- cc_ref.export_model(blob_path);
- // G-API
- auto comp = AGNetGenComp::create();
- auto pp = AGNetGenComp::params(blob_path, device);
- EXPECT_ANY_THROW(pp.cfgOutputTensorPrecision(CV_16F));
- }
- TEST_F(TestAgeGenderOV, InferGeneric_ThrowInvalidConfigIR) {
- // G-API
- auto comp = AGNetGenComp::create();
- auto pp = AGNetGenComp::params(xml_path, bin_path, device);
- pp.cfgPluginConfig({{"some_key", "some_value"}});
- EXPECT_ANY_THROW(comp.compile(cv::GMatDesc{CV_8U,3,cv::Size{320, 240}},
- cv::compile_args(cv::gapi::networks(pp))));
- }
- TEST_F(TestAgeGenderOV, InferGeneric_ThrowInvalidConfigBlob) {
- // OpenVINO (Just for blob compilation)
- AGNetOVComp ref(xml_path, bin_path, device);
- auto cc_ref = ref.compile();
- cc_ref.export_model(blob_path);
- // G-API
- auto comp = AGNetGenComp::create();
- auto pp = AGNetGenComp::params(blob_path, device);
- pp.cfgPluginConfig({{"some_key", "some_value"}});
- EXPECT_ANY_THROW(comp.compile(cv::GMatDesc{CV_8U,3,cv::Size{320, 240}},
- cv::compile_args(cv::gapi::networks(pp))));
- }
- TEST_F(TestAgeGenderOV, Infer_ThrowInvalidImageLayout) {
- const auto in_mat = getRandomImage({300, 300});
- auto comp = AGNetTypedComp::create();
- auto pp = AGNetTypedComp::params(xml_path, bin_path, device);
- pp.cfgInputTensorLayout("NCHW");
- EXPECT_ANY_THROW(comp.compile(cv::descr_of(in_mat),
- cv::compile_args(cv::gapi::networks(pp))));
- }
- TEST_F(TestAgeGenderOV, Infer_TensorWithPreproc) {
- const auto in_mat = getRandomTensor({1, 240, 320, 3}, CV_32F);
- // OpenVINO
- AGNetOVComp ref(xml_path, bin_path, device);
- ref.cfgPrePostProcessing([](ov::preprocess::PrePostProcessor &ppp) {
- auto& input = ppp.input();
- input.tensor().set_spatial_static_shape(240, 320)
- .set_layout("NHWC");
- input.preprocess().resize(ov::preprocess::ResizeAlgorithm::RESIZE_LINEAR);
- });
- ref.apply(in_mat, ov_age, ov_gender);
- // G-API
- auto comp = AGNetTypedComp::create();
- auto pp = AGNetTypedComp::params(xml_path, bin_path, device);
- pp.cfgResize(cv::INTER_LINEAR)
- .cfgInputTensorLayout("NHWC");
- comp.apply(cv::gin(in_mat), cv::gout(gapi_age, gapi_gender),
- cv::compile_args(cv::gapi::networks(pp)));
- // Assert
- validate();
- }
- TEST_F(TestAgeGenderOV, InferROIGeneric_Image) {
- const auto in_mat = getRandomImage({300, 300});
- cv::Rect roi(cv::Rect(cv::Point{64, 60}, cv::Size{96, 96}));
- // OpenVINO
- AGNetOVComp ref(xml_path, bin_path, device);
- ref.cfgPrePostProcessing([](ov::preprocess::PrePostProcessor &ppp) {
- ppp.input().tensor().set_element_type(ov::element::u8);
- ppp.input().tensor().set_layout("NHWC");
- });
- ref.compile()(in_mat, roi, ov_age, ov_gender);
- // G-API
- auto comp = AGNetROIGenComp::create();
- auto pp = AGNetROIGenComp::params(xml_path, bin_path, device);
- comp.apply(cv::gin(in_mat, roi), cv::gout(gapi_age, gapi_gender),
- cv::compile_args(cv::gapi::networks(pp)));
- // Assert
- validate();
- }
- TEST_F(TestAgeGenderOV, InferROIGeneric_ThrowIncorrectLayout) {
- const auto in_mat = getRandomImage({300, 300});
- cv::Rect roi(cv::Rect(cv::Point{64, 60}, cv::Size{96, 96}));
- // G-API
- auto comp = AGNetROIGenComp::create();
- auto pp = AGNetROIGenComp::params(xml_path, bin_path, device);
- pp.cfgInputTensorLayout("NCHW");
- EXPECT_ANY_THROW(comp.apply(cv::gin(in_mat, roi), cv::gout(gapi_age, gapi_gender),
- cv::compile_args(cv::gapi::networks(pp))));
- }
- TEST_F(TestAgeGenderOV, InferROIGeneric_ThrowTensorInput) {
- const auto in_mat = getRandomTensor({1, 3, 62, 62}, CV_32F);
- cv::Rect roi(cv::Rect(cv::Point{64, 60}, cv::Size{96, 96}));
- // G-API
- auto comp = AGNetROIGenComp::create();
- auto pp = AGNetROIGenComp::params(xml_path, bin_path, device);
- EXPECT_ANY_THROW(comp.apply(cv::gin(in_mat, roi), cv::gout(gapi_age, gapi_gender),
- cv::compile_args(cv::gapi::networks(pp))));
- }
- TEST_F(TestAgeGenderOV, InferROIGeneric_ThrowExplicitResize) {
- const auto in_mat = getRandomImage({300, 300});
- cv::Rect roi(cv::Rect(cv::Point{64, 60}, cv::Size{96, 96}));
- // G-API
- auto comp = AGNetROIGenComp::create();
- auto pp = AGNetROIGenComp::params(xml_path, bin_path, device);
- pp.cfgResize(cv::INTER_LINEAR);
- EXPECT_ANY_THROW(comp.apply(cv::gin(in_mat, roi), cv::gout(gapi_age, gapi_gender),
- cv::compile_args(cv::gapi::networks(pp))));
- }
- TEST_F(TestAgeGenderListOV, InferListGeneric_Image) {
- const auto in_mat = getRandomImage({300, 300});
- // OpenVINO
- AGNetOVComp ref(xml_path, bin_path, device);
- ref.cfgPrePostProcessing([](ov::preprocess::PrePostProcessor &ppp) {
- ppp.input().tensor().set_element_type(ov::element::u8);
- ppp.input().tensor().set_layout("NHWC");
- });
- ref.compile()(in_mat, roi_list, ov_age, ov_gender);
- // G-API
- auto comp = AGNetListGenComp::create();
- auto pp = AGNetListGenComp::params(xml_path, bin_path, device);
- comp.apply(cv::gin(in_mat, roi_list), cv::gout(gapi_age, gapi_gender),
- cv::compile_args(cv::gapi::networks(pp)));
- // Assert
- validate();
- }
- TEST_F(TestAgeGenderListOV, InferList2Generic_Image) {
- const auto in_mat = getRandomImage({300, 300});
- // OpenVINO
- AGNetOVComp ref(xml_path, bin_path, device);
- ref.cfgPrePostProcessing([](ov::preprocess::PrePostProcessor &ppp) {
- ppp.input().tensor().set_element_type(ov::element::u8);
- ppp.input().tensor().set_layout("NHWC");
- });
- ref.compile()(in_mat, roi_list, ov_age, ov_gender);
- // G-API
- auto comp = AGNetList2GenComp::create();
- auto pp = AGNetList2GenComp::params(xml_path, bin_path, device);
- comp.apply(cv::gin(in_mat, roi_list), cv::gout(gapi_age, gapi_gender),
- cv::compile_args(cv::gapi::networks(pp)));
- // Assert
- validate();
- }
- static ov::element::Type toOV(int depth) {
- switch (depth) {
- case CV_8U: return ov::element::u8;
- case CV_32S: return ov::element::i32;
- case CV_32F: return ov::element::f32;
- case CV_16F: return ov::element::f16;
- default: GAPI_Error("OV Backend: Unsupported data type");
- }
- return ov::element::dynamic;
- }
- struct TestMeanScaleOV : public ::testing::TestWithParam<int>{
- G_API_NET(IdentityNet, <cv::GMat(cv::GMat)>, "test-identity-net");
- static cv::GComputation create() {
- cv::GMat in;
- cv::GMat out;
- out = cv::gapi::infer<IdentityNet>(in);
- return cv::GComputation{cv::GIn(in), cv::GOut(out)};
- }
- using Params = cv::gapi::ov::Params<IdentityNet>;
- static Params params(const std::string &xml_path,
- const std::string &bin_path,
- const std::string &device) {
- return Params {
- xml_path, bin_path, device
- }.cfgInputModelLayout("NHWC")
- .cfgOutputLayers({ "output" });
- }
- TestMeanScaleOV() {
- initDLDTDataPath();
- m_model_path = findDataFile("gapi/ov/identity_net_100x100.xml");
- m_weights_path = findDataFile("gapi/ov/identity_net_100x100.bin");
- m_device_id = "CPU";
- m_ov_model = cv::gapi::ov::wrap::getCore()
- .read_model(m_model_path, m_weights_path);
- auto input_depth = GetParam();
- auto input = cv::imread(findDataFile("gapi/gapi_logo.jpg"));
- input.convertTo(m_in_mat, input_depth);
- }
- void addPreprocToOV(
- std::function<void(ov::preprocess::PrePostProcessor&)> f) {
- auto input_depth = GetParam();
- ov::preprocess::PrePostProcessor ppp(m_ov_model);
- ppp.input().tensor().set_layout(ov::Layout("NHWC"))
- .set_element_type(toOV(input_depth))
- .set_shape({ 1, 100, 100, 3 });
- ppp.input().model().set_layout(ov::Layout("NHWC"));
- f(ppp);
- m_ov_model = ppp.build();
- }
- void runOV() {
- auto compiled_model = cv::gapi::ov::wrap::getCore()
- .compile_model(m_ov_model, m_device_id);
- auto infer_request = compiled_model.create_infer_request();
- auto input_tensor = infer_request.get_input_tensor();
- cv::gapi::ov::util::to_ov(m_in_mat, input_tensor);
- infer_request.infer();
- auto out_tensor = infer_request.get_tensor("output");
- m_out_mat_ov.create(cv::gapi::ov::util::to_ocv(out_tensor.get_shape()),
- cv::gapi::ov::util::to_ocv(out_tensor.get_element_type()));
- cv::gapi::ov::util::to_ocv(out_tensor, m_out_mat_ov);
- }
- std::string m_model_path;
- std::string m_weights_path;
- std::string m_device_id;
- std::shared_ptr<ov::Model> m_ov_model;
- cv::Mat m_in_mat;
- cv::Mat m_out_mat_gapi;
- cv::Mat m_out_mat_ov;
- };
- TEST_P(TestMeanScaleOV, Mean)
- {
- int input_depth = GetParam();
- std::vector<float> mean_values{ 220.1779, 218.9857, 217.8986 };
- // Run OV reference pipeline:
- {
- addPreprocToOV([&](ov::preprocess::PrePostProcessor& ppp) {
- if (input_depth == CV_8U || input_depth == CV_32S) {
- ppp.input().preprocess().convert_element_type(ov::element::f32);
- }
- ppp.input().preprocess().mean(mean_values);
- });
- runOV();
- }
- // Run G-API
- GComputation comp = create();
- auto pp = params(m_model_path, m_weights_path, m_device_id);
- pp.cfgMean(mean_values);
- comp.apply(cv::gin(m_in_mat), cv::gout(m_out_mat_gapi),
- cv::compile_args(cv::gapi::networks(pp)));
- // Validate OV results against G-API ones:
- normAssert(m_out_mat_ov, m_out_mat_gapi, "Test output");
- }
- TEST_P(TestMeanScaleOV, Scale)
- {
- int input_depth = GetParam();
- std::vector<float> scale_values{ 2., 2., 2. };
- // Run OV reference pipeline:
- {
- addPreprocToOV([&](ov::preprocess::PrePostProcessor& ppp) {
- if (input_depth == CV_8U || input_depth == CV_32S) {
- ppp.input().preprocess().convert_element_type(ov::element::f32);
- }
- ppp.input().preprocess().scale(scale_values);
- });
- runOV();
- }
- // Run G-API
- GComputation comp = create();
- auto pp = params(m_model_path, m_weights_path, m_device_id);
- pp.cfgScale(scale_values);
- comp.apply(cv::gin(m_in_mat), cv::gout(m_out_mat_gapi),
- cv::compile_args(cv::gapi::networks(pp)));
- // Validate OV results against G-API ones:
- normAssert(m_out_mat_ov, m_out_mat_gapi, "Test output");
- }
- TEST_P(TestMeanScaleOV, MeanAndScale)
- {
- int input_depth = GetParam();
- std::vector<float> mean_values{ 220.1779, 218.9857, 217.8986 };
- std::vector<float> scale_values{ 2., 2., 2. };
- // Run OV reference pipeline:
- {
- addPreprocToOV([&](ov::preprocess::PrePostProcessor& ppp) {
- if (input_depth == CV_8U || input_depth == CV_32S) {
- ppp.input().preprocess().convert_element_type(ov::element::f32);
- }
- ppp.input().preprocess().mean(mean_values);
- ppp.input().preprocess().scale(scale_values);
- });
- runOV();
- }
- // Run G-API
- GComputation comp = create();
- auto pp = params(m_model_path, m_weights_path, m_device_id);
- pp.cfgMean(mean_values);
- pp.cfgScale(scale_values);
- comp.apply(cv::gin(m_in_mat), cv::gout(m_out_mat_gapi),
- cv::compile_args(cv::gapi::networks(pp)));
- // Validate OV results against G-API ones:
- normAssert(m_out_mat_ov, m_out_mat_gapi, "Test output");
- }
- INSTANTIATE_TEST_CASE_P(Instantiation, TestMeanScaleOV,
- Values(CV_8U, CV_32S, CV_16F, CV_32F));
- } // namespace opencv_test
- #endif // HAVE_INF_ENGINE && INF_ENGINE_RELEASE >= 2022010000
|