Merge pull request #16803 from TolyaTalamanov:at/yuv-to-gray

* Implement NV12toGray

* Snapshot

* Implement NV12toGray as compound kernel

* Update gapi_imgproc_tests_inl.hpp

* Remove YUV2Gray from public API
This commit is contained in:
Anatoliy Talamanov 2020-03-24 13:51:18 +03:00 committed by GitHub
parent ea34b2fefb
commit 4d3d6230c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 135 additions and 5 deletions

View File

@ -222,6 +222,21 @@ namespace imgproc {
} }
}; };
G_TYPED_KERNEL(GNV12toGray, <GMat(GMat,GMat)>, "org.opencv.colorconvert.imgproc.nv12togray") {
static GMatDesc outMeta(GMatDesc inY, GMatDesc inUV) {
GAPI_Assert(inY.depth == CV_8U);
GAPI_Assert(inUV.depth == CV_8U);
GAPI_Assert(inY.chan == 1);
GAPI_Assert(inY.planar == false);
GAPI_Assert(inUV.chan == 2);
GAPI_Assert(inUV.planar == false);
GAPI_Assert(inY.size.width == 2 * inUV.size.width);
GAPI_Assert(inY.size.height == 2 * inUV.size.height);
return inY.withType(CV_8U, 1);
}
};
G_TYPED_KERNEL(GNV12toBGRp, <GMatP(GMat,GMat)>, "org.opencv.colorconvert.imgproc.nv12tobgrp") { G_TYPED_KERNEL(GNV12toBGRp, <GMatP(GMat,GMat)>, "org.opencv.colorconvert.imgproc.nv12tobgrp") {
static GMatDesc outMeta(GMatDesc inY, GMatDesc inUV) { static GMatDesc outMeta(GMatDesc inY, GMatDesc inUV) {
GAPI_Assert(inY.depth == CV_8U); GAPI_Assert(inY.depth == CV_8U);
@ -819,6 +834,21 @@ Output image must be 8-bit unsigned 3-channel image @ref CV_8UC3.
*/ */
GAPI_EXPORTS GMat NV12toRGB(const GMat& src_y, const GMat& src_uv); GAPI_EXPORTS GMat NV12toRGB(const GMat& src_y, const GMat& src_uv);
/** @brief Converts an image from NV12 (YUV420p) color space to gray-scaled.
The function converts an input image from NV12 color space to gray-scaled.
The conventional ranges for Y, U, and V channel values are 0 to 255.
Output image must be 8-bit unsigned 1-channel image @ref CV_8UC1.
@note Function textual ID is "org.opencv.imgproc.colorconvert.nv12togray"
@param src_y input image: 8-bit unsigned 1-channel image @ref CV_8UC1.
@param src_uv input image: 8-bit unsigned 2-channel image @ref CV_8UC2.
@sa YUV2RGB, NV12toBGR
*/
GAPI_EXPORTS GMat NV12toGray(const GMat& src_y, const GMat& src_uv);
/** @brief Converts an image from NV12 (YUV420p) color space to BGR. /** @brief Converts an image from NV12 (YUV420p) color space to BGR.
The function converts an input image from NV12 color space to RGB. The function converts an input image from NV12 color space to RGB.
The conventional ranges for Y, U, and V channel values are 0 to 255. The conventional ranges for Y, U, and V channel values are 0 to 255.

View File

@ -157,18 +157,26 @@ GMat RGB2Lab(const GMat& src)
return imgproc::GRGB2Lab::on(src); return imgproc::GRGB2Lab::on(src);
} }
GMat BayerGR2RGB(const GMat& src_gr) { GMat BayerGR2RGB(const GMat& src_gr)
{
return imgproc::GBayerGR2RGB::on(src_gr); return imgproc::GBayerGR2RGB::on(src_gr);
} }
GMat RGB2HSV(const GMat& src) { GMat RGB2HSV(const GMat& src)
{
return imgproc::GRGB2HSV::on(src); return imgproc::GRGB2HSV::on(src);
} }
GMat RGB2YUV422(const GMat& src) { GMat RGB2YUV422(const GMat& src)
{
return imgproc::GRGB2YUV422::on(src); return imgproc::GRGB2YUV422::on(src);
} }
GMat NV12toGray(const GMat &y, const GMat &uv)
{
return imgproc::GNV12toGray::on(y, uv);
}
GMatP NV12toRGBp(const GMat &y, const GMat &uv) GMatP NV12toRGBp(const GMat &y, const GMat &uv)
{ {
return imgproc::GNV12toRGBp::on(y, uv); return imgproc::GNV12toRGBp::on(y, uv);

View File

@ -10,9 +10,11 @@
#include <opencv2/gapi/imgproc.hpp> #include <opencv2/gapi/imgproc.hpp>
#include <opencv2/gapi/cpu/imgproc.hpp> #include <opencv2/gapi/cpu/imgproc.hpp>
#include <opencv2/gapi/cpu/gcpukernel.hpp> #include <opencv2/gapi/cpu/gcpukernel.hpp>
#include <opencv2/gapi/gcompoundkernel.hpp>
#include "backends/fluid/gfluidimgproc_func.hpp" #include "backends/fluid/gfluidimgproc_func.hpp"
namespace { namespace {
cv::Mat add_border(const cv::Mat& in, const int ksize, const int borderType, const cv::Scalar& bordVal){ cv::Mat add_border(const cv::Mat& in, const int ksize, const int borderType, const cv::Scalar& bordVal){
if( borderType == cv::BORDER_CONSTANT ) if( borderType == cv::BORDER_CONSTANT )
@ -335,6 +337,57 @@ GAPI_OCV_KERNEL(GCPUNV12toRGBp, cv::gapi::imgproc::GNV12toRGBp)
} }
}; };
G_TYPED_KERNEL(GYUV2Gray, <cv::GMat(cv::GMat)>, "yuvtogray") {
static cv::GMatDesc outMeta(cv::GMatDesc in) {
GAPI_Assert(in.depth == CV_8U);
GAPI_Assert(in.planar == false);
GAPI_Assert(in.size.width % 2 == 0);
GAPI_Assert(in.size.height % 3 == 0);
/* YUV format for this kernel:
* Y Y Y Y Y Y Y Y
* Y Y Y Y Y Y Y Y
* Y Y Y Y Y Y Y Y
* Y Y Y Y Y Y Y Y
* U V U V U V U V
* U V U V U V U V
*/
return {CV_8U, 1, cv::gapi::own::Size{in.size.width, in.size.height - (in.size.height / 3)}, false};
}
};
GAPI_OCV_KERNEL(GCPUYUV2Gray, GYUV2Gray)
{
static void run(const cv::Mat& in, cv::Mat& out)
{
cv::cvtColor(in, out, cv::COLOR_YUV2GRAY_NV12);
}
};
G_TYPED_KERNEL(GConcatYUVPlanes, <cv::GMat(cv::GMat, cv::GMat)>, "concatyuvplanes") {
static cv::GMatDesc outMeta(cv::GMatDesc y, cv::GMatDesc uv) {
return {CV_8U, 1, cv::gapi::own::Size{y.size.width, y.size.height + uv.size.height}, false};
}
};
GAPI_OCV_KERNEL(GCPUConcatYUVPlanes, GConcatYUVPlanes)
{
static void run(const cv::Mat& in_y, const cv::Mat& in_uv, cv::Mat& out)
{
cv::Mat uv_planar(in_uv.rows, in_uv.cols * 2, CV_8UC1, in_uv.data);
cv::vconcat(in_y, uv_planar, out);
}
};
GAPI_COMPOUND_KERNEL(GCPUNV12toGray, cv::gapi::imgproc::GNV12toGray)
{
static cv::GMat expand(cv::GMat y, cv::GMat uv)
{
return GYUV2Gray::on(GConcatYUVPlanes::on(y, uv));
}
};
GAPI_OCV_KERNEL(GCPUNV12toBGRp, cv::gapi::imgproc::GNV12toBGRp) GAPI_OCV_KERNEL(GCPUNV12toBGRp, cv::gapi::imgproc::GNV12toBGRp)
{ {
static void run(const cv::Mat& inY, const cv::Mat& inUV, cv::Mat& out) static void run(const cv::Mat& inY, const cv::Mat& inUV, cv::Mat& out)
@ -345,7 +398,6 @@ GAPI_OCV_KERNEL(GCPUNV12toBGRp, cv::gapi::imgproc::GNV12toBGRp)
} }
}; };
cv::gapi::GKernelPackage cv::gapi::imgproc::cpu::kernels() cv::gapi::GKernelPackage cv::gapi::imgproc::cpu::kernels()
{ {
static auto pkg = cv::gapi::kernels static auto pkg = cv::gapi::kernels
@ -376,8 +428,11 @@ cv::gapi::GKernelPackage cv::gapi::imgproc::cpu::kernels()
, GCPUBayerGR2RGB , GCPUBayerGR2RGB
, GCPURGB2HSV , GCPURGB2HSV
, GCPURGB2YUV422 , GCPURGB2YUV422
, GCPUYUV2Gray
, GCPUNV12toRGBp , GCPUNV12toRGBp
, GCPUNV12toBGRp , GCPUNV12toBGRp
, GCPUNV12toGray
, GCPUConcatYUVPlanes
>(); >();
return pkg; return pkg;
} }

View File

@ -56,10 +56,12 @@ GAPI_TEST_FIXTURE(RGB2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cm
GAPI_TEST_FIXTURE(BGR2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) GAPI_TEST_FIXTURE(BGR2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(RGB2YUVTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) GAPI_TEST_FIXTURE(RGB2YUVTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(YUV2RGBTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) GAPI_TEST_FIXTURE(YUV2RGBTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(YUV2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(NV12toRGBTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) GAPI_TEST_FIXTURE(NV12toRGBTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(NV12toBGRpTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) GAPI_TEST_FIXTURE(NV12toBGRpTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(NV12toRGBpTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) GAPI_TEST_FIXTURE(NV12toRGBpTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(NV12toBGRTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) GAPI_TEST_FIXTURE(NV12toBGRTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(NV12toGrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(RGB2LabTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) GAPI_TEST_FIXTURE(RGB2LabTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(BGR2LUVTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) GAPI_TEST_FIXTURE(BGR2LUVTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(LUV2BGRTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) GAPI_TEST_FIXTURE(LUV2BGRTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)

View File

@ -504,6 +504,33 @@ TEST_P(NV12toBGRTest, AccuracyTest)
} }
} }
TEST_P(NV12toGrayTest, AccuracyTest)
{
// G-API code //////////////////////////////////////////////////////////////
cv::GMat in_y;
cv::GMat in_uv;
auto out = cv::gapi::NV12toGray(in_y, in_uv);
// Additional mat for uv
cv::Mat in_mat_uv(cv::Size(sz.width / 2, sz.height / 2), CV_8UC2);
cv::randn(in_mat_uv, cv::Scalar::all(127), cv::Scalar::all(40.f));
cv::GComputation c(cv::GIn(in_y, in_uv), cv::GOut(out));
c.apply(cv::gin(in_mat1, in_mat_uv), cv::gout(out_mat_gapi), getCompileArgs());
cv::Mat out_mat_ocv_planar;
cv::Mat uv_planar(in_mat1.rows / 2, in_mat1.cols, CV_8UC1, in_mat_uv.data);
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::vconcat(in_mat1, uv_planar, out_mat_ocv_planar);
cv::cvtColor(out_mat_ocv_planar, out_mat_ocv, cv::COLOR_YUV2GRAY_NV12);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv));
EXPECT_EQ(out_mat_gapi.size(), sz);
}
}
static void toPlanar(const cv::Mat& in, cv::Mat& out) static void toPlanar(const cv::Mat& in, cv::Mat& out)
{ {

View File

@ -244,11 +244,19 @@ INSTANTIATE_TEST_CASE_P(NV12toBGRTestCPU, NV12toBGRTest,
Values(IMGPROC_CPU), Values(IMGPROC_CPU),
Values(AbsExact().to_compare_obj()))); Values(AbsExact().to_compare_obj())));
INSTANTIATE_TEST_CASE_P(NV12toGrayTestCPU, NV12toGrayTest,
Combine(Values(CV_8UC1),
Values(cv::Size(1280, 720),
cv::Size(640, 480)),
Values(CV_8UC1),
Values(IMGPROC_CPU),
Values(AbsExact().to_compare_obj())));
INSTANTIATE_TEST_CASE_P(NV12toRGBpTestCPU, NV12toRGBpTest, INSTANTIATE_TEST_CASE_P(NV12toRGBpTestCPU, NV12toRGBpTest,
Combine(Values(CV_8UC1), Combine(Values(CV_8UC1),
Values(cv::Size(1280, 720), Values(cv::Size(1280, 720),
cv::Size(640, 480)), cv::Size(640, 480)),
Values(CV_8UC3), Values(CV_8UC1),
Values(IMGPROC_CPU), Values(IMGPROC_CPU),
Values(AbsExact().to_compare_obj()))); Values(AbsExact().to_compare_obj())));