!7486 [MD] Add subtract image proccessing

Merge pull request !7486 from jiangzhiwen/lite/image_subtract
pull/7486/MERGE
mindspore-ci-bot 5 years ago committed by Gitee
commit 8ff82843ea

@ -20,6 +20,7 @@
#include <cmath>
#include <vector>
#include <algorithm>
#include <limits>
namespace mindspore {
namespace dataset {
@ -868,5 +869,87 @@ bool Affine(LiteMat &src, LiteMat &out_img, double M[6], std::vector<size_t> dsi
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 mindspore

@ -102,6 +102,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,
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_

@ -198,16 +198,10 @@ void *LiteMat::AlignMalloc(unsigned int size) {
}
return nullptr;
}
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 mindspore

@ -65,6 +65,16 @@ using INT8_C2 = Chn2<int8_t>;
using INT8_C3 = Chn3<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_C2 = Chn2<uint32_t>;
using UINT32_C3 = Chn3<uint32_t>;

@ -440,7 +440,6 @@ TEST_F(MindDataImageProcess, TestAffine) {
for (size_t i = 0; i < 6; i++) {
M[i] = rotate_matrix.at<double>(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<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);
}
}

Loading…
Cancel
Save