Merge pull request #19554 from amirtu:OCV-215_cvtColorTwoPlane_wrong_output_when_Y_Plane_Mat_has_step

different paddings in cvtColorTwoPlane() for biplane YUV420

* Different paddings support in cvtColorTwoPlane() for biplane YUV420

* Build fix for dispatch case.

* Resoted old behaviour for y.step==uv.step to exclude perf regressions.

Co-authored-by: amir.tulegenov <amir.tulegenov@xperience.ai>
Co-authored-by: Alexander Smorkalov <alexander.smorkalov@xperience.ai>
This commit is contained in:
Amir Tulegenov 2021-09-22 20:42:32 +06:00 committed by GitHub
parent 998406d20e
commit 86a51015b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 149 additions and 70 deletions

View File

@ -1778,30 +1778,30 @@ TegraCvtColor_Invoker(bgrx2hsvf, bgrx2hsv, src_data + static_cast<size_t>(range.
: CV_HAL_ERROR_NOT_IMPLEMENTED \
)
#define TEGRA_CVT2PYUVTOBGR(src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx) \
#define TEGRA_CVT2PYUVTOBGR_EX(y_data, y_step, uv_data, uv_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx) \
( \
CAROTENE_NS::isSupportedConfiguration() ? \
dcn == 3 ? \
uIdx == 0 ? \
(swapBlue ? \
CAROTENE_NS::yuv420i2rgb(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step) : \
CAROTENE_NS::yuv420i2bgr(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step)), \
CV_HAL_ERROR_OK : \
uIdx == 1 ? \
(swapBlue ? \
CAROTENE_NS::yuv420sp2rgb(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step) : \
CAROTENE_NS::yuv420sp2bgr(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step)), \
CV_HAL_ERROR_OK : \
CV_HAL_ERROR_NOT_IMPLEMENTED : \
@ -1809,29 +1809,32 @@ TegraCvtColor_Invoker(bgrx2hsvf, bgrx2hsv, src_data + static_cast<size_t>(range.
uIdx == 0 ? \
(swapBlue ? \
CAROTENE_NS::yuv420i2rgbx(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step) : \
CAROTENE_NS::yuv420i2bgrx(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step)), \
CV_HAL_ERROR_OK : \
uIdx == 1 ? \
(swapBlue ? \
CAROTENE_NS::yuv420sp2rgbx(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step) : \
CAROTENE_NS::yuv420sp2bgrx(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step)), \
CV_HAL_ERROR_OK : \
CV_HAL_ERROR_NOT_IMPLEMENTED : \
CV_HAL_ERROR_NOT_IMPLEMENTED \
: CV_HAL_ERROR_NOT_IMPLEMENTED \
)
#define TEGRA_CVT2PYUVTOBGR(src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx) \
TEGRA_CVT2PYUVTOBGR_EX(src_data, src_step, src_data + src_step * dst_height, src_step, dst_data, dst_step, \
dst_width, dst_height, dcn, swapBlue, uIdx);
#undef cv_hal_cvtBGRtoBGR
#define cv_hal_cvtBGRtoBGR TEGRA_CVTBGRTOBGR
@ -1847,6 +1850,8 @@ TegraCvtColor_Invoker(bgrx2hsvf, bgrx2hsv, src_data + static_cast<size_t>(range.
#define cv_hal_cvtBGRtoHSV TEGRA_CVTBGRTOHSV
#undef cv_hal_cvtTwoPlaneYUVtoBGR
#define cv_hal_cvtTwoPlaneYUVtoBGR TEGRA_CVT2PYUVTOBGR
#undef cv_hal_cvtTwoPlaneYUVtoBGREx
#define cv_hal_cvtTwoPlaneYUVtoBGREx TEGRA_CVT2PYUVTOBGR_EX
#endif // OPENCV_IMGPROC_HAL_INTERFACE_H

View File

@ -923,6 +923,11 @@ int ovx_hal_cvtGraytoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep,
}
int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx)
{
return ovx_hal_cvtTwoPlaneYUVtoBGREx(a, astep, a + h * astep, astep, b, bstep, w, h, bcn, swapBlue, uIdx);
}
int ovx_hal_cvtTwoPlaneYUVtoBGREx(const uchar * a, size_t astep, const uchar * b, size_t bstep, uchar * c, size_t cstep, int w, int h, int bcn, bool swapBlue, int uIdx)
{
if (skipSmallImages<VX_KERNEL_COLOR_CONVERT>(w, h))
return CV_HAL_ERROR_NOT_IMPLEMENTED;
@ -933,8 +938,7 @@ int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t
if (w & 1 || h & 1) // It's not described in spec but sample implementation unable to convert odd sized images
return CV_HAL_ERROR_NOT_IMPLEMENTED;
refineStep(w, h, uIdx ? VX_DF_IMAGE_NV21 : VX_DF_IMAGE_NV12, astep);
refineStep(w, h, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, bstep);
try
{
ivx::Context ctx = getOpenVXHALContext();
@ -943,8 +947,8 @@ int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t
std::vector<void *> ptrs;
addr.push_back(ivx::Image::createAddressing(w, h, 1, (vx_int32)astep));
ptrs.push_back((void*)a);
addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 2, (vx_int32)astep));
ptrs.push_back((void*)(a + h * astep));
addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 2, (vx_int32)bstep));
ptrs.push_back((void*)b);
vxImage
ia = ivx::Image::createFromHandle(ctx, uIdx ? VX_DF_IMAGE_NV21 : VX_DF_IMAGE_NV12, addr, ptrs);
@ -952,7 +956,7 @@ int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t
return CV_HAL_ERROR_NOT_IMPLEMENTED; // OpenCV store NV12/NV21 as RANGE_RESTRICTED while OpenVX expect RANGE_FULL
vxImage
ib = ivx::Image::createFromHandle(ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX,
ivx::Image::createAddressing(w, h, bcn, (vx_int32)bstep), b);
ivx::Image::createAddressing(w, h, bcn, (vx_int32)cstep), c);
ivx::IVX_CHECK_STATUS(vxuColorConvert(ctx, ia, ib));
}
catch (ivx::RuntimeError & e)

