Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit912d27a

Browse files
authored
Merge pull request#28180 from fengyuentau:rvv_hal/flip
rvv_hal: fix flip inplace#28180Fixes#28124### Pull Request Readiness ChecklistSee details athttps://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request- [x] I agree to contribute to the project under Apache 2 License.- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV- [x] The PR is proposed to the proper branch- [x] There is a reference to the original bug report and related work- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name.- [x] The feature is well documented and sample code can be built with the project CMake
1 parentf5d6fe5 commit912d27a

File tree

2 files changed

+78
-9
lines changed

2 files changed

+78
-9
lines changed

‎hal/riscv-rvv/src/core/flip.cpp‎

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,25 @@ CV_HAL_RVV_FLIP_C1(64UC1, uint64_t, RVV_U64M8)
4646
#defineCV_HAL_RVV_FLIP_INPLACE_C1(name, _Tps, RVV) \
4747
inlinevoid flip_inplace_##name(uchar* data,size_t step,int width,int height,int flip_mode) { \
4848
auto new_height = (flip_mode <0 ? height /2 : height); \
49-
auto new_width = width /2; \
50-
for (int h =0; h < new_height; h++) { \
49+
auto new_width = (flip_mode <0 ? width : width /2); \
50+
int h; \
51+
for (h =0; h < new_height; h++) { \
5152
_Tps* row_begin = (_Tps*)(data + step * h); \
52-
_Tps* row_end = (_Tps*)(data + step * (flip_mode <0 ? (new_height - h) : (h +1))); \
53+
_Tps* row_end = (_Tps*)(data + step * (flip_mode <0 ? (height - h) : (h +1))); \
54+
int vl; \
55+
for (int w =0; w < new_width; w += vl) { \
56+
vl =RVV::setvl(new_width - w); \
57+
RVV::VecType indices =__riscv_vrsub(RVV::vid(vl), vl -1, vl); \
58+
auto v_left =RVV::vload(row_begin + w, vl); \
59+
auto v_right =RVV::vload(row_end - w - vl, vl); \
60+
RVV::vstore(row_begin + w,__riscv_vrgather(v_right, indices, vl), vl); \
61+
RVV::vstore(row_end - w - vl,__riscv_vrgather(v_left, indices, vl), vl); \
62+
} \
63+
} \
64+
if (flip_mode == -1 && new_height *2 != height) { \
65+
_Tps* row_begin = (_Tps*)(data + step * h); \
66+
_Tps* row_end = (_Tps*)(data + step * (h +1)); \
67+
new_width /=2; \
5368
int vl; \
5469
for (int w =0; w < new_width; w += vl) { \
5570
vl =RVV::setvl(new_width - w); \
@@ -117,10 +132,27 @@ CV_HAL_RVV_FLIP_C3(64UC3, uint64_t, RVV_C3_U64M2)
117132
#defineCV_HAL_RVV_FLIP_INPLACE_C3(name, _Tps, RVV) \
118133
inlinevoid flip_inplace_##name(uchar* data,size_t step,int width,int height,int flip_mode) { \
119134
auto new_height = (flip_mode <0 ? height /2 : height); \
120-
auto new_width = width /2; \
121-
for (int h =0; h < new_height; h++) { \
135+
auto new_width = (flip_mode <0 ? width : width /2); \
136+
int h; \
137+
for (h =0; h < new_height; h++) { \
122138
_Tps* row_begin = (_Tps*)(data + step * h); \
123-
_Tps* row_end = (_Tps*)(data + step * (flip_mode <0 ? (new_height - h) : (h +1))); \
139+
_Tps* row_end = (_Tps*)(data + step * (flip_mode <0 ? (height - h) : (h +1))); \
140+
int vl; \
141+
for (int w =0; w < new_width; w += vl) { \
142+
vl =RVV::setvl(new_width - w); \
143+
RVV::VecType indices =__riscv_vrsub(RVV::vid(vl), vl -1, vl); \
144+
auto v_left =RVV::vload3(row_begin +3 * w, vl); \
145+
auto flipped_left =RVV::vflip3(v_left, indices, vl); \
146+
auto v_right =RVV::vload3(row_end -3 * (w + vl), vl); \
147+
auto flipped_right =RVV::vflip3(v_right, indices, vl); \
148+
RVV::vstore3(row_begin +3 * w, flipped_right, vl); \
149+
RVV::vstore3(row_end -3 * (w + vl), flipped_left, vl); \
150+
} \
151+
} \
152+
if (flip_mode == -1 && new_height *2 != height) { \
153+
_Tps* row_begin = (_Tps*)(data + step * h); \
154+
_Tps* row_end = (_Tps*)(data + step * (h +1)); \
155+
new_width /=2; \
124156
int vl; \
125157
for (int w =0; w < new_width; w += vl) { \
126158
vl =RVV::setvl(new_width - w); \
@@ -322,10 +354,8 @@ int flip(int src_type, const uchar* src_data, size_t src_step, int src_width, in
322354
if (src_width <0 || src_height <0 || esz >32)
323355
return CV_HAL_ERROR_NOT_IMPLEMENTED;
324356

325-
// BUG: https://github.com/opencv/opencv/issues/28124
326357
if (src_data == dst_data) {
327-
return CV_HAL_ERROR_NOT_IMPLEMENTED;
328-
//return flip_inplace(esz, dst_data, dst_step, src_width, src_height, flip_mode);
358+
returnflip_inplace(esz, dst_data, dst_step, src_width, src_height, flip_mode);
329359
}
330360

331361
if (flip_mode ==0)

‎modules/core/test/test_arithm.cpp‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,14 @@ static void flip(const Mat& src, Mat& dst, int flipcode)
878878
}
879879
}
880880

881+
staticvoidflip_inplace(Mat& dst,int flipcode)
882+
{
883+
Mat m;
884+
m.create(dst.size(), dst.type());
885+
reference::flip(dst, m, flipcode);
886+
memcpy(dst.ptr<uchar>(), m.ptr<uchar>(), dst.total() * dst.elemSize());
887+
}
888+
881889
staticvoidrotate(const Mat& src, Mat& dst,int rotateMode)
882890
{
883891
Mat tmp;
@@ -944,6 +952,36 @@ struct FlipOp : public BaseElemWiseOp
944952
int flipcode;
945953
};
946954

955+
structFlipInplaceOp :publicBaseElemWiseOp
956+
{
957+
FlipInplaceOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA,1,1, Scalar::all(0)) { flipcode =0; }
958+
voidgetRandomSize(RNG& rng, vector<int>& size)
959+
{
960+
cvtest::randomSize(rng,2,2, ARITHM_MAX_SIZE_LOG, size);
961+
}
962+
voidop(const vector<Mat>& src, Mat& dst,const Mat&)
963+
{
964+
dst.create(src[0].size(), src[0].type());
965+
memcpy(dst.ptr<uchar>(), src[0].ptr<uchar>(), src[0].total() * src[0].elemSize());
966+
cv::flip(dst, dst, flipcode);
967+
}
968+
voidrefop(const vector<Mat>& src, Mat& dst,const Mat&)
969+
{
970+
dst.create(src[0].size(), src[0].type());
971+
memcpy(dst.ptr<uchar>(), src[0].ptr<uchar>(), src[0].total() * src[0].elemSize());
972+
reference::flip_inplace(dst, flipcode);
973+
}
974+
voidgenerateScalars(int, RNG& rng)
975+
{
976+
flipcode = rng.uniform(0,3) -1;
977+
}
978+
doublegetMaxErr(int)
979+
{
980+
return0;
981+
}
982+
int flipcode;
983+
};
984+
947985
structRotateOp :publicBaseElemWiseOp
948986
{
949987
RotateOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA,1,1, Scalar::all(0)) { rotatecode =0; }
@@ -1622,6 +1660,7 @@ INSTANTIATE_TEST_CASE_P(Core_InRangeS, ElemWiseTest, ::testing::Values(ElemWiseO
16221660
INSTANTIATE_TEST_CASE_P(Core_InRange, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new InRangeOp)));
16231661

16241662
INSTANTIATE_TEST_CASE_P(Core_Flip, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new FlipOp)));
1663+
INSTANTIATE_TEST_CASE_P(Core_FlipInplace, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new FlipInplaceOp)));
16251664
INSTANTIATE_TEST_CASE_P(Core_Rotate, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new RotateOp)));
16261665
INSTANTIATE_TEST_CASE_P(Core_Transpose, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new TransposeOp)));
16271666
INSTANTIATE_TEST_CASE_P(Core_SetIdentity, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new SetIdentityOp)));

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp