mirror of
https://github.com/opencv/opencv.git
synced 2025-08-06 14:36:36 +08:00
Merge pull request #15312 from smirnov-alexey:gapi_fluid_garray
* Support GArray as input in fluid kernels * Create tests on GArray input in fluid * Some fixes to fully support GArray * Refactor code and change the kernel according to review * Add histogram calculation as a G-API kernel Add assert that input GArgs in fluid contain at least one GMat
This commit is contained in:
parent
e98e58c65a
commit
8a7e74673e
@ -154,6 +154,15 @@ template<> struct fluid_get_in<cv::GScalar>
|
||||
}
|
||||
#endif // !defined(GAPI_STANDALONE)
|
||||
};
|
||||
|
||||
template<typename U> struct fluid_get_in<cv::GArray<U>>
|
||||
{
|
||||
static const std::vector<U>& get(const cv::GArgs &in_args, int idx)
|
||||
{
|
||||
return in_args.at(idx).unsafe_get<cv::detail::VectorRef>().rref<U>();
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> struct fluid_get_in
|
||||
{
|
||||
static const T& get(const cv::GArgs &in_args, int idx)
|
||||
@ -250,6 +259,7 @@ template<typename Impl, typename... Ins, typename... Outs, bool UseScratch>
|
||||
struct FluidCallHelper<Impl, std::tuple<Ins...>, std::tuple<Outs...>, UseScratch>
|
||||
{
|
||||
static_assert(all_satisfy<is_gmat_type, Outs...>::value, "return type must be GMat");
|
||||
static_assert(contains<GMat, Ins...>::value, "input must contain at least one GMat");
|
||||
|
||||
// Execution dispatcher ////////////////////////////////////////////////////
|
||||
template<int... IIs, int... OIs>
|
||||
|
@ -1229,6 +1229,7 @@ void cv::gimpl::GFluidExecutable::bindInArg(const cv::gimpl::RcDesc &rc, const G
|
||||
{
|
||||
case GShape::GMAT: m_buffers[m_id_map.at(rc.id)].priv().bindTo(util::get<cv::gapi::own::Mat>(arg), true); break;
|
||||
case GShape::GSCALAR: m_res.slot<cv::gapi::own::Scalar>()[rc.id] = util::get<cv::gapi::own::Scalar>(arg); break;
|
||||
case GShape::GARRAY: m_res.slot<cv::detail::VectorRef>()[rc.id] = util::get<cv::detail::VectorRef>(arg); break;
|
||||
default: util::throw_error(std::logic_error("Unsupported GShape type"));
|
||||
}
|
||||
}
|
||||
@ -1254,7 +1255,8 @@ void cv::gimpl::GFluidExecutable::bindOutArg(const cv::gimpl::RcDesc &rc, const
|
||||
void cv::gimpl::GFluidExecutable::packArg(cv::GArg &in_arg, const cv::GArg &op_arg)
|
||||
{
|
||||
GAPI_Assert(op_arg.kind != cv::detail::ArgKind::GMAT
|
||||
&& op_arg.kind != cv::detail::ArgKind::GSCALAR);
|
||||
&& op_arg.kind != cv::detail::ArgKind::GSCALAR
|
||||
&& op_arg.kind != cv::detail::ArgKind::GARRAY);
|
||||
|
||||
if (op_arg.kind == cv::detail::ArgKind::GOBJREF)
|
||||
{
|
||||
@ -1263,6 +1265,10 @@ void cv::gimpl::GFluidExecutable::packArg(cv::GArg &in_arg, const cv::GArg &op_a
|
||||
{
|
||||
in_arg = GArg(m_res.slot<cv::gapi::own::Scalar>()[ref.id]);
|
||||
}
|
||||
else if (ref.shape == GShape::GARRAY)
|
||||
{
|
||||
in_arg = GArg(m_res.slot<cv::detail::VectorRef>()[ref.id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,7 @@ class GFluidExecutable final: public GIslandExecutable
|
||||
|
||||
std::vector<FluidAgent*> m_script;
|
||||
|
||||
using Magazine = detail::magazine<cv::gapi::own::Scalar>;
|
||||
using Magazine = detail::magazine<cv::gapi::own::Scalar, cv::detail::VectorRef>;
|
||||
Magazine m_res;
|
||||
|
||||
std::size_t m_num_int_buffers; // internal buffers counter (m_buffers - num_scratch)
|
||||
|
@ -244,6 +244,26 @@ TEST(Fluid, Sum_2_Mats_And_Scalar)
|
||||
EXPECT_EQ(0, cv::countNonZero(out_mat != ref_mat));
|
||||
}
|
||||
|
||||
TEST(Fluid, EqualizeHist)
|
||||
{
|
||||
cv::GMat in, out;
|
||||
cv::GComputation c(cv::GIn(in), cv::GOut(TEqualizeHist::on(in, TCalcHist::on(in))));
|
||||
|
||||
cv::Mat in_mat(320, 480, CV_8UC1),
|
||||
out_mat(320, 480, CV_8UC1),
|
||||
ref_mat(320, 480, CV_8UC1);
|
||||
|
||||
cv::randu(in_mat, 200, 240);
|
||||
|
||||
auto cc = c.compile(cv::descr_of(in_mat), cv::compile_args(fluidTestPackage));
|
||||
|
||||
cc(cv::gin(in_mat), cv::gout(out_mat));
|
||||
|
||||
cv::equalizeHist(in_mat, ref_mat);
|
||||
|
||||
EXPECT_EQ(0, cv::countNonZero(out_mat != ref_mat));
|
||||
}
|
||||
|
||||
TEST(Fluid, Split3)
|
||||
{
|
||||
cv::GMat bgr;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include "gapi_fluid_test_kernels.hpp"
|
||||
#include <opencv2/gapi/core.hpp>
|
||||
#include <opencv2/gapi/own/saturate.hpp>
|
||||
@ -448,6 +449,56 @@ GAPI_FLUID_KERNEL(FSum2MatsAndScalar, TSum2MatsAndScalar, false)
|
||||
}
|
||||
};
|
||||
|
||||
GAPI_FLUID_KERNEL(FEqualizeHist, TEqualizeHist, false)
|
||||
{
|
||||
static const int Window = 1;
|
||||
static const int LPI = 2;
|
||||
|
||||
static void run(const cv::gapi::fluid::View &mat,
|
||||
const std::vector<int> &arr,
|
||||
cv::gapi::fluid::Buffer &out)
|
||||
{
|
||||
for (int l = 0, lpi = out.lpi(); l < lpi; l++)
|
||||
{
|
||||
const uint8_t* in_row = mat.InLine <uint8_t>(l);
|
||||
uint8_t* out_row = out.OutLine<uint8_t>(l);
|
||||
|
||||
for (int i = 0, w = mat.length(); i < w; i++)
|
||||
{
|
||||
out_row[i] = static_cast<uint8_t>(arr[in_row[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
GAPI_OCV_KERNEL(OCVCalcHist, TCalcHist)
|
||||
{
|
||||
static void run(const cv::Mat& in, std::vector<int>& out)
|
||||
{
|
||||
out = std::vector<int>(256, 0);
|
||||
|
||||
// Calculate normalized accumulated integral transformation array for gapi
|
||||
for(int i = 0; i < in.rows; ++i)
|
||||
for(int j = 0; j < in.cols; ++j)
|
||||
++out[in.at<uint8_t>(i, j)];
|
||||
|
||||
for(unsigned int i = 1; i < out.size(); ++i)
|
||||
out[i] += out[i-1];
|
||||
|
||||
int size = in.size().width * in.size().height;
|
||||
int min = size;
|
||||
for(unsigned int i = 0; i < out.size(); ++i)
|
||||
if(out[i] != 0 && out[i] < min)
|
||||
min = out[i];
|
||||
|
||||
for(auto & el : out)
|
||||
{
|
||||
// General histogram equalization formula
|
||||
el = cvRound(((float)(el - min) / (float)(size - min))*255);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const int ITUR_BT_601_CY = 1220542;
|
||||
static const int ITUR_BT_601_CUB = 2116026;
|
||||
static const int ITUR_BT_601_CUG = -409993;
|
||||
@ -569,6 +620,8 @@ cv::gapi::GKernelPackage fluidTestPackage = cv::gapi::kernels
|
||||
,FSum2MatsAndScalar
|
||||
,FTestSplit3
|
||||
,FTestSplit3_4lpi
|
||||
,FEqualizeHist
|
||||
,OCVCalcHist
|
||||
>();
|
||||
} // namespace gapi_test_kernels
|
||||
} // namespace cv
|
||||
|
@ -15,6 +15,7 @@ namespace cv
|
||||
namespace gapi_test_kernels
|
||||
{
|
||||
using cv::gapi::core::GMat3;
|
||||
using GMat2 = std::tuple<GMat, GMat>;
|
||||
|
||||
G_TYPED_KERNEL(TAddSimple, <GMat(GMat, GMat)>, "test.fluid.add_simple") {
|
||||
static cv::GMatDesc outMeta(cv::GMatDesc a, cv::GMatDesc) {
|
||||
@ -112,6 +113,20 @@ G_TYPED_KERNEL_M(TSplit3_4lpi, <GMat3(GMat)>, "test.fluid.split3_4lpi") {
|
||||
}
|
||||
};
|
||||
|
||||
G_TYPED_KERNEL(TEqualizeHist, <GMat(GMat, GArray<int>)>, "test.fluid.equalize_hist")
|
||||
{
|
||||
static GMatDesc outMeta(GMatDesc in, const cv::GArrayDesc&) {
|
||||
return in;
|
||||
}
|
||||
};
|
||||
|
||||
G_TYPED_KERNEL(TCalcHist, <GArray<int>(GMat)>, "test.ocv.calc_hist")
|
||||
{
|
||||
static GArrayDesc outMeta(GMatDesc) {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
GMat merge3_4lpi(const GMat& src1, const GMat& src2, const GMat& src3);
|
||||
std::tuple<GMat, GMat, GMat> split3_4lpi(const GMat& src);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user