View File

@ -49,6 +49,7 @@ int ovx_hal_morph(cvhalFilter2D *filter_context, uchar *a, size_t astep, uchar *
int ovx_hal_cvtBGRtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int acn, int bcn, bool swapBlue);
int ovx_hal_cvtGraytoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int bcn);
int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx);
int ovx_hal_cvtTwoPlaneYUVtoBGREx(const uchar * a, size_t astep, const uchar * b, size_t bstep, uchar * c, size_t cstep, int w, int h, int bcn, bool swapBlue, int uIdx);
int ovx_hal_cvtThreePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx);
int ovx_hal_cvtBGRtoThreePlaneYUV(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int acn, bool swapBlue, int uIdx);
int ovx_hal_cvtOnePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx, int ycn);
@ -130,6 +131,8 @@ int ovx_hal_integral(int depth, int sdepth, int, const uchar * a, size_t astep,
#define cv_hal_cvtGraytoBGR ovx_hal_cvtGraytoBGR
#undef cv_hal_cvtTwoPlaneYUVtoBGR
#define cv_hal_cvtTwoPlaneYUVtoBGR ovx_hal_cvtTwoPlaneYUVtoBGR
#undef cv_hal_cvtTwoPlaneYUVtoBGREx
#define cv_hal_cvtTwoPlaneYUVtoBGREx ovx_hal_cvtTwoPlaneYUVtoBGREx
#undef cv_hal_cvtThreePlaneYUVtoBGR
#define cv_hal_cvtThreePlaneYUVtoBGR ovx_hal_cvtThreePlaneYUVtoBGR
#undef cv_hal_cvtBGRtoThreePlaneYUV

View File

@ -198,6 +198,11 @@ CV_EXPORTS void cvtTwoPlaneYUVtoBGR(const uchar * y_data, const uchar * uv_data,
int dst_width, int dst_height,
int dcn, bool swapBlue, int uIdx);
CV_EXPORTS void cvtTwoPlaneYUVtoBGR(const uchar * y_data, size_t y_step, const uchar * uv_data, size_t uv_step,
uchar * dst_data, size_t dst_step,
int dst_width, int dst_height,
int dcn, bool swapBlue, int uIdx);
CV_EXPORTS void cvtThreePlaneYUVtoBGR(const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int dst_width, int dst_height,

View File

@ -124,8 +124,9 @@ void cvtTwoPlaneYUVtoBGR(const uchar * src_data, size_t src_step,
CALL_HAL(cvtTwoPlaneYUVtoBGR, cv_hal_cvtTwoPlaneYUVtoBGR, src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx);
CV_CPU_DISPATCH(cvtTwoPlaneYUVtoBGR, (src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx),
CV_CPU_DISPATCH_MODES_ALL);
cvtTwoPlaneYUVtoBGR(
src_data, src_step, src_data + src_step * dst_height, src_step, dst_data, dst_step,
dst_width, dst_height, dcn, swapBlue, uIdx);
}
void cvtTwoPlaneYUVtoBGR(const uchar * y_data, const uchar * uv_data, size_t src_step,
@ -135,7 +136,20 @@ void cvtTwoPlaneYUVtoBGR(const uchar * y_data, const uchar * uv_data, size_t src
{
CV_INSTRUMENT_REGION();
CV_CPU_DISPATCH(cvtTwoPlaneYUVtoBGR, (y_data, uv_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx),
cvtTwoPlaneYUVtoBGR(y_data, src_step, uv_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx);
}
void cvtTwoPlaneYUVtoBGR(const uchar * y_data, size_t y_step, const uchar * uv_data, size_t uv_step,
uchar * dst_data, size_t dst_step,
int dst_width, int dst_height,
int dcn, bool swapBlue, int uIdx)
{
CV_INSTRUMENT_REGION();
CALL_HAL(cvtTwoPlaneYUVtoBGREx, cv_hal_cvtTwoPlaneYUVtoBGREx,
y_data, y_step, uv_data, uv_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx);
CV_CPU_DISPATCH(cvtTwoPlaneYUVtoBGR, (y_data, y_step, uv_data, uv_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx),
CV_CPU_DISPATCH_MODES_ALL);
}
@ -172,7 +186,8 @@ void cvtBGRtoTwoPlaneYUV(const uchar * src_data, size_t src_step,
{
CV_INSTRUMENT_REGION();
// TODO: add hal replacement method
CALL_HAL(cvtBGRtoTwoPlaneYUV, cv_hal_cvtBGRtoTwoPlaneYUV,
src_data, src_step, y_data, dst_step, uv_data, dst_step, width, height, scn, swapBlue, uIdx);
CV_CPU_DISPATCH(cvtBGRtoTwoPlaneYUV, (src_data, src_step, y_data, uv_data, dst_step, width, height, scn, swapBlue, uIdx),
CV_CPU_DISPATCH_MODES_ALL);
@ -406,14 +421,21 @@ void cvtColorTwoPlaneYUV2BGRpair( InputArray _ysrc, InputArray _uvsrc, OutputArr
Mat ysrc = _ysrc.getMat(), uvsrc = _uvsrc.getMat();
CV_CheckEQ(ysrc.step, uvsrc.step, "");
_dst.create( ysz, CV_MAKETYPE(depth, dcn));
Mat dst = _dst.getMat();
hal::cvtTwoPlaneYUVtoBGR(ysrc.data, uvsrc.data, ysrc.step,
dst.data, dst.step, dst.cols, dst.rows,
dcn, swapb, uidx);
if(ysrc.step == uvsrc.step)
{
hal::cvtTwoPlaneYUVtoBGR(ysrc.data, uvsrc.data, ysrc.step,
dst.data, dst.step, dst.cols, dst.rows,
dcn, swapb, uidx);
}
else
{
hal::cvtTwoPlaneYUVtoBGR(ysrc.data, ysrc.step, uvsrc.data, uvsrc.step,
dst.data, dst.step, dst.cols, dst.rows,
dcn, swapb, uidx);
}
}
} // namespace cv

View File

@ -17,11 +17,7 @@ void cvtYUVtoBGR(const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int depth, int dcn, bool swapBlue, bool isCbCr);
void cvtTwoPlaneYUVtoBGR(const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int dst_width, int dst_height,
int dcn, bool swapBlue, int uIdx);
void cvtTwoPlaneYUVtoBGR(const uchar * y_data, const uchar * uv_data, size_t src_step,
void cvtTwoPlaneYUVtoBGR(const uchar * y_data, size_t y_step, const uchar * uv_data, size_t uv_step,
uchar * dst_data, size_t dst_step,
int dst_width, int dst_height,
int dcn, bool swapBlue, int uIdx);
@ -1177,24 +1173,28 @@ struct YUV420sp2RGB8Invoker : ParallelLoopBody
uchar * dst_data;
size_t dst_step;
int width;
const uchar* my1, *muv;
size_t stride;
const uchar* my1;
size_t my1_step;
const uchar* muv;
size_t muv_step;
YUV420sp2RGB8Invoker(uchar * _dst_data, size_t _dst_step, int _dst_width, size_t _stride, const uchar* _y1, const uchar* _uv)
: dst_data(_dst_data), dst_step(_dst_step), width(_dst_width), my1(_y1), muv(_uv), stride(_stride) {}
YUV420sp2RGB8Invoker(uchar * _dst_data, size_t _dst_step, int _dst_width,
const uchar* _y1, size_t _y1_step, const uchar* _uv, size_t _uv_step) :
dst_data(_dst_data), dst_step(_dst_step), width(_dst_width),
my1(_y1), my1_step(_y1_step), muv(_uv), muv_step(_uv_step) {}
void operator()(const Range& range) const CV_OVERRIDE
{
const int rangeBegin = range.start * 2;
const int rangeEnd = range.end * 2;
const uchar* y1 = my1 + rangeBegin * stride, *uv = muv + rangeBegin * stride / 2;
const uchar* y1 = my1 + rangeBegin * my1_step, *uv = muv + rangeBegin * muv_step / 2;
for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, uv += stride)
for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += my1_step * 2, uv += muv_step)
{
uchar* row1 = dst_data + dst_step * j;
uchar* row2 = dst_data + dst_step * (j + 1);
const uchar* y2 = y1 + stride;
const uchar* y2 = y1 + my1_step;
int i = 0;
#if CV_SIMD
@ -1395,9 +1395,10 @@ struct YUV420p2RGB8Invoker : ParallelLoopBody
#define MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION (320*240)
template<int bIdx, int uIdx, int dcn>
inline void cvtYUV420sp2RGB(uchar * dst_data, size_t dst_step, int dst_width, int dst_height, size_t _stride, const uchar* _y1, const uchar* _uv)
inline void cvtYUV420sp2RGB(uchar * dst_data, size_t dst_step, int dst_width, int dst_height,
const uchar* _y1, size_t _y1_step, const uchar* _uv, size_t _uv_step)
{
YUV420sp2RGB8Invoker<bIdx, uIdx, dcn> converter(dst_data, dst_step, dst_width, _stride, _y1, _uv);
YUV420sp2RGB8Invoker<bIdx, uIdx, dcn> converter(dst_data, dst_step, dst_width, _y1, _y1_step, _uv, _uv_step);
if (dst_width * dst_height >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION)
parallel_for_(Range(0, dst_height/2), converter);
else
@ -1817,26 +1818,16 @@ void cvtYUVtoBGR(const uchar * src_data, size_t src_step,
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, YCrCb2RGB_f<float>(dcn, blueIdx, isCbCr));
}
void cvtTwoPlaneYUVtoBGR(const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int dst_width, int dst_height,
int dcn, bool swapBlue, int uIdx)
{
CV_INSTRUMENT_REGION();
const uchar* uv = src_data + src_step * static_cast<size_t>(dst_height);
cvtTwoPlaneYUVtoBGR(src_data, uv, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx);
}
typedef void (*cvt_2plane_yuv_ptr_t)(uchar * /* dst_data*/,
size_t /* dst_step */,
int /* dst_width */,
int /* dst_height */,
size_t /* _stride */,
const uchar* /* _y1 */,
const uchar* /* _uv */);
size_t /* _y1_step */,
const uchar* /* _uv */,
size_t /* _uv_step */);
void cvtTwoPlaneYUVtoBGR(const uchar * y_data, const uchar * uv_data, size_t src_step,
void cvtTwoPlaneYUVtoBGR(const uchar * y_data, size_t y_step, const uchar * uv_data, size_t uv_step,
uchar * dst_data, size_t dst_step,
int dst_width, int dst_height,
int dcn, bool swapBlue, int uIdx)
@ -1859,7 +1850,7 @@ void cvtTwoPlaneYUVtoBGR(const uchar * y_data, const uchar * uv_data, size_t src
default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break;
};
cvtPtr(dst_data, dst_step, dst_width, dst_height, src_step, y_data, uv_data);
cvtPtr(dst_data, dst_step, dst_width, dst_height, y_data, y_step, uv_data, uv_step);
}
typedef void (*cvt_3plane_yuv_ptr_t)(uchar * /* dst_data */,

View File

@ -498,6 +498,39 @@ inline int hal_ni_cvtLabtoBGR(const uchar * src_data, size_t src_step, uchar * d
*/
inline int hal_ni_cvtTwoPlaneYUVtoBGR(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int dst_width, int dst_height, int dcn, bool swapBlue, int uIdx) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
/**
@brief Extended version of hal_cvtTwoPlaneYUVtoBGR.
@param y_data,y_step source image data and step (Y-plane)
@param uv_data,uv_step source image data and step (UV-plane)
@param dst_data,dst_step destination image data and step
@param dst_width,dst_height destination image size
@param dcn destination image channels (3 or 4)
@param swapBlue if set to true B and R destination channels will be swapped (write RGB)
@param uIdx U-channel index in the interleaved U/V plane (0 or 1)
Convert from YUV (YUV420sp (or NV12/NV21) - Y plane followed by interleaved U/V plane) to BGR, RGB, BGRA or RGBA.
Only for CV_8U.
*/
inline int hal_ni_cvtTwoPlaneYUVtoBGREx(const uchar * y_data, size_t y_step, const uchar * uv_data, size_t uv_step,
uchar * dst_data, size_t dst_step, int dst_width, int dst_height,
int dcn, bool swapBlue, int uIdx) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
/**
@brief hal_cvtBGRtoTwoPlaneYUV
@param src_data,src_step source image data and step
@param y_data,y_step destination image data and step (Y-plane)
@param uv_data,uv_step destination image data and step (UV-plane)
@param width,height image size
@param scn source image channels (3 or 4)
@param swapBlue if set to true B and R source channels will be swapped (treat as RGB)
@param uIdx U-channel plane index (0 or 1)
Convert from BGR, RGB, BGRA or RGBA to YUV (YUV420sp (or NV12/NV21) - Y plane followed by interleaved U/V plane).
Only for CV_8U.
*/
inline int hal_ni_cvtBGRtoTwoPlaneYUV(const uchar * src_data, size_t src_step,
uchar * y_data, size_t y_step, uchar * uv_data, size_t uv_step,
int width, int height,
int scn, bool swapBlue, int uIdx) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
/**
@brief hal_cvtThreePlaneYUVtoBGR
@param src_data,src_step source image data and step
@ -576,6 +609,8 @@ inline int hal_ni_cvtMultipliedRGBAtoRGBA(const uchar * src_data, size_t src_ste
#define cv_hal_cvtBGRtoLab hal_ni_cvtBGRtoLab
#define cv_hal_cvtLabtoBGR hal_ni_cvtLabtoBGR
#define cv_hal_cvtTwoPlaneYUVtoBGR hal_ni_cvtTwoPlaneYUVtoBGR
#define cv_hal_cvtTwoPlaneYUVtoBGREx hal_ni_cvtTwoPlaneYUVtoBGREx
#define cv_hal_cvtBGRtoTwoPlaneYUV hal_ni_cvtBGRtoTwoPlaneYUV
#define cv_hal_cvtThreePlaneYUVtoBGR hal_ni_cvtThreePlaneYUVtoBGR
#define cv_hal_cvtBGRtoThreePlaneYUV hal_ni_cvtBGRtoThreePlaneYUV
#define cv_hal_cvtOnePlaneYUVtoBGR hal_ni_cvtOnePlaneYUVtoBGR

View File

@ -3072,20 +3072,34 @@ TEST(ImgProc_RGB2YUV, regression_13668)
EXPECT_EQ(res, ref);
}
TEST(ImgProc_cvtColorTwoPlane, missing_check_17036) // test can be removed if required feature is implemented
TEST(ImgProc_cvtColorTwoPlane, y_plane_padding_differs_from_uv_plane_padding_17036)
{
std::vector<uchar> y_data(700 * 480);
std::vector<uchar> uv_data(640 * 240);
RNG &rng = theRNG();
Mat y_plane_padding(480, 640, CV_8UC1, y_data.data(), 700); // with stride
Mat uv_plane(240, 320, CV_8UC2, uv_data.data());
std::vector<uchar> y_reference(640 * 480);
std::vector<uchar> uv_reference(640 * 240);
std::vector<uchar> y_padded(700 * 480);
std::vector<uchar> uv_padded(700 * 240);
Mat result;
Mat y_reference_mat(480, 640, CV_8UC1, y_reference.data());
Mat uv_reference_mat(240, 320, CV_8UC2, uv_reference.data());
Mat y_padded_mat(480, 640, CV_8UC1, y_padded.data(), 700);
Mat uv_padded_mat(240, 320, CV_8UC2, uv_padded.data(), 700);
EXPECT_THROW(
cvtColorTwoPlane(y_plane_padding, uv_plane, result, COLOR_YUV2RGB_NV21);
, cv::Exception
);
rng.fill(y_reference_mat, RNG::UNIFORM, 16, 235 + 1);
rng.fill(uv_reference_mat, RNG::UNIFORM, 16, 240 + 1);
y_reference_mat.copyTo(y_padded_mat(Rect(0, 0, y_reference_mat.cols, y_reference_mat.rows)));
uv_reference_mat.copyTo(uv_padded_mat(Rect(0, 0, uv_reference_mat.cols, uv_reference_mat.rows)));
Mat rgb_reference_mat, rgb_y_padded_mat, rgb_uv_padded_mat;
cvtColorTwoPlane(y_reference_mat, uv_reference_mat, rgb_reference_mat, COLOR_YUV2RGB_NV21);
cvtColorTwoPlane(y_padded_mat, uv_reference_mat, rgb_y_padded_mat, COLOR_YUV2RGB_NV21);
cvtColorTwoPlane(y_reference_mat, uv_padded_mat, rgb_uv_padded_mat, COLOR_YUV2RGB_NV21);
EXPECT_DOUBLE_EQ(cvtest::norm(rgb_reference_mat, rgb_y_padded_mat, NORM_INF), .0);
EXPECT_DOUBLE_EQ(cvtest::norm(rgb_reference_mat, rgb_uv_padded_mat, NORM_INF), .0);
}