| @@ -20,6 +20,7 @@ | |||||
| #include <cmath> | #include <cmath> | ||||
| #include <vector> | #include <vector> | ||||
| #include <algorithm> | #include <algorithm> | ||||
| #include <limits> | |||||
| namespace mindspore { | namespace mindspore { | ||||
| namespace dataset { | namespace dataset { | ||||
| @@ -692,5 +693,87 @@ bool Affine(LiteMat &src, LiteMat &out_img, double M[6], std::vector<size_t> dsi | |||||
| return ImplementAffine(src, out_img, M, dsize, borderValue); | return ImplementAffine(src, out_img, M, dsize, borderValue); | ||||
| } | } | ||||
| template <typename T> | |||||
| 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<int>(src1_ptr[i]) - src2_ptr[i]; | |||||
| dst[i] = | |||||
| std::max<int>(std::numeric_limits<uint8_t>::min(), std::min<int>(std::numeric_limits<uint8_t>::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<int>(src1_ptr[i]) - src2_ptr[i]; | |||||
| dst[i] = | |||||
| std::max<int>(std::numeric_limits<uint16_t>::min(), std::min<int>(std::numeric_limits<uint16_t>::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<int64_t>(src1_ptr[i]) - src2_ptr[i]; | |||||
| dst[i] = std::max<int64_t>(std::numeric_limits<uint32_t>::min(), | |||||
| std::min<int64_t>(std::numeric_limits<uint32_t>::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<bool>(src1, src2, dst, total_size); | |||||
| } else if (src1.data_type_ == LDataType::INT8) { | |||||
| SubtractImpl<int8_t>(src1, src2, dst, total_size); | |||||
| } else if (src1.data_type_ == LDataType::UINT8) { | |||||
| SubtractImpl<uint8_t>(src1, src2, dst, total_size); | |||||
| } else if (src1.data_type_ == LDataType::INT16) { | |||||
| SubtractImpl<int16_t>(src1, src2, dst, total_size); | |||||
| } else if (src1.data_type_ == LDataType::UINT16) { | |||||
| SubtractImpl<uint16_t>(src1, src2, dst, total_size); | |||||
| } else if (src1.data_type_ == LDataType::INT32) { | |||||
| SubtractImpl<int32_t>(src1, src2, dst, total_size); | |||||
| } else if (src1.data_type_ == LDataType::UINT32) { | |||||
| SubtractImpl<uint32_t>(src1, src2, dst, total_size); | |||||
| } else if (src1.data_type_ == LDataType::INT64) { | |||||
| SubtractImpl<int64_t>(src1, src2, dst, total_size); | |||||
| } else if (src1.data_type_ == LDataType::UINT64) { | |||||
| SubtractImpl<uint64_t>(src1, src2, dst, total_size); | |||||
| } else if (src1.data_type_ == LDataType::FLOAT32) { | |||||
| SubtractImpl<float>(src1, src2, dst, total_size); | |||||
| } else if (src1.data_type_ == LDataType::FLOAT64) { | |||||
| SubtractImpl<double>(src1, src2, dst, total_size); | |||||
| } else { | |||||
| return false; | |||||
| } | |||||
| return true; | |||||
| } | |||||
| } // namespace dataset | } // namespace dataset | ||||
| } // namespace mindspore | } // namespace mindspore | ||||
| @@ -87,6 +87,9 @@ void ConvertBoxes(std::vector<std::vector<float>> &boxes, const std::vector<std: | |||||
| std::vector<int> ApplyNms(const std::vector<std::vector<float>> &all_boxes, std::vector<float> &all_scores, float thres, | std::vector<int> ApplyNms(const std::vector<std::vector<float>> &all_boxes, std::vector<float> &all_scores, float thres, | ||||
| int max_boxes); | 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 dataset | ||||
| } // namespace mindspore | } // namespace mindspore | ||||
| #endif // IMAGE_PROCESS_H_ | #endif // IMAGE_PROCESS_H_ | ||||
| @@ -198,16 +198,10 @@ void *LiteMat::AlignMalloc(unsigned int size) { | |||||
| } | } | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| void LiteMat::AlignFree(void *ptr) { (void)free(reinterpret_cast<void **>(ptr)[-1]); } | void LiteMat::AlignFree(void *ptr) { (void)free(reinterpret_cast<void **>(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 dataset | ||||
| } // namespace mindspore | } // namespace mindspore | ||||
| @@ -65,6 +65,16 @@ using INT8_C2 = Chn2<int8_t>; | |||||
| using INT8_C3 = Chn3<int8_t>; | using INT8_C3 = Chn3<int8_t>; | ||||
| using INT8_C4 = Chn4<int8_t>; | using INT8_C4 = Chn4<int8_t>; | ||||
| using UINT16_C1 = Chn1<uint16_t>; | |||||
| using UINT16_C2 = Chn2<uint16_t>; | |||||
| using UINT16_C3 = Chn3<uint16_t>; | |||||
| using UINT16_C4 = Chn4<uint16_t>; | |||||
| using INT16_C1 = Chn1<int16_t>; | |||||
| using INT16_C2 = Chn2<int16_t>; | |||||
| using INT16_C3 = Chn3<int16_t>; | |||||
| using INT16_C4 = Chn4<int16_t>; | |||||
| using UINT32_C1 = Chn1<uint32_t>; | using UINT32_C1 = Chn1<uint32_t>; | ||||
| using UINT32_C2 = Chn2<uint32_t>; | using UINT32_C2 = Chn2<uint32_t>; | ||||
| using UINT32_C3 = Chn3<uint32_t>; | using UINT32_C3 = Chn3<uint32_t>; | ||||
| @@ -332,7 +332,6 @@ TEST_F(MindDataImageProcess, TestAffine) { | |||||
| for (size_t i = 0; i < 6; i++) { | for (size_t i = 0; i < 6; i++) { | ||||
| M[i] = rotate_matrix.at<double>(i); | M[i] = rotate_matrix.at<double>(i); | ||||
| } | } | ||||
| std::cout << std::endl; | |||||
| LiteMat dst; | LiteMat dst; | ||||
| EXPECT_TRUE(Affine(src, dst, M, {rows, cols}, UINT8_C1(0))); | EXPECT_TRUE(Affine(src, dst, M, {rows, cols}, UINT8_C1(0))); | ||||
| @@ -343,3 +342,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<UINT8_C1 *>(src1_uint8.data_ptr_)[i] = 3; | |||||
| static_cast<UINT8_C1 *>(src2_uint8.data_ptr_)[i] = 2; | |||||
| static_cast<UINT8_C1 *>(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<UINT8_C1 *>(expect_uint8.data_ptr_)[i].c1, | |||||
| static_cast<UINT8_C1 *>(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<INT8_C1 *>(src1_int8.data_ptr_)[i] = 2; | |||||
| static_cast<INT8_C1 *>(src2_int8.data_ptr_)[i] = 3; | |||||
| static_cast<INT8_C1 *>(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<INT8_C1 *>(expect_int8.data_ptr_)[i].c1, | |||||
| static_cast<INT8_C1 *>(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<UINT16_C1 *>(src1_uint16.data_ptr_)[i] = 2; | |||||
| static_cast<UINT16_C1 *>(src2_uint16.data_ptr_)[i] = 3; | |||||
| static_cast<UINT16_C1 *>(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<UINT16_C1 *>(expect_uint16.data_ptr_)[i].c1, | |||||
| static_cast<UINT16_C1 *>(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<INT16_C1 *>(src1_int16.data_ptr_)[i] = 2; | |||||
| static_cast<INT16_C1 *>(src2_int16.data_ptr_)[i] = 3; | |||||
| static_cast<INT16_C1 *>(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<INT16_C1 *>(expect_int16.data_ptr_)[i].c1, | |||||
| static_cast<INT16_C1 *>(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<UINT32_C1 *>(src1_uint32.data_ptr_)[i] = 2; | |||||
| static_cast<UINT32_C1 *>(src2_uint32.data_ptr_)[i] = 3; | |||||
| static_cast<UINT32_C1 *>(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<UINT32_C1 *>(expect_uint32.data_ptr_)[i].c1, | |||||
| static_cast<UINT32_C1 *>(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<INT32_C1 *>(src1_int32.data_ptr_)[i] = 2; | |||||
| static_cast<INT32_C1 *>(src2_int32.data_ptr_)[i] = 4; | |||||
| static_cast<INT32_C1 *>(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<INT32_C1 *>(expect_int32.data_ptr_)[i].c1, | |||||
| static_cast<INT32_C1 *>(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<FLOAT32_C1 *>(src1_float.data_ptr_)[i] = 3.4; | |||||
| static_cast<FLOAT32_C1 *>(src2_float.data_ptr_)[i] = 5.7; | |||||
| static_cast<FLOAT32_C1 *>(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<FLOAT32_C1 *>(expect_float.data_ptr_)[i].c1, | |||||
| static_cast<FLOAT32_C1 *>(dst_float.data_ptr_)[i].c1); | |||||
| } | |||||
| } | |||||