mirror of
https://github.com/opencv/opencv_contrib.git
synced 2025-10-23 18:09:25 +08:00
Merge branch 4.x
This commit is contained in:
@@ -19,20 +19,24 @@ if(OCV_DEPENDENCIES_FOUND)
|
||||
if(NOT ENABLE_CUDA_FIRST_CLASS_LANGUAGE)
|
||||
ocv_check_windows_crt_linkage()
|
||||
set(target_libs ${target_libs} ${CUDA_LIBRARIES})
|
||||
set(test_cudev_cuda_options "")
|
||||
if(CUDA_VERSION VERSION_LESS "11.0")
|
||||
# Windows version does not support --std option
|
||||
if(UNIX OR APPLE)
|
||||
ocv_update(OPENCV_CUDA_OPTIONS_opencv_test_cudev "-std=c++11")
|
||||
list(APPEND test_cudev_cuda_options "-std=c++11")
|
||||
endif()
|
||||
else()
|
||||
if(CUDA_VERSION VERSION_LESS "12.8")
|
||||
ocv_update(OPENCV_CUDA_OPTIONS_opencv_test_cudev "-std=c++14")
|
||||
list(APPEND test_cudev_cuda_options "-std=c++14")
|
||||
else()
|
||||
ocv_update(OPENCV_CUDA_OPTIONS_opencv_test_cudev "-std=c++17")
|
||||
list(APPEND test_cudev_cuda_options "-std=c++17")
|
||||
if(WIN32)
|
||||
list(APPEND test_cudev_cuda_options "-Xcompiler=/Zc:preprocessor")
|
||||
endif()
|
||||
endif()
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wdeprecated-declarations)
|
||||
endif()
|
||||
CUDA_ADD_EXECUTABLE(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} OPTIONS ${OPENCV_CUDA_OPTIONS_opencv_test_cudev})
|
||||
CUDA_ADD_EXECUTABLE(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} OPTIONS ${test_cudev_cuda_options})
|
||||
else()
|
||||
ocv_add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES})
|
||||
endif()
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "opencv2/fastcv/fft_dsp.hpp"
|
||||
#include "opencv2/fastcv/edges_dsp.hpp"
|
||||
#include "opencv2/fastcv/blur_dsp.hpp"
|
||||
#include "opencv2/fastcv/color.hpp"
|
||||
|
||||
/**
|
||||
* @defgroup fastcv Module-wrapper for FastCV hardware accelerated functions
|
||||
|
||||
43
modules/fastcv/include/opencv2/fastcv/color.hpp
Normal file
43
modules/fastcv/include/opencv2/fastcv/color.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
// 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.
|
||||
|
||||
|
||||
#ifndef OPENCV_FASTCV_COLOR_HPP
|
||||
#define OPENCV_FASTCV_COLOR_HPP
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace fastcv
|
||||
{
|
||||
|
||||
enum ColorConversionCodes {
|
||||
// FastCV-specific color conversion codes (avoid collision with OpenCV core)
|
||||
COLOR_YUV2YUV444sp_NV12 = 156, //!< FastCV: YCbCr420PseudoPlanar to YCbCr444PseudoPlanar
|
||||
COLOR_YUV2YUV422sp_NV12 = 157, //!< FastCV: YCbCr420PseudoPlanar to YCbCr422PseudoPlanar
|
||||
COLOR_YUV422sp2YUV444sp = 158, //!< FastCV: YCbCr422PseudoPlanar to YCbCr444PseudoPlanar
|
||||
COLOR_YUV422sp2YUV_NV12 = 159, //!< FastCV: YCbCr422PseudoPlanar to YCbCr420PseudoPlanar
|
||||
COLOR_YUV444sp2YUV422sp = 160, //!< FastCV: YCbCr444PseudoPlanar to YCbCr422PseudoPlanar
|
||||
COLOR_YUV444sp2YUV_NV12 = 161, //!< FastCV: YCbCr444PseudoPlanar to YCbCr420PseudoPlanar
|
||||
COLOR_YUV2RGB565_NV12 = 162, //!< FastCV: YCbCr420PseudoPlanar to RGB565
|
||||
COLOR_YUV422sp2RGB565 = 163, //!< FastCV: YCbCr422PseudoPlanar to RGB565
|
||||
COLOR_YUV422sp2RGB = 164, //!< FastCV: YCbCr422PseudoPlanar to RGB888
|
||||
COLOR_YUV422sp2RGBA = 165, //!< FastCV: YCbCr422PseudoPlanar to RGBA8888
|
||||
COLOR_YUV444sp2RGB565 = 166, //!< FastCV: YCbCr444PseudoPlanar to RGB565
|
||||
COLOR_YUV444sp2RGB = 167, //!< FastCV: YCbCr444PseudoPlanar to RGB888
|
||||
COLOR_YUV444sp2RGBA = 168, //!< FastCV: YCbCr444PseudoPlanar to RGBA8888
|
||||
COLOR_RGB2YUV_NV12 = 169, //!< FastCV: RGB888 to YCbCr420PseudoPlanar
|
||||
COLOR_RGB5652YUV444sp = 170, //!< FastCV: RGB565 to YCbCr444PseudoPlanar
|
||||
COLOR_RGB5652YUV422sp = 171, //!< FastCV: RGB565 to YCbCr422PseudoPlanar
|
||||
COLOR_RGB5652YUV_NV12 = 172, //!< FastCV: RGB565 to YCbCr420PseudoPlanar
|
||||
COLOR_RGB2YUV444sp = 173, //!< FastCV: RGB888 to YCbCr444PseudoPlanar
|
||||
COLOR_RGB2YUV422sp = 174, //!< FastCV: RGB888 to YCbCr422PseudoPlanar
|
||||
};
|
||||
|
||||
CV_EXPORTS_W void cvtColor(InputArray src, OutputArray dst, int code);
|
||||
|
||||
}}; //cv::fastcv namespace end
|
||||
|
||||
#endif // OPENCV_FASTCV_COLOR_HPP
|
||||
372
modules/fastcv/src/color.cpp
Normal file
372
modules/fastcv/src/color.cpp
Normal file
@@ -0,0 +1,372 @@
|
||||
// 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.
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
namespace cv { namespace fastcv {
|
||||
|
||||
static void fastcvColorWrapper(const Mat& src, Mat& dst, int code);
|
||||
|
||||
inline double heightFactor(int fmt /*420 / 422 / 444*/)
|
||||
{
|
||||
switch (fmt)
|
||||
{
|
||||
case 420: return 1.5; // YUV420 has 1.5× rows
|
||||
case 422: return 2.0; // YUV422 have 2× rows
|
||||
case 444: return 2.0; // YUV444 have 3× rows
|
||||
default: return 1.0; // packed RGB565/RGB888 → no extra plane
|
||||
}
|
||||
}
|
||||
|
||||
inline void getFormats(int code, int& srcFmt, int& dstFmt)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case COLOR_YUV2YUV444sp_NV12: srcFmt=420; dstFmt=444; break;
|
||||
case COLOR_YUV2YUV422sp_NV12: srcFmt=420; dstFmt=422; break;
|
||||
case COLOR_YUV422sp2YUV444sp: srcFmt=422; dstFmt=444; break;
|
||||
case COLOR_YUV422sp2YUV_NV12: srcFmt=422; dstFmt=420; break;
|
||||
case COLOR_YUV444sp2YUV422sp: srcFmt=444; dstFmt=422; break;
|
||||
case COLOR_YUV444sp2YUV_NV12: srcFmt=444; dstFmt=420; break;
|
||||
case COLOR_YUV2RGB565_NV12: srcFmt=420; dstFmt=565; break;
|
||||
case COLOR_YUV422sp2RGB565: srcFmt=422; dstFmt=565; break;
|
||||
case COLOR_YUV422sp2RGB: srcFmt=422; dstFmt=888; break;
|
||||
case COLOR_YUV422sp2RGBA:srcFmt=422; dstFmt=8888; break;
|
||||
case COLOR_YUV444sp2RGB565: srcFmt=444; dstFmt=565; break;
|
||||
case COLOR_YUV444sp2RGB: srcFmt=444; dstFmt=888; break;
|
||||
case COLOR_YUV444sp2RGBA:srcFmt=444; dstFmt=8888; break;
|
||||
case COLOR_RGB5652YUV444sp: srcFmt=565; dstFmt=444; break;
|
||||
case COLOR_RGB5652YUV422sp: srcFmt=565; dstFmt=422; break;
|
||||
case COLOR_RGB5652YUV_NV12: srcFmt=565; dstFmt=420; break;
|
||||
case COLOR_RGB2YUV444sp: srcFmt=888; dstFmt=444; break;
|
||||
case COLOR_RGB2YUV422sp: srcFmt=888; dstFmt=422; break;
|
||||
case COLOR_RGB2YUV_NV12: srcFmt=888; dstFmt=420; break;
|
||||
|
||||
default:
|
||||
CV_Error(Error::StsBadArg, "Unknown FastCV color-code");
|
||||
}
|
||||
}
|
||||
|
||||
void cvtColor( InputArray _src, OutputArray _dst, int code)
|
||||
{
|
||||
switch( code )
|
||||
{
|
||||
case COLOR_YUV2YUV444sp_NV12:
|
||||
case COLOR_YUV2YUV422sp_NV12:
|
||||
case COLOR_YUV422sp2YUV444sp:
|
||||
case COLOR_YUV422sp2YUV_NV12:
|
||||
case COLOR_YUV444sp2YUV422sp:
|
||||
case COLOR_YUV444sp2YUV_NV12:
|
||||
case COLOR_YUV2RGB565_NV12:
|
||||
case COLOR_YUV422sp2RGB565:
|
||||
case COLOR_YUV422sp2RGB:
|
||||
case COLOR_YUV422sp2RGBA:
|
||||
case COLOR_YUV444sp2RGB565:
|
||||
case COLOR_YUV444sp2RGB:
|
||||
case COLOR_YUV444sp2RGBA:
|
||||
case COLOR_RGB5652YUV444sp:
|
||||
case COLOR_RGB5652YUV422sp:
|
||||
case COLOR_RGB5652YUV_NV12:
|
||||
case COLOR_RGB2YUV444sp:
|
||||
case COLOR_RGB2YUV422sp:
|
||||
case COLOR_RGB2YUV_NV12:
|
||||
fastcvColorWrapper(_src.getMat(), _dst.getMatRef(), code);
|
||||
break;
|
||||
|
||||
default:
|
||||
CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported color conversion code" );
|
||||
}
|
||||
}
|
||||
|
||||
void fastcvColorWrapper(const Mat& src, Mat& dst, int code)
|
||||
{
|
||||
CV_Assert(src.isContinuous());
|
||||
CV_Assert(reinterpret_cast<uintptr_t>(src.data) % 16 == 0);
|
||||
|
||||
const uint32_t width = static_cast<uint32_t>(src.cols);
|
||||
int srcFmt, dstFmt;
|
||||
getFormats(code, srcFmt, dstFmt);
|
||||
|
||||
const double hFactorSrc = heightFactor(srcFmt);
|
||||
CV_Assert(std::fmod(src.rows, hFactorSrc) == 0.0);
|
||||
|
||||
const uint32_t height = static_cast<uint32_t>(src.rows / hFactorSrc); // Y-plane height we pass to FastCV
|
||||
|
||||
const uint8_t* srcY = src.data;
|
||||
const size_t srcYBytes = static_cast<size_t>(src.step) * height;
|
||||
const uint8_t* srcC = srcY + srcYBytes;
|
||||
const uint32_t srcStride = static_cast<uint32_t>(src.step);
|
||||
|
||||
const int dstRows = static_cast<int>(height * heightFactor(dstFmt)); // 1.5·H or 2·H
|
||||
|
||||
int dstType = CV_8UC1; // default for planar/semi-planar YUV formats (1 byte per pixel)
|
||||
|
||||
switch (dstFmt)
|
||||
{
|
||||
case 420: case 422: case 444:
|
||||
dstType = CV_8UC1;
|
||||
break;
|
||||
|
||||
case 565: // RGB565 – 16-bit packed RGB, 2 bytes per pixel
|
||||
dstType = CV_8UC2;
|
||||
break;
|
||||
|
||||
case 888: // RGB888 – 3 bytes per pixel
|
||||
dstType = CV_8UC3;
|
||||
break;
|
||||
|
||||
case 8888: // RGBA8888 – 4 bytes per pixel
|
||||
dstType = CV_8UC4;
|
||||
break;
|
||||
|
||||
default:
|
||||
CV_Error(cv::Error::StsBadArg, "Unsupported destination pixel format for FastCV");
|
||||
}
|
||||
|
||||
dst.create(dstRows, width, dstType);
|
||||
|
||||
CV_Assert(dst.isContinuous());
|
||||
CV_Assert(reinterpret_cast<uintptr_t>(dst.data) % 16 == 0);
|
||||
|
||||
uint8_t* dstY = dst.data;
|
||||
uint8_t* dstC = dstY + static_cast<size_t>(dst.step) * height; // offset by Y-plane bytes
|
||||
const uint32_t dstStride = static_cast<uint32_t>(dst.step);
|
||||
|
||||
switch(code)
|
||||
{
|
||||
case COLOR_YUV2YUV444sp_NV12:
|
||||
{
|
||||
fcvColorYCbCr420PseudoPlanarToYCbCr444PseudoPlanaru8(
|
||||
srcY, srcC,
|
||||
width, height,
|
||||
srcStride, srcStride,
|
||||
dstY, dstC,
|
||||
dstStride, dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_YUV2YUV422sp_NV12:
|
||||
{
|
||||
fcvColorYCbCr420PseudoPlanarToYCbCr422PseudoPlanaru8(
|
||||
srcY, srcC,
|
||||
width, height,
|
||||
srcStride, srcStride,
|
||||
dstY, dstC,
|
||||
dstStride, dstStride
|
||||
);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_YUV422sp2YUV444sp:
|
||||
{
|
||||
fcvColorYCbCr422PseudoPlanarToYCbCr444PseudoPlanaru8(
|
||||
srcY, srcC,
|
||||
width, height,
|
||||
srcStride, srcStride,
|
||||
dstY, dstC,
|
||||
dstStride, dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_YUV422sp2YUV_NV12:
|
||||
{
|
||||
fcvColorYCbCr422PseudoPlanarToYCbCr420PseudoPlanaru8(
|
||||
srcY, srcC,
|
||||
width, height,
|
||||
srcStride, srcStride,
|
||||
dstY, dstC,
|
||||
dstStride, dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_YUV444sp2YUV422sp:
|
||||
{
|
||||
fcvColorYCbCr444PseudoPlanarToYCbCr422PseudoPlanaru8(
|
||||
srcY, srcC,
|
||||
width, height,
|
||||
srcStride, srcStride,
|
||||
dstY, dstC,
|
||||
dstStride, dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_YUV444sp2YUV_NV12:
|
||||
{
|
||||
fcvColorYCbCr444PseudoPlanarToYCbCr420PseudoPlanaru8(
|
||||
srcY, srcC,
|
||||
width, height,
|
||||
srcStride, srcStride,
|
||||
dstY, dstC,
|
||||
dstStride, dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_RGB5652YUV444sp:
|
||||
{
|
||||
fcvColorRGB565ToYCbCr444PseudoPlanaru8(
|
||||
srcY,
|
||||
width, height,
|
||||
srcStride,
|
||||
dstY, dstC,
|
||||
dstStride, dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_RGB5652YUV422sp:
|
||||
{
|
||||
fcvColorRGB565ToYCbCr422PseudoPlanaru8(
|
||||
srcY,
|
||||
width, height,
|
||||
srcStride,
|
||||
dstY, dstC,
|
||||
dstStride, dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_RGB5652YUV_NV12:
|
||||
{
|
||||
fcvColorRGB565ToYCbCr420PseudoPlanaru8(
|
||||
srcY,
|
||||
width, height,
|
||||
srcStride,
|
||||
dstY, dstC,
|
||||
dstStride, dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_RGB2YUV444sp:
|
||||
{
|
||||
fcvColorRGB888ToYCbCr444PseudoPlanaru8(
|
||||
srcY,
|
||||
width, height,
|
||||
srcStride,
|
||||
dstY, dstC,
|
||||
dstStride, dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_RGB2YUV422sp:
|
||||
{
|
||||
fcvColorRGB888ToYCbCr422PseudoPlanaru8(
|
||||
srcY,
|
||||
width, height,
|
||||
srcStride,
|
||||
dstY, dstC,
|
||||
dstStride, dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_RGB2YUV_NV12:
|
||||
{
|
||||
fcvColorRGB888ToYCbCr420PseudoPlanaru8(
|
||||
srcY,
|
||||
width, height,
|
||||
srcStride,
|
||||
dstY, dstC,
|
||||
dstStride, dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_YUV2RGB565_NV12:
|
||||
{
|
||||
fcvColorYCbCr420PseudoPlanarToRGB565u8(
|
||||
srcY, srcC,
|
||||
width, height,
|
||||
srcStride, srcStride,
|
||||
dstY,
|
||||
dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_YUV422sp2RGB565:
|
||||
{
|
||||
fcvColorYCbCr422PseudoPlanarToRGB565u8(
|
||||
srcY, srcC,
|
||||
width, height,
|
||||
srcStride, srcStride,
|
||||
dstY,
|
||||
dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_YUV422sp2RGB:
|
||||
{
|
||||
fcvColorYCbCr422PseudoPlanarToRGB888u8(
|
||||
srcY, srcC,
|
||||
width, height,
|
||||
srcStride, srcStride,
|
||||
dstY,
|
||||
dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_YUV422sp2RGBA:
|
||||
{
|
||||
fcvColorYCbCr422PseudoPlanarToRGBA8888u8(
|
||||
srcY, srcC,
|
||||
width, height,
|
||||
srcStride, srcStride,
|
||||
dstY,
|
||||
dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_YUV444sp2RGB565:
|
||||
{
|
||||
fcvColorYCbCr444PseudoPlanarToRGB565u8(
|
||||
srcY, srcC,
|
||||
width, height,
|
||||
srcStride, srcStride,
|
||||
dstY,
|
||||
dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_YUV444sp2RGB:
|
||||
{
|
||||
fcvColorYCbCr444PseudoPlanarToRGB888u8(
|
||||
srcY, srcC,
|
||||
width, height,
|
||||
srcStride, srcStride,
|
||||
dstY,
|
||||
dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_YUV444sp2RGBA:
|
||||
{
|
||||
fcvColorYCbCr444PseudoPlanarToRGBA8888u8(
|
||||
srcY, srcC,
|
||||
width, height,
|
||||
srcStride, srcStride,
|
||||
dstY,
|
||||
dstStride
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
CV_Error(cv::Error::StsBadArg, "Unsupported FastCV color code");
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace cv::fastcv
|
||||
136
modules/fastcv/test/test_color.cpp
Normal file
136
modules/fastcv/test/test_color.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
static inline void fillRandom8U(cv::Mat& m)
|
||||
{
|
||||
cv::RNG& rng = cv::theRNG();
|
||||
rng.fill(m, cv::RNG::UNIFORM, 0, 256);
|
||||
}
|
||||
|
||||
TEST(Fastcv_cvtColor, YUV420_to_YUV422_and_back_roundtrip)
|
||||
{
|
||||
const cv::Size sz(640, 480);
|
||||
|
||||
cv::Mat bgr(sz, CV_8UC3);
|
||||
fillRandom8U(bgr);
|
||||
|
||||
cv::Mat rgb;
|
||||
cv::cvtColor(bgr, rgb, cv::COLOR_BGR2RGB);
|
||||
|
||||
cv::Mat yuv420_before;
|
||||
yuv420_before.allocator = cv::fastcv::getQcAllocator();
|
||||
cv::fastcv::cvtColor(rgb, yuv420_before, cv::fastcv::COLOR_RGB2YUV_NV12);
|
||||
|
||||
cv::Mat yuv422;
|
||||
yuv422.allocator = cv::fastcv::getQcAllocator();
|
||||
cv::fastcv::cvtColor(yuv420_before, yuv422, cv::fastcv::COLOR_YUV2YUV422sp_NV12);
|
||||
|
||||
cv::Mat yuv422_to_bgr;
|
||||
|
||||
cv::Mat yuv420_after;
|
||||
yuv420_after.allocator = cv::fastcv::getQcAllocator();
|
||||
cv::fastcv::cvtColor(yuv422, yuv420_after, cv::fastcv::COLOR_YUV422sp2YUV_NV12);
|
||||
|
||||
ASSERT_EQ(yuv420_before.size(), yuv420_after.size());
|
||||
ASSERT_EQ(yuv420_before.type(), yuv420_after.type());
|
||||
|
||||
double maxDiff = cv::norm(yuv420_before, yuv420_after, cv::NORM_INF);
|
||||
std::cout << "Max difference YUV420 before vs after = " << maxDiff << std::endl;
|
||||
EXPECT_LE(maxDiff, 1.0);
|
||||
}
|
||||
|
||||
TEST(Fastcv_cvtColor, YUV444_to_YUV420_and_back_roundtrip)
|
||||
{
|
||||
const cv::Size sz(640, 480);
|
||||
|
||||
cv::Mat bgr(sz, CV_8UC3);
|
||||
fillRandom8U(bgr);
|
||||
cv::Mat rgb;
|
||||
cv::cvtColor(bgr, rgb, cv::COLOR_BGR2RGB);
|
||||
|
||||
cv::Mat yuv444_initial;
|
||||
yuv444_initial.allocator = cv::fastcv::getQcAllocator();
|
||||
cv::fastcv::cvtColor(rgb, yuv444_initial, cv::fastcv::COLOR_RGB2YUV444sp);
|
||||
|
||||
cv::Mat yuv420;
|
||||
yuv420.allocator = cv::fastcv::getQcAllocator();
|
||||
cv::fastcv::cvtColor(yuv444_initial, yuv420, cv::fastcv::COLOR_YUV444sp2YUV_NV12);
|
||||
|
||||
cv::Mat yuv444_final;
|
||||
yuv444_final.allocator = cv::fastcv::getQcAllocator();
|
||||
cv::fastcv::cvtColor(yuv420, yuv444_final, cv::fastcv::COLOR_YUV2YUV444sp_NV12);
|
||||
|
||||
ASSERT_EQ(yuv444_initial.size(), yuv444_final.size());
|
||||
ASSERT_EQ(yuv444_initial.type(), yuv444_final.type());
|
||||
|
||||
double maxDiff = cv::norm(yuv444_initial, yuv444_final, cv::NORM_INF);
|
||||
std::cout << "Max difference YUV444 before vs after roundtrip = " << maxDiff << std::endl;
|
||||
EXPECT_LE(maxDiff, 2.0);
|
||||
}
|
||||
|
||||
TEST(Fastcv_cvtColor, YUV444_to_YUV422_and_back_roundtrip)
|
||||
{
|
||||
const cv::Size sz(640, 480);
|
||||
|
||||
cv::Mat bgr(sz, CV_8UC3);
|
||||
fillRandom8U(bgr);
|
||||
cv::Mat rgb;
|
||||
cv::cvtColor(bgr, rgb, cv::COLOR_BGR2RGB);
|
||||
|
||||
cv::Mat yuv444_initial;
|
||||
yuv444_initial.allocator = cv::fastcv::getQcAllocator();
|
||||
cv::fastcv::cvtColor(rgb, yuv444_initial, cv::fastcv::COLOR_RGB2YUV444sp);
|
||||
|
||||
cv::Mat yuv422;
|
||||
yuv422.allocator = cv::fastcv::getQcAllocator();
|
||||
cv::fastcv::cvtColor(yuv444_initial, yuv422, cv::fastcv::COLOR_YUV444sp2YUV422sp);
|
||||
|
||||
cv::Mat yuv444_final;
|
||||
yuv444_final.allocator = cv::fastcv::getQcAllocator();
|
||||
cv::fastcv::cvtColor(yuv422, yuv444_final, cv::fastcv::COLOR_YUV422sp2YUV444sp);
|
||||
|
||||
ASSERT_EQ(yuv444_initial.size(), yuv444_final.size());
|
||||
ASSERT_EQ(yuv444_initial.type(), yuv444_final.type());
|
||||
|
||||
double maxDiff = cv::norm(yuv444_initial, yuv444_final, cv::NORM_INF);
|
||||
std::cout << "Max difference YUV444 before vs after roundtrip = " << maxDiff << std::endl;
|
||||
EXPECT_LE(maxDiff, 2.0);
|
||||
}
|
||||
|
||||
TEST(Fastcv_cvtColor, YUV444_to_RGB565_and_back_roundtrip)
|
||||
{
|
||||
const cv::Size sz(640, 480);
|
||||
cv::Mat bgr(sz, CV_8UC3);
|
||||
fillRandom8U(bgr);
|
||||
|
||||
cv::Mat rgb;
|
||||
cv::cvtColor(bgr, rgb, cv::COLOR_BGR2RGB);
|
||||
|
||||
cv::Mat yuv444_initial;
|
||||
yuv444_initial.allocator = cv::fastcv::getQcAllocator();
|
||||
cv::fastcv::cvtColor(rgb, yuv444_initial, cv::fastcv::COLOR_RGB2YUV444sp);
|
||||
|
||||
cv::Mat rgb565(sz, CV_8UC2);
|
||||
rgb565.allocator = cv::fastcv::getQcAllocator();
|
||||
cv::fastcv::cvtColor(yuv444_initial, rgb565, cv::fastcv::COLOR_YUV444sp2RGB565);
|
||||
|
||||
cv::Mat yuv444_roundtrip;
|
||||
yuv444_roundtrip.allocator = cv::fastcv::getQcAllocator();
|
||||
cv::fastcv::cvtColor(rgb565, yuv444_roundtrip, cv::fastcv::COLOR_RGB5652YUV444sp);
|
||||
|
||||
ASSERT_EQ(yuv444_initial.size(), yuv444_roundtrip.size());
|
||||
ASSERT_EQ(yuv444_initial.type(), yuv444_roundtrip.type());
|
||||
|
||||
double maxDiff = cv::norm(yuv444_initial, yuv444_roundtrip, cv::NORM_INF);
|
||||
std::cout << "Max difference YUV444 after RGB565 roundtrip = " << maxDiff << std::endl;
|
||||
|
||||
EXPECT_LE(maxDiff, 2.0);
|
||||
}
|
||||
|
||||
}} // namespace opencv_test
|
||||
@@ -99,6 +99,8 @@ struct ParamDesc {
|
||||
PluginConfigT config;
|
||||
|
||||
size_t nireq = 1;
|
||||
|
||||
bool ensure_named_tensors = false;
|
||||
};
|
||||
|
||||
// NB: Just helper to avoid code duplication.
|
||||
@@ -205,6 +207,24 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** @brief Ensures the model has named tensors.
|
||||
|
||||
This function is used to ensure that all tensors in the model have names.
|
||||
It goes through all input and output nodes of the model and sets the names
|
||||
if they are not set. This is neccessary for models with nameless tensors.
|
||||
|
||||
If a tensor does not have a name, it will be assigned a default name
|
||||
based on the producer node's friendly name. If the producer node has multiple
|
||||
outputs, the name will be in the form "node_name:N", where N is the output index.
|
||||
|
||||
@param flag If true, then it guarantees that all tensors will have names.
|
||||
@return reference to this parameter structure.
|
||||
*/
|
||||
Params<Net>& cfgEnsureNamedTensors(bool flag = true) {
|
||||
m_desc.ensure_named_tensors = flag;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** @brief Specifies tensor layout for an input layer.
|
||||
|
||||
The function is used to set tensor layout for an input layer.
|
||||
@@ -524,6 +544,12 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** @see ov::Params::cfgEnsureNamedTensors. */
|
||||
Params& cfgEnsureNamedTensors(bool flag = true) {
|
||||
m_desc.ensure_named_tensors = flag;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** @see ov::Params::cfgInputTensorLayout. */
|
||||
Params& cfgInputTensorLayout(std::string layout) {
|
||||
detail::getModelToSetAttrOrThrow(m_desc.kind, "input tensor layout")
|
||||
|
||||
@@ -69,6 +69,27 @@ ov::Core cv::gapi::ov::wrap::getCore() {
|
||||
? create_OV_Core_pointer() : create_OV_Core_instance();
|
||||
}
|
||||
|
||||
static std::string make_default_tensor_name(const ov::Output<const ov::Node>& output) {
|
||||
auto default_name = output.get_node()->get_friendly_name();
|
||||
if (output.get_node()->get_output_size() > 1) {
|
||||
default_name += ':' + std::to_string(output.get_index());
|
||||
}
|
||||
return default_name;
|
||||
}
|
||||
|
||||
static void ensureNamedTensors(std::shared_ptr<ov::Model> model) {
|
||||
for (auto& input : model->inputs()) {
|
||||
if (input.get_names().empty()) {
|
||||
input.set_names({make_default_tensor_name(input)});
|
||||
}
|
||||
}
|
||||
for (auto& output : model->outputs()) {
|
||||
if (output.get_names().empty()) {
|
||||
output.set_names({make_default_tensor_name(output)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ov::AnyMap toOV(const ParamDesc::PluginConfigT &config) {
|
||||
return {config.begin(), config.end()};
|
||||
}
|
||||
@@ -236,6 +257,10 @@ struct OVUnit {
|
||||
.read_model(desc.model_path, desc.bin_path);
|
||||
GAPI_Assert(model);
|
||||
|
||||
if (params.ensure_named_tensors) {
|
||||
ensureNamedTensors(model);
|
||||
}
|
||||
|
||||
if (params.num_in == 1u && params.input_names.empty()) {
|
||||
params.input_names = { model->inputs().begin()->get_any_name() };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user