diff --git a/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/image_process.cc b/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/image_process.cc index b6cca3332e..081d7f2122 100644 --- a/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/image_process.cc +++ b/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/image_process.cc @@ -20,6 +20,7 @@ #include #include #include +#include namespace mindspore { namespace dataset { @@ -868,5 +869,87 @@ bool Affine(LiteMat &src, LiteMat &out_img, double M[6], std::vector dsi return ImplementAffine(src, out_img, M, dsize, borderValue); } +template +inline void SubtractImpl(const T *src1_ptr, const T *src2_ptr, T *dst, size_t total_size) { + for (size_t i = 0; i < total_size; i++) { + dst[i] = src1_ptr[i] - src2_ptr[i]; + } +} + +template <> +inline void SubtractImpl(const uint8_t *src1_ptr, const uint8_t *src2_ptr, uint8_t *dst, size_t total_size) { + for (size_t i = 0; i < total_size; i++) { + int val = static_cast(src1_ptr[i]) - src2_ptr[i]; + dst[i] = + std::max(std::numeric_limits::min(), std::min(std::numeric_limits::max(), val)); + } +} + +template <> +inline void SubtractImpl(const uint16_t *src1_ptr, const uint16_t *src2_ptr, uint16_t *dst, size_t total_size) { + for (size_t i = 0; i < total_size; i++) { + int val = static_cast(src1_ptr[i]) - src2_ptr[i]; + dst[i] = + std::max(std::numeric_limits::min(), std::min(std::numeric_limits::max(), val)); + } +} + +template <> +inline void SubtractImpl(const uint32_t *src1_ptr, const uint32_t *src2_ptr, uint32_t *dst, size_t total_size) { + for (size_t i = 0; i < total_size; i++) { + int64_t val = static_cast(src1_ptr[i]) - src2_ptr[i]; + dst[i] = std::max(std::numeric_limits::min(), + std::min(std::numeric_limits::max(), val)); + } +} + +bool Subtract(const LiteMat &src1, const LiteMat &src2, LiteMat &dst) { + if (src1.width_ != src2.width_ || src1.height_ != src2.height_ || src1.channel_ != src2.channel_) { + return false; + } + + if (src1.data_type_ != src2.data_type_) { + return false; + } + + if (dst.IsEmpty()) { + dst.Init(src1.width_, src1.height_, src1.channel_, src1.data_type_); + } else if (src1.width_ != dst.width_ || src1.height_ != dst.height_ || src1.channel_ != dst.channel_) { + return false; + } else if (src1.data_type_ != dst.data_type_) { + return false; + } + + size_t total_size = src1.height_ * src1.width_ * src1.channel_; + + if (src1.data_type_ == LDataType::BOOL) { + SubtractImpl(src1, src2, dst, total_size); + } else if (src1.data_type_ == LDataType::INT8) { + SubtractImpl(src1, src2, dst, total_size); + } else if (src1.data_type_ == LDataType::UINT8) { + SubtractImpl(src1, src2, dst, total_size); + } else if (src1.data_type_ == LDataType::INT16) { + SubtractImpl(src1, src2, dst, total_size); + } else if (src1.data_type_ == LDataType::UINT16) { + SubtractImpl(src1, src2, dst, total_size); + } else if (src1.data_type_ == LDataType::INT32) { + SubtractImpl(src1, src2, dst, total_size); + } else if (src1.data_type_ == LDataType::UINT32) { + SubtractImpl(src1, src2, dst, total_size); + } else if (src1.data_type_ == LDataType::INT64) { + SubtractImpl(src1, src2, dst, total_size); + } else if (src1.data_type_ == LDataType::UINT64) { + SubtractImpl(src1, src2, dst, total_size); + } else if (src1.data_type_ == LDataType::FLOAT32) { + SubtractImpl(src1, src2, dst, total_size); + } else if (src1.data_type_ == LDataType::FLOAT64) { + SubtractImpl(src1, src2, dst, total_size); + } else { + return false; + } + + return true; +} + } // namespace dataset } // namespace mindspore diff --git a/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/image_process.h b/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/image_process.h index d1a3c39d11..1816fe837a 100644 --- a/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/image_process.h +++ b/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/image_process.h @@ -102,6 +102,9 @@ void ConvertBoxes(std::vector> &boxes, const std::vector ApplyNms(const std::vector> &all_boxes, std::vector &all_scores, float thres, int max_boxes); +/// \brief Calculates the difference between the two images for each element +bool Subtract(const LiteMat &src1, const LiteMat &src2, LiteMat &dst); + } // namespace dataset } // namespace mindspore #endif // IMAGE_PROCESS_H_ diff --git a/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/lite_mat.cc b/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/lite_mat.cc index cbd6517986..63f9ac5cbb 100644 --- a/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/lite_mat.cc +++ b/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/lite_mat.cc @@ -198,16 +198,10 @@ void *LiteMat::AlignMalloc(unsigned int size) { } return nullptr; } + void LiteMat::AlignFree(void *ptr) { (void)free(reinterpret_cast(ptr)[-1]); } -inline void LiteMat::InitElemSize(LDataType data_type) { - if (data_type == LDataType::UINT8) { - elem_size_ = 1; - } else if (data_type == LDataType::UINT16) { - elem_size_ = 2; - } else if (data_type == LDataType::FLOAT32) { - elem_size_ = 4; - } else { - } -} + +inline void LiteMat::InitElemSize(LDataType data_type) { elem_size_ = data_type.SizeInBytes(); } + } // namespace dataset } // namespace mindspore diff --git a/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/lite_mat.h b/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/lite_mat.h index 91f517ab25..ad6b278dc7 100644 --- a/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/lite_mat.h +++ b/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/lite_mat.h @@ -65,6 +65,16 @@ using INT8_C2 = Chn2; using INT8_C3 = Chn3; using INT8_C4 = Chn4; +using UINT16_C1 = Chn1; +using UINT16_C2 = Chn2; +using UINT16_C3 = Chn3; +using UINT16_C4 = Chn4; + +using INT16_C1 = Chn1; +using INT16_C2 = Chn2; +using INT16_C3 = Chn3; +using INT16_C4 = Chn4; + using UINT32_C1 = Chn1; using UINT32_C2 = Chn2; using UINT32_C3 = Chn3; diff --git a/tests/ut/cpp/dataset/image_process_test.cc b/tests/ut/cpp/dataset/image_process_test.cc index 9f92b67812..32859e87e2 100644 --- a/tests/ut/cpp/dataset/image_process_test.cc +++ b/tests/ut/cpp/dataset/image_process_test.cc @@ -440,7 +440,6 @@ TEST_F(MindDataImageProcess, TestAffine) { for (size_t i = 0; i < 6; i++) { M[i] = rotate_matrix.at(i); } - std::cout << std::endl; LiteMat dst; EXPECT_TRUE(Affine(src, dst, M, {rows, cols}, UINT8_C1(0))); @@ -451,3 +450,136 @@ TEST_F(MindDataImageProcess, TestAffine) { } } } + +TEST_F(MindDataImageProcess, TestSubtractUint8) { + const size_t cols = 4; + // Test uint8 + LiteMat src1_uint8(1, cols); + LiteMat src2_uint8(1, cols); + LiteMat expect_uint8(1, cols); + for (size_t i = 0; i < cols; i++) { + static_cast(src1_uint8.data_ptr_)[i] = 3; + static_cast(src2_uint8.data_ptr_)[i] = 2; + static_cast(expect_uint8.data_ptr_)[i] = 1; + } + LiteMat dst_uint8; + EXPECT_TRUE(Subtract(src1_uint8, src2_uint8, dst_uint8)); + for (size_t i = 0; i < cols; i++) { + EXPECT_EQ(static_cast(expect_uint8.data_ptr_)[i].c1, + static_cast(dst_uint8.data_ptr_)[i].c1); + } +} + +TEST_F(MindDataImageProcess, TestSubtractInt8) { + const size_t cols = 4; + // Test int8 + LiteMat src1_int8(1, cols, LDataType(LDataType::INT8)); + LiteMat src2_int8(1, cols, LDataType(LDataType::INT8)); + LiteMat expect_int8(1, cols, LDataType(LDataType::INT8)); + for (size_t i = 0; i < cols; i++) { + static_cast(src1_int8.data_ptr_)[i] = 2; + static_cast(src2_int8.data_ptr_)[i] = 3; + static_cast(expect_int8.data_ptr_)[i] = -1; + } + LiteMat dst_int8; + EXPECT_TRUE(Subtract(src1_int8, src2_int8, dst_int8)); + for (size_t i = 0; i < cols; i++) { + EXPECT_EQ(static_cast(expect_int8.data_ptr_)[i].c1, + static_cast(dst_int8.data_ptr_)[i].c1); + } +} + +TEST_F(MindDataImageProcess, TestSubtractUInt16) { + const size_t cols = 4; + // Test uint16 + LiteMat src1_uint16(1, cols, LDataType(LDataType::UINT16)); + LiteMat src2_uint16(1, cols, LDataType(LDataType::UINT16)); + LiteMat expect_uint16(1, cols, LDataType(LDataType::UINT16)); + for (size_t i = 0; i < cols; i++) { + static_cast(src1_uint16.data_ptr_)[i] = 2; + static_cast(src2_uint16.data_ptr_)[i] = 3; + static_cast(expect_uint16.data_ptr_)[i] = 0; + } + LiteMat dst_uint16; + EXPECT_TRUE(Subtract(src1_uint16, src2_uint16, dst_uint16)); + for (size_t i = 0; i < cols; i++) { + EXPECT_EQ(static_cast(expect_uint16.data_ptr_)[i].c1, + static_cast(dst_uint16.data_ptr_)[i].c1); + } +} + +TEST_F(MindDataImageProcess, TestSubtractInt16) { + const size_t cols = 4; + // Test int16 + LiteMat src1_int16(1, cols, LDataType(LDataType::INT16)); + LiteMat src2_int16(1, cols, LDataType(LDataType::INT16)); + LiteMat expect_int16(1, cols, LDataType(LDataType::INT16)); + for (size_t i = 0; i < cols; i++) { + static_cast(src1_int16.data_ptr_)[i] = 2; + static_cast(src2_int16.data_ptr_)[i] = 3; + static_cast(expect_int16.data_ptr_)[i] = -1; + } + LiteMat dst_int16; + EXPECT_TRUE(Subtract(src1_int16, src2_int16, dst_int16)); + for (size_t i = 0; i < cols; i++) { + EXPECT_EQ(static_cast(expect_int16.data_ptr_)[i].c1, + static_cast(dst_int16.data_ptr_)[i].c1); + } +} + +TEST_F(MindDataImageProcess, TestSubtractUInt32) { + const size_t cols = 4; + // Test uint16 + LiteMat src1_uint32(1, cols, LDataType(LDataType::UINT32)); + LiteMat src2_uint32(1, cols, LDataType(LDataType::UINT32)); + LiteMat expect_uint32(1, cols, LDataType(LDataType::UINT32)); + for (size_t i = 0; i < cols; i++) { + static_cast(src1_uint32.data_ptr_)[i] = 2; + static_cast(src2_uint32.data_ptr_)[i] = 3; + static_cast(expect_uint32.data_ptr_)[i] = 0; + } + LiteMat dst_uint32; + EXPECT_TRUE(Subtract(src1_uint32, src2_uint32, dst_uint32)); + for (size_t i = 0; i < cols; i++) { + EXPECT_EQ(static_cast(expect_uint32.data_ptr_)[i].c1, + static_cast(dst_uint32.data_ptr_)[i].c1); + } +} + +TEST_F(MindDataImageProcess, TestSubtractInt32) { + const size_t cols = 4; + // Test int32 + LiteMat src1_int32(1, cols, LDataType(LDataType::INT32)); + LiteMat src2_int32(1, cols, LDataType(LDataType::INT32)); + LiteMat expect_int32(1, cols, LDataType(LDataType::INT32)); + for (size_t i = 0; i < cols; i++) { + static_cast(src1_int32.data_ptr_)[i] = 2; + static_cast(src2_int32.data_ptr_)[i] = 4; + static_cast(expect_int32.data_ptr_)[i] = -2; + } + LiteMat dst_int32; + EXPECT_TRUE(Subtract(src1_int32, src2_int32, dst_int32)); + for (size_t i = 0; i < cols; i++) { + EXPECT_EQ(static_cast(expect_int32.data_ptr_)[i].c1, + static_cast(dst_int32.data_ptr_)[i].c1); + } +} + +TEST_F(MindDataImageProcess, TestSubtractFloat) { + const size_t cols = 4; + // Test float + LiteMat src1_float(1, cols, LDataType(LDataType::FLOAT32)); + LiteMat src2_float(1, cols, LDataType(LDataType::FLOAT32)); + LiteMat expect_float(1, cols, LDataType(LDataType::FLOAT32)); + for (size_t i = 0; i < cols; i++) { + static_cast(src1_float.data_ptr_)[i] = 3.4; + static_cast(src2_float.data_ptr_)[i] = 5.7; + static_cast(expect_float.data_ptr_)[i] = -2.3; + } + LiteMat dst_float; + EXPECT_TRUE(Subtract(src1_float, src2_float, dst_float)); + for (size_t i = 0; i < cols; i++) { + EXPECT_FLOAT_EQ(static_cast(expect_float.data_ptr_)[i].c1, + static_cast(dst_float.data_ptr_)[i].c1); + } +}