Unverified Commit 4d3d6230 authored by Anatoliy Talamanov's avatar Anatoliy Talamanov Committed by GitHub

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
parent ea34b2fe
...@@ -222,6 +222,21 @@ namespace imgproc { ...@@ -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. ...@@ -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.
......
...@@ -157,18 +157,26 @@ GMat RGB2Lab(const GMat& src) ...@@ -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);
......
...@@ -10,9 +10,11 @@ ...@@ -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) ...@@ -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) ...@@ -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() ...@@ -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;
} }
...@@ -56,10 +56,12 @@ GAPI_TEST_FIXTURE(RGB2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cm ...@@ -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)
......
...@@ -504,6 +504,33 @@ TEST_P(NV12toBGRTest, AccuracyTest) ...@@ -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)
{ {
......
...@@ -244,11 +244,19 @@ INSTANTIATE_TEST_CASE_P(NV12toBGRTestCPU, NV12toBGRTest, ...@@ -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())));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment