Skip to content

Commit e3165a9

Browse files
authored
Merge pull request #3924 from CodeLinaro:integrateYUV_fastcv_extn
Fastcv extn for integrate YUV(YCbCr) image and bug fix in split extn
2 parents 43a4786 + 8e491e1 commit e3165a9

File tree

5 files changed

+108
-1
lines changed

5 files changed

+108
-1
lines changed

modules/fastcv/include/opencv2/fastcv/arithm.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,24 @@ CV_EXPORTS_W void gemm(InputArray src1, InputArray src2, OutputArray dst, float
6565

6666
//! @}
6767

68+
//! @addtogroup fastcv
69+
//! @{
70+
71+
/**
72+
* @brief Integral of a YCbCr420 image.
73+
* Note: Input height should be multiple of 2. Input width and stride should be multiple of 16.
74+
* Output stride should be multiple of 8.
75+
* It is optimized for Qualcomm's processors
76+
* @param Y Input Y component of 8UC1 YCbCr420 image.
77+
* @param CbCr Input CbCr component(interleaved) of 8UC1 YCbCr420 image.
78+
* @param IY Output Y integral of CV_32S one channel, size (Y height + 1)*(Y width + 1)
79+
* @param ICb Output Cb integral of CV_32S one channel, size (Y height/2 + 1)*(Y width/2 + 1)
80+
* @param ICr Output Cr integral of CV_32S one channel, size (Y height/2 + 1)*(Y width/2 + 1)
81+
*/
82+
CV_EXPORTS_W void integrateYUV(InputArray Y, InputArray CbCr, OutputArray IY, OutputArray ICb, OutputArray ICr);
83+
84+
//! @}
85+
6886
} // fastcv::
6987
} // cv::
7088

modules/fastcv/perf/perf_arithm.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include "perf_precomp.hpp"
7+
8+
namespace opencv_test {
9+
10+
typedef perf::TestBaseWithParam<tuple<Size, int>> IntegrateYUVPerfTest;
11+
12+
PERF_TEST_P(IntegrateYUVPerfTest, run,
13+
::testing::Combine(::testing::Values(perf::szVGA, perf::sz720p, perf::sz1080p), // image size
14+
::testing::Values(CV_8U) // image depth
15+
)
16+
)
17+
{
18+
cv::Size srcSize = get<0>(GetParam());
19+
int depth = get<1>(GetParam());
20+
21+
cv::Mat Y(srcSize, depth), CbCr(srcSize.height/2, srcSize.width, depth);
22+
cv::Mat IY, ICb, ICr;
23+
RNG& rng = cv::theRNG();
24+
cvtest::randUni(rng, Y, Scalar::all(0), Scalar::all(255));
25+
cvtest::randUni(rng, CbCr, Scalar::all(0), Scalar::all(255));
26+
27+
TEST_CYCLE() cv::fastcv::integrateYUV(Y, CbCr, IY, ICb, ICr);
28+
29+
SANITY_CHECK_NOTHING();
30+
}
31+
32+
} // namespace

modules/fastcv/src/arithm.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,5 +180,29 @@ void gemm(InputArray _src1, InputArray _src2, OutputArray _dst, float alpha, Inp
180180
}
181181
}
182182

183+
void integrateYUV(InputArray _Y, InputArray _CbCr, OutputArray _IY, OutputArray _ICb, OutputArray _ICr)
184+
{
185+
CV_Assert(!_Y.empty() && !_CbCr.empty());
186+
CV_Assert(_Y.type() == _CbCr.type() && _Y.type() == CV_8UC1);
187+
Mat Y = _Y.getMat();
188+
Mat CbCr = _CbCr.getMat();
189+
int Ywidth = Y.cols;
190+
int Yheight = Y.rows;
191+
192+
INITIALIZATION_CHECK;
193+
194+
_IY.create(Yheight + 1, Ywidth + 1, CV_32SC1);
195+
_ICb.create(Yheight/2 + 1, Ywidth/2 + 1, CV_32SC1);
196+
_ICr.create(Yheight/2 + 1, Ywidth/2 + 1, CV_32SC1);
197+
198+
Mat IY_ = _IY.getMat();
199+
Mat ICb_ = _ICb.getMat();
200+
Mat ICr_ = _ICr.getMat();
201+
202+
fcvIntegrateImageYCbCr420PseudoPlanaru8(Y.data, CbCr.data, Ywidth, Yheight, Y.step[0],
203+
CbCr.step[0], (uint32_t*)IY_.data, (uint32_t*)ICb_.data, (uint32_t*)ICr_.data,
204+
IY_.step[0], ICb_.step[0], ICr_.step[0]);
205+
}
206+
183207
} // fastcv::
184208
} // cv::

modules/fastcv/src/channel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ void split(InputArray _src, OutputArrayOfArrays _mv)
8686

8787
CV_Assert(depth == CV_8U && (cn == 2 || cn == 3 || cn == 4));
8888
CV_Assert(src.dims <= 2);
89-
89+
_mv.create(cn, 1, depth);
9090
for( int k = 0; k < cn; k++ )
9191
{
9292
_mv.create(src.dims, src.size, depth, k);

modules/fastcv/test/test_arithm.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,36 @@ TEST_P(ArithmOpTest, accuracy)
7979
EXPECT_EQ(normL2, 0);
8080
}
8181

82+
typedef testing::TestWithParam<tuple<Size>> IntegrateYUVTest;
83+
84+
TEST_P(IntegrateYUVTest, accuracy)
85+
{
86+
auto p = GetParam();
87+
Size srcSize = std::get<0>(p);
88+
int depth = CV_8U;
89+
90+
cv::Mat Y(srcSize, depth), CbCr(srcSize.height/2, srcSize.width, depth);
91+
cv::Mat IY, ICb, ICr;
92+
RNG& rng = cv::theRNG();
93+
cvtest::randUni(rng, Y, Scalar::all(0), Scalar::all(255));
94+
cvtest::randUni(rng, CbCr, Scalar::all(0), Scalar::all(255));
95+
96+
cv::fastcv::integrateYUV(Y, CbCr, IY, ICb, ICr);
97+
98+
CbCr = CbCr.reshape(2,0);
99+
std::vector<cv::Mat> ref;
100+
cv::fastcv::split(CbCr, ref);
101+
102+
cv::Mat IY_ref, ICb_ref, ICr_ref;
103+
cv::integral(Y,IY_ref,CV_32S);
104+
cv::integral(ref[0],ICb_ref,CV_32S);
105+
cv::integral(ref[1],ICr_ref,CV_32S);
106+
107+
EXPECT_EQ(IY_ref.at<int>(IY_ref.rows - 1, IY_ref.cols - 1), IY.at<int>(IY.rows - 1, IY.cols - 1));
108+
EXPECT_EQ(ICb_ref.at<int>(ICb_ref.rows - 1, ICb_ref.cols - 1), ICb.at<int>(ICb.rows - 1, ICb.cols - 1));
109+
EXPECT_EQ(ICr_ref.at<int>(ICr_ref.rows - 1, ICr_ref.cols - 1), ICr.at<int>(ICr.rows - 1, ICr.cols - 1));
110+
}
111+
82112
INSTANTIATE_TEST_CASE_P(FastCV_Extension, MatMulTest,
83113
::testing::Combine(::testing::Values(8, 16, 128, 256), // rows1
84114
::testing::Values(8, 16, 128, 256), // cols1
@@ -89,4 +119,7 @@ INSTANTIATE_TEST_CASE_P(FastCV_Extension, ArithmOpTest,
89119
::testing::Values(CV_8U, CV_16S), // depth
90120
::testing::Values(0,1))); // op type
91121

122+
INSTANTIATE_TEST_CASE_P(FastCV_Extension, IntegrateYUVTest,
123+
Values(perf::szVGA, perf::sz720p, perf::sz1080p)); // sz
124+
92125
}} // namespaces opencv_test, ::

0 commit comments

Comments
 (0)