From: @xulei2020 Reviewed-by: Signed-off-by:tags/v1.2.0-rc1
| @@ -2,4 +2,5 @@ file(GLOB_RECURSE _CURRENT_SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cc" | |||
| set_property(SOURCE ${_CURRENT_SRC_FILES} PROPERTY COMPILE_DEFINITIONS SUBMODULE_ID=mindspore::SubModuleId::SM_MD) | |||
| add_library(lite-cv OBJECT | |||
| image_process.cc | |||
| warp_affine.cc | |||
| lite_mat.cc) | |||
| @@ -28,11 +28,34 @@ | |||
| #endif | |||
| #endif | |||
| namespace mindspore { | |||
| namespace dataset { | |||
| #ifdef PLATFORM_ARM64 | |||
| #define R2GRAY 9798 | |||
| #define G2GRAY 19235 | |||
| #define B2GRAY 3735 | |||
| #define GRAYSHIFT 15 | |||
| #define GRAYSHIFT_DELTA (1 << (GRAYSHIFT - 1)) | |||
| #else | |||
| #define R2GRAY 77 | |||
| #define G2GRAY 150 | |||
| #define B2GRAY 29 | |||
| #define GRAYSHIFT 8 | |||
| #endif | |||
| #define YSCALE 0x0101 | |||
| #define UTOB (-128) | |||
| #define UTOG 25 | |||
| #define VTOR (-102) | |||
| #define VTOG 52 | |||
| #define YTOG 18997 | |||
| #define YTOGB (-1160) | |||
| #define BTOB (UTOB * 128 + YTOGB) | |||
| #define BTOG (UTOG * 128 + VTOG * 128 + YTOGB) | |||
| #define BTOR (VTOR * 128 + YTOGB) | |||
| #define Equ(a, b) ((std::fabs((a) - (b)) < 1e-6)) | |||
| namespace mindspore { | |||
| namespace dataset { | |||
| static inline void InitBilinearWeight(int *data_ptr, int16_t *weight_ptr, double scale, int dst_length, int src_length, | |||
| int a) { | |||
| const int RESIZE_SCALE = 1 << 11; | |||
| @@ -374,6 +397,79 @@ static bool ConvertYUV420SPToBGR(const uint8_t *data, LDataType data_type, bool | |||
| return true; | |||
| } | |||
| #ifdef PLATFORM_ARM64 | |||
| static uint8x8_t RGBToGray(const uint16x8_t &r_value, const uint16x8_t &g_value, const uint16x8_t &b_value, | |||
| const uint16x4_t &r2y_value, const uint16x4_t &g2y_value, const uint16x4_t &b2y_value) { | |||
| uint32x4_t dst0_value = vmull_u16(vget_low_u16(g_value), g2y_value); | |||
| uint32x4_t dst1_value = vmull_u16(vget_high_u16(g_value), g2y_value); | |||
| dst0_value = vmlal_u16(dst0_value, vget_low_u16(r_value), r2y_value); | |||
| dst1_value = vmlal_u16(dst1_value, vget_high_u16(r_value), r2y_value); | |||
| dst0_value = vmlal_u16(dst0_value, vget_low_u16(b_value), b2y_value); | |||
| dst1_value = vmlal_u16(dst1_value, vget_high_u16(b_value), b2y_value); | |||
| uint8x8_t v_gray = vqmovn_u16(vcombine_u16(vrshrn_n_u32(dst0_value, GRAYSHIFT), vrshrn_n_u32(dst1_value, GRAYSHIFT))); | |||
| return v_gray; | |||
| } | |||
| static bool ConvertRGBAToGRAY_Neon(const uint8_t *srcBase, uint8_t *dstBase, int w, int h) { | |||
| const uint32_t r_to_gray = R2GRAY; | |||
| const uint32_t g_to_gray = G2GRAY; | |||
| const uint32_t b_to_gray = B2GRAY; | |||
| uint16x4_t r2y_value = vdup_n_u16(R2GRAY); | |||
| uint16x4_t g2y_value = vdup_n_u16(G2GRAY); | |||
| uint16x4_t b2y_value = vdup_n_u16(B2GRAY); | |||
| size_t w16b = w >= 15 ? w - 15 : 0; | |||
| size_t w8b = w >= 7 ? w - 7 : 0; | |||
| for (size_t i = 0; i < h; ++i) { | |||
| const uint8_t *src_ptr = srcBase + w * i * 4; | |||
| uint8_t *dst_ptr = dstBase + w * i * 4; | |||
| size_t src_j = 0u; | |||
| size_t dst_j = 0u; | |||
| for (; dst_j < w16b; src_j += 64, dst_j += 16) { | |||
| uint8x16x4_t src_value0 = vld4q_u8(src_ptr + src_j); | |||
| // 0 | |||
| uint16x8_t r_value = vmovl_u8(vget_low_u8(src_value0.val[0])); | |||
| uint16x8_t g_value = vmovl_u8(vget_low_u8(src_value0.val[1])); | |||
| uint16x8_t b_value = vmovl_u8(vget_low_u8(src_value0.val[2])); | |||
| uint8x8_t gray_value0 = RGBToGray(r_value, g_value, b_value, r2y_value, g2y_value, b2y_value); | |||
| r_value = vmovl_u8(vget_high_u8(src_value0.val[0])); | |||
| g_value = vmovl_u8(vget_high_u8(src_value0.val[1])); | |||
| b_value = vmovl_u8(vget_high_u8(src_value0.val[2])); | |||
| uint8x8_t gray_value1 = RGBToGray(r_value, g_value, b_value, r2y_value, g2y_value, b2y_value); | |||
| vst1q_u8(dst_ptr + dst_j, vcombine_u8(gray_value0, gray_value1)); | |||
| } | |||
| if (dst_j < w8b) { | |||
| uint8x8x4_t v_src = vld4_u8(src_ptr + src_j); | |||
| uint16x8_t r_value = vmovl_u8(v_src.val[0]); | |||
| uint16x8_t g_value = vmovl_u8(v_src.val[1]); | |||
| uint16x8_t b_value = vmovl_u8(v_src.val[2]); | |||
| uint8x8_t gray_value = RGBToGray(r_value, g_value, b_value, r2y_value, g2y_value, b2y_value); | |||
| vst1_u8(dst_ptr + dst_j, gray_value); | |||
| src_j += 32; | |||
| dst_j += 8; | |||
| } | |||
| for (; dst_j < w; src_j += 4, dst_j++) { | |||
| uint32_t val = src_ptr[src_j] * r_to_gray + src_ptr[src_j + 1] * g_to_gray + src_ptr[src_j + 2] * b_to_gray; | |||
| dst_ptr[dst_j] = U32TOU8CAST((val + GRAYSHIFT_DELTA) >> GRAYSHIFT); | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| #endif | |||
| static bool ConvertRGBAToGRAY(const unsigned char *data, LDataType data_type, int w, int h, LiteMat &mat) { | |||
| if (data_type == LDataType::UINT8) { | |||
| mat.Init(w, h, 1, LDataType::UINT8); | |||
| @@ -382,6 +478,9 @@ static bool ConvertRGBAToGRAY(const unsigned char *data, LDataType data_type, in | |||
| } | |||
| unsigned char *ptr = mat; | |||
| const unsigned char *data_ptr = data; | |||
| #ifdef PLATFORM_ARM64 | |||
| ConvertRGBAToGRAY_Neon(data_ptr, ptr, w, h); | |||
| #else | |||
| for (int y = 0; y < h; y++) { | |||
| for (int x = 0; x < w; x++) { | |||
| *ptr = (data_ptr[2] * B2GRAY + data_ptr[1] * G2GRAY + data_ptr[0] * R2GRAY) >> GRAYSHIFT; | |||
| @@ -389,6 +488,7 @@ static bool ConvertRGBAToGRAY(const unsigned char *data, LDataType data_type, in | |||
| data_ptr += 4; | |||
| } | |||
| } | |||
| #endif | |||
| } else { | |||
| return false; | |||
| } | |||
| @@ -30,22 +30,6 @@ namespace dataset { | |||
| #define INT16_CAST(X) \ | |||
| static_cast<int16_t>(::std::min(::std::max(static_cast<int>(X + (X >= 0.f ? 0.5f : -0.5f)), -32768), 32767)); | |||
| #define R2GRAY 77 | |||
| #define G2GRAY 150 | |||
| #define B2GRAY 29 | |||
| #define GRAYSHIFT 8 | |||
| #define YSCALE 0x0101 | |||
| #define UTOB (-128) | |||
| #define UTOG 25 | |||
| #define VTOR (-102) | |||
| #define VTOG 52 | |||
| #define YTOG 18997 | |||
| #define YTOGB (-1160) | |||
| #define BTOB (UTOB * 128 + YTOGB) | |||
| #define BTOG (UTOG * 128 + VTOG * 128 + YTOGB) | |||
| #define BTOR (VTOR * 128 + YTOGB) | |||
| enum PaddBorderType { PADD_BORDER_CONSTANT = 0, PADD_BORDER_REPLICATE = 1 }; | |||
| struct BoxesConfig { | |||
| @@ -107,6 +91,14 @@ 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 affine image by linear | |||
| bool WarpAffineBilinear(const LiteMat &src, LiteMat &dst, const LiteMat &M, int dst_w, int dst_h, | |||
| PaddBorderType borderType, std::vector<uint8_t> &borderValue); | |||
| /// \brief perspective image by linear | |||
| bool WarpPerspectiveBilinear(const LiteMat &src, LiteMat &dst, const LiteMat &M, int dst_w, int dst_h, | |||
| PaddBorderType borderType, std::vector<uint8_t> &borderValue); | |||
| } // namespace dataset | |||
| } // namespace mindspore | |||
| #endif // IMAGE_PROCESS_H_ | |||
| @@ -39,6 +39,7 @@ LiteMat::LiteMat() { | |||
| size_ = 0; | |||
| data_type_ = LDataType::UINT8; | |||
| ref_count_ = nullptr; | |||
| setSteps(0, 0, 0); | |||
| } | |||
| LiteMat::LiteMat(int width, LDataType data_type) { | |||
| @@ -52,6 +53,7 @@ LiteMat::LiteMat(int width, LDataType data_type) { | |||
| data_type_ = LDataType::UINT8; | |||
| ref_count_ = nullptr; | |||
| size_ = 0; | |||
| setSteps(0, 0, 0); | |||
| Init(width, data_type); | |||
| } | |||
| @@ -66,6 +68,7 @@ LiteMat::LiteMat(int width, int height, LDataType data_type) { | |||
| data_type_ = LDataType::UINT8; | |||
| ref_count_ = nullptr; | |||
| size_ = 0; | |||
| setSteps(0, 0, 0); | |||
| Init(width, height, data_type); | |||
| } | |||
| @@ -80,6 +83,7 @@ LiteMat::LiteMat(int width, int height, void *p_data, LDataType data_type) { | |||
| data_type_ = LDataType::UINT8; | |||
| ref_count_ = nullptr; | |||
| size_ = 0; | |||
| setSteps(0, 0, 0); | |||
| Init(width, height, p_data, data_type); | |||
| } | |||
| @@ -94,6 +98,7 @@ LiteMat::LiteMat(int width, int height, int channel, LDataType data_type) { | |||
| data_type_ = LDataType::UINT8; | |||
| ref_count_ = nullptr; | |||
| size_ = 0; | |||
| setSteps(0, 0, 0); | |||
| Init(width, height, channel, data_type); | |||
| } | |||
| @@ -108,6 +113,7 @@ LiteMat::LiteMat(int width, int height, int channel, void *p_data, LDataType dat | |||
| data_type_ = LDataType::UINT8; | |||
| ref_count_ = nullptr; | |||
| size_ = 0; | |||
| setSteps(0, 0, 0); | |||
| Init(width, height, channel, p_data, data_type); | |||
| } | |||
| @@ -130,11 +136,18 @@ LiteMat::LiteMat(const LiteMat &m) { | |||
| data_type_ = m.data_type_; | |||
| ref_count_ = m.ref_count_; | |||
| size_ = 0; | |||
| setSteps(m.steps_[0], m.steps_[1], m.steps_[2]); | |||
| if (ref_count_) { | |||
| addRef(ref_count_, 1); | |||
| } | |||
| } | |||
| void LiteMat::setSteps(int c0, int c1, int c2) { | |||
| steps_[0] = c0; | |||
| steps_[1] = c1; | |||
| steps_[2] = c2; | |||
| } | |||
| LiteMat &LiteMat::operator=(const LiteMat &m) { | |||
| if (this == &m) { | |||
| return *this; | |||
| @@ -154,7 +167,8 @@ LiteMat &LiteMat::operator=(const LiteMat &m) { | |||
| dims_ = m.dims_; | |||
| data_type_ = m.data_type_; | |||
| ref_count_ = m.ref_count_; | |||
| size_ = 0; | |||
| setSteps(m.steps_[0], m.steps_[1], m.steps_[2]); | |||
| size_ = m.size_; | |||
| return *this; | |||
| } | |||
| @@ -171,6 +185,7 @@ void LiteMat::Init(int width, LDataType data_type) { | |||
| data_ptr_ = AlignMalloc(size_); | |||
| ref_count_ = new int[1]; | |||
| *ref_count_ = 1; | |||
| steps_[0] = elem_size_; | |||
| } | |||
| void LiteMat::Init(int width, int height, LDataType data_type) { | |||
| @@ -186,6 +201,8 @@ void LiteMat::Init(int width, int height, LDataType data_type) { | |||
| data_ptr_ = AlignMalloc(size_); | |||
| ref_count_ = new int[1]; | |||
| *ref_count_ = 1; | |||
| steps_[1] = elem_size_; | |||
| steps_[0] = width_ * steps_[1]; | |||
| } | |||
| void LiteMat::Init(int width, int height, void *p_data, LDataType data_type) { | |||
| @@ -199,6 +216,8 @@ void LiteMat::Init(int width, int height, void *p_data, LDataType data_type) { | |||
| size_ = c_step_ * channel_ * elem_size_; | |||
| data_ptr_ = p_data; | |||
| ref_count_ = nullptr; | |||
| steps_[1] = elem_size_; | |||
| steps_[0] = width_ * steps_[1]; | |||
| } | |||
| void LiteMat::Init(int width, int height, int channel, LDataType data_type) { | |||
| @@ -214,6 +233,10 @@ void LiteMat::Init(int width, int height, int channel, LDataType data_type) { | |||
| data_ptr_ = AlignMalloc(size_); | |||
| ref_count_ = new int[1]; | |||
| *ref_count_ = 1; | |||
| steps_[2] = elem_size_; | |||
| steps_[1] = channel * steps_[2]; | |||
| steps_[0] = width_ * steps_[1]; | |||
| } | |||
| void LiteMat::Init(int width, int height, int channel, void *p_data, LDataType data_type) { | |||
| @@ -227,6 +250,9 @@ void LiteMat::Init(int width, int height, int channel, void *p_data, LDataType d | |||
| size_ = c_step_ * channel_ * elem_size_; | |||
| data_ptr_ = p_data; | |||
| ref_count_ = nullptr; | |||
| steps_[2] = elem_size_; | |||
| steps_[1] = channel * steps_[2]; | |||
| steps_[0] = width_ * steps_[1]; | |||
| } | |||
| bool LiteMat::IsEmpty() const { return data_ptr_ == nullptr || c_step_ * channel_ == 0; } | |||
| @@ -248,6 +274,7 @@ void LiteMat::Release() { | |||
| c_step_ = 0; | |||
| ref_count_ = 0; | |||
| size_ = 0; | |||
| setSteps(0, 0, 0); | |||
| } | |||
| void *LiteMat::AlignMalloc(unsigned int size) { | |||
| @@ -271,6 +298,31 @@ void LiteMat::AlignFree(void *ptr) { | |||
| inline void LiteMat::InitElemSize(LDataType data_type) { elem_size_ = data_type.SizeInBytes(); } | |||
| bool LiteMat::GetROI(int x, int y, int w, int h, LiteMat &m) { | |||
| if (x < 0 || y < 0 || x + w > width_ || h + y > height_) { | |||
| return false; | |||
| } | |||
| if (!m.IsEmpty()) { | |||
| m.Release(); | |||
| } | |||
| if (ref_count_) { | |||
| addRef(ref_count_, 1); | |||
| } | |||
| m.height_ = h; | |||
| m.width_ = w; | |||
| m.dims_ = dims_; | |||
| m.elem_size_ = elem_size_; | |||
| m.data_ptr_ = reinterpret_cast<uint8_t *>(data_ptr_) + y * steps_[0] + x * elem_size_ * channel_; | |||
| m.channel_ = channel_; | |||
| m.c_step_ = c_step_; | |||
| m.data_type_ = data_type_; | |||
| m.ref_count_ = ref_count_; | |||
| m.setSteps(steps_[0], steps_[1], steps_[2]); | |||
| return true; | |||
| } | |||
| template <typename T> | |||
| inline void SubtractImpl(const T *src0, const T *src1, T *dst, int64_t total_size) { | |||
| for (int64_t i = 0; i < total_size; i++) { | |||
| @@ -24,6 +24,7 @@ namespace mindspore { | |||
| namespace dataset { | |||
| #define ALIGN 16 | |||
| #define MAX_DIMS 3 | |||
| template <typename T> | |||
| struct Chn1 { | |||
| @@ -121,6 +122,8 @@ enum LPixelType { | |||
| NV122BGR = 7, | |||
| }; | |||
| enum WARP_BORDER_MODE { WARP_BORDER_MODE_CONSTANT }; | |||
| class LDataType { | |||
| public: | |||
| enum Type : uint8_t { | |||
| @@ -137,6 +140,7 @@ class LDataType { | |||
| FLOAT16, | |||
| FLOAT32, | |||
| FLOAT64, | |||
| DOUBLE, | |||
| NUM_OF_TYPES | |||
| }; | |||
| @@ -179,6 +183,7 @@ class LDataType { | |||
| 2, // FLOAT16 | |||
| 4, // FLOAT32 | |||
| 8, // FLOAT64 | |||
| 8, // DOUBLE | |||
| }; | |||
| Type type_; | |||
| @@ -213,6 +218,8 @@ class LiteMat { | |||
| void Init(int width, int height, int channel, void *p_data, LDataType data_type = LDataType::UINT8); | |||
| bool GetROI(int x, int y, int w, int h, LiteMat &dst); // NOLINT | |||
| bool IsEmpty() const; | |||
| void Release(); | |||
| @@ -229,6 +236,14 @@ class LiteMat { | |||
| return reinterpret_cast<const T *>(data_ptr_); | |||
| } | |||
| template <typename T> | |||
| inline T *ptr(int w) const { | |||
| if (IsEmpty()) { | |||
| return nullptr; | |||
| } | |||
| return reinterpret_cast<T *>(reinterpret_cast<unsigned char *>(data_ptr_) + steps_[0] * w); | |||
| } | |||
| private: | |||
| /// \brief apply for memory alignment | |||
| void *AlignMalloc(unsigned int size); | |||
| @@ -241,6 +256,8 @@ class LiteMat { | |||
| /// \brief add reference | |||
| int addRef(int *p, int value); | |||
| void setSteps(int c0, int c1, int c2); | |||
| public: | |||
| void *data_ptr_ = nullptr; | |||
| int elem_size_; | |||
| @@ -252,6 +269,7 @@ class LiteMat { | |||
| size_t size_; | |||
| LDataType data_type_; | |||
| int *ref_count_; | |||
| size_t steps_[MAX_DIMS]; | |||
| }; | |||
| /// \brief Calculates the difference between the two images for each element | |||
| @@ -0,0 +1,522 @@ | |||
| /** | |||
| * Copyright 2021 Huawei Technologies Co., Ltd | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| * you may not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #include <limits.h> | |||
| #include <math.h> | |||
| #include <vector> | |||
| #include "lite_cv/lite_mat.h" | |||
| #include "lite_cv/image_process.h" | |||
| #ifdef ENABLE_ANDROID | |||
| #if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || defined(_M_ARM64) | |||
| #define USE_NEON | |||
| #include <arm_neon.h> | |||
| #endif | |||
| #endif | |||
| #define BITS 5 | |||
| #define BITS1 15 | |||
| #define TAB_SZ (1 << BITS) | |||
| #define TAB_SZ2 (TAB_SZ * TAB_SZ) | |||
| #define U32TOU8CAST(value) ((uint8_t)std::min(value, (uint32_t)UCHAR_MAX)) | |||
| #define FLOATTOSHORT(value) (IntCastShort(round(value))) | |||
| #define REMAP_SCALE (1 << 15) | |||
| #define INTTOUCHAR(v) ((uint8_t)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0)) | |||
| #define SrcValue(y, x) (reinterpret_cast<double *>(src + y * 3))[x] | |||
| #define DstValue(y, x) (reinterpret_cast<double *>(dst + y * 3))[x] | |||
| namespace mindspore { | |||
| namespace dataset { | |||
| static int16_t BWBlock_i[TAB_SZ2][2][2]; | |||
| static double GetDet3(double *src) { | |||
| double a1 = SrcValue(0, 0) * (SrcValue(1, 1) * SrcValue(2, 2) - SrcValue(1, 2) * SrcValue(2, 1)); | |||
| double a2 = SrcValue(0, 1) * (SrcValue(1, 0) * SrcValue(2, 2) - SrcValue(1, 2) * SrcValue(2, 0)); | |||
| double a3 = SrcValue(0, 2) * (SrcValue(1, 0) * SrcValue(2, 1) - SrcValue(1, 1) * SrcValue(2, 0)); | |||
| return a1 - a2 + a3; | |||
| } | |||
| static int16_t IntCastShort(int value) { | |||
| return (int16_t)((unsigned)(value - SHRT_MIN) <= (unsigned)USHRT_MAX ? value : value > 0 ? SHRT_MAX : SHRT_MIN); | |||
| } | |||
| static void InitWBlockInter(float *wBlock, int wBlockSz) { | |||
| float scale = 1.f / wBlockSz; | |||
| for (int i = 0; i < wBlockSz; i++, wBlock += 2) { | |||
| float value = (i * scale); | |||
| wBlock[0] = 1.f - value; | |||
| wBlock[1] = value; | |||
| } | |||
| } | |||
| static const void *InitWBlock() { | |||
| static bool initWB = false; | |||
| int16_t *iWBlock = 0; | |||
| int ks = 2; | |||
| iWBlock = BWBlock_i[0][0]; | |||
| if (!initWB) { | |||
| float *_wblock = new float[8 * TAB_SZ]; | |||
| int i, j, h1, h2; | |||
| InitWBlockInter(_wblock, TAB_SZ); | |||
| for (i = 0; i < TAB_SZ; i++) { | |||
| for (j = 0; j < TAB_SZ; j++, iWBlock += ks * ks) { | |||
| int sum_i = 0; | |||
| for (h1 = 0; h1 < ks; h1++) { | |||
| float vy = _wblock[i * ks + h1]; | |||
| for (h2 = 0; h2 < ks; h2++) { | |||
| float v = vy * _wblock[j * ks + h2]; | |||
| sum_i += iWBlock[h1 * ks + h2] = FLOATTOSHORT(v * REMAP_SCALE); | |||
| } | |||
| } | |||
| if (sum_i != REMAP_SCALE) { | |||
| int df = sum_i - REMAP_SCALE; | |||
| int ks2 = 1; | |||
| int tk1 = ks2; | |||
| int tk2 = ks2; | |||
| int mtk1 = ks2; | |||
| int mtk2 = ks2; | |||
| for (h1 = ks2; h1 < ks2 + 2; h1++) { | |||
| for (h2 = ks2; h2 < ks2 + 2; h2++) { | |||
| if (iWBlock[h1 * ks + h2] < iWBlock[mtk1 * ks + mtk2]) { | |||
| mtk1 = h1, mtk2 = h2; | |||
| } else if (iWBlock[h1 * ks + h2] > iWBlock[tk1 * ks + tk2]) { | |||
| tk1 = h1, tk2 = h2; | |||
| } | |||
| } | |||
| } | |||
| if (df < 0) { | |||
| iWBlock[tk1 * ks + tk2] = (int16_t)(iWBlock[tk1 * ks + tk2] - df); | |||
| } else { | |||
| iWBlock[mtk1 * ks + mtk2] = (int16_t)(iWBlock[mtk1 * ks + mtk2] - df); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| iWBlock -= TAB_SZ2 * ks * ks; | |||
| delete[] _wblock; | |||
| initWB = true; | |||
| } | |||
| return (const void *)iWBlock; | |||
| } | |||
| static uint8_t CastToFixed(int v) { return INTTOUCHAR(((v + (1 << (BITS1 - 1))) >> BITS1)); } | |||
| static int BorderPolate(int value, int length, PaddBorderType borderType) { | |||
| if ((unsigned)value < (unsigned)length) { | |||
| return value; | |||
| } else if (borderType == 0) { | |||
| value = -1; | |||
| } | |||
| return value; | |||
| } | |||
| static void RemapBilinear(const LiteMat &_src, LiteMat &_dst, const LiteMat &_hw, const LiteMat &_fhw, // NOLINT | |||
| const void *_wblock, const PaddBorderType borderType, | |||
| const std::vector<uint8_t> &borderValue) { | |||
| const int cn = _src.channel_; | |||
| const int16_t *wblock = (const int16_t *)_wblock; | |||
| const uint8_t *src_ptr = _src.ptr<uint8_t>(0); | |||
| size_t src_step = _src.steps_[0]; | |||
| unsigned src_width = std::max(_src.width_ - 1, 0); | |||
| unsigned src_height = std::max(_src.height_ - 1, 0); | |||
| for (int dy = 0; dy < _dst.height_; dy++) { | |||
| uint8_t *dst_ptr = _dst.ptr<uint8_t>(dy); | |||
| const int16_t *HW = _hw.ptr<int16_t>(dy); | |||
| const uint16_t *FHW = _fhw.ptr<uint16_t>(dy); | |||
| int tt = 0; | |||
| bool prevLine = false; | |||
| for (int dx = 0; dx <= _dst.width_; dx++) { | |||
| bool curLine = | |||
| dx < _dst.width_ ? (unsigned)HW[dx * 2] < src_width && (unsigned)HW[dx * 2 + 1] < src_height : !prevLine; | |||
| if (curLine == prevLine) continue; | |||
| int H1 = dx; | |||
| dx = tt; | |||
| tt = H1; | |||
| prevLine = curLine; | |||
| if (!curLine) { | |||
| int length = 0; | |||
| dst_ptr += length * cn; | |||
| dx += length; | |||
| if (cn == 1) { | |||
| for (; dx < H1; dx++, dst_ptr++) { | |||
| int shx = HW[dx * 2]; | |||
| int shy = HW[dx * 2 + 1]; | |||
| const int16_t *w_ptr = wblock + FHW[dx] * 4; | |||
| const uint8_t *t_src_ptr = src_ptr + shy * src_step + shx; | |||
| *dst_ptr = | |||
| CastToFixed(reinterpret_cast<int>(t_src_ptr[0] * w_ptr[0] + t_src_ptr[1] * w_ptr[1] + | |||
| t_src_ptr[src_step] * w_ptr[2] + t_src_ptr[src_step + 1] * w_ptr[3])); | |||
| } | |||
| } else if (cn == 2) { | |||
| for (; dx < H1; dx++, dst_ptr += 2) { | |||
| int shx = HW[dx * 2]; | |||
| int shy = HW[dx * 2 + 1]; | |||
| const int16_t *w_ptr = wblock + FHW[dx] * 4; | |||
| const uint8_t *t_src_ptr = src_ptr + shy * src_step + shx * 2; | |||
| int v0 = t_src_ptr[0] * w_ptr[0] + t_src_ptr[2] * w_ptr[1] + t_src_ptr[src_step] * w_ptr[2] + | |||
| t_src_ptr[src_step + 2] * w_ptr[3]; | |||
| int v1 = t_src_ptr[1] * w_ptr[0] + t_src_ptr[3] * w_ptr[1] + t_src_ptr[src_step + 1] * w_ptr[2] + | |||
| t_src_ptr[src_step + 3] * w_ptr[3]; | |||
| dst_ptr[0] = CastToFixed(v0); | |||
| dst_ptr[1] = CastToFixed(v1); | |||
| } | |||
| } else if (cn == 3) { | |||
| for (; dx < H1; dx++, dst_ptr += 3) { | |||
| int shx = HW[dx * 2]; | |||
| int shy = HW[dx * 2 + 1]; | |||
| const int16_t *w_ptr = wblock + FHW[dx] * 4; | |||
| const uint8_t *t_src_ptr = src_ptr + shy * src_step + shx * 3; | |||
| int v0 = t_src_ptr[0] * w_ptr[0] + t_src_ptr[3] * w_ptr[1] + t_src_ptr[src_step] * w_ptr[2] + | |||
| t_src_ptr[src_step + 3] * w_ptr[3]; | |||
| int v1 = t_src_ptr[1] * w_ptr[0] + t_src_ptr[4] * w_ptr[1] + t_src_ptr[src_step + 1] * w_ptr[2] + | |||
| t_src_ptr[src_step + 4] * w_ptr[3]; | |||
| int v2 = t_src_ptr[2] * w_ptr[0] + t_src_ptr[5] * w_ptr[1] + t_src_ptr[src_step + 2] * w_ptr[2] + | |||
| t_src_ptr[src_step + 5] * w_ptr[3]; | |||
| dst_ptr[0] = CastToFixed(v0); | |||
| dst_ptr[1] = CastToFixed(v1); | |||
| dst_ptr[2] = CastToFixed(v2); | |||
| } | |||
| } else if (cn == 4) { | |||
| for (; dx < H1; dx++, dst_ptr += 4) { | |||
| int shx = HW[dx * 2]; | |||
| int shy = HW[dx * 2 + 1]; | |||
| const int16_t *w_ptr = wblock + FHW[dx] * 4; | |||
| const uint8_t *t_src_ptr = src_ptr + shy * src_step + shx * 4; | |||
| int v0 = t_src_ptr[0] * w_ptr[0] + t_src_ptr[4] * w_ptr[1] + t_src_ptr[src_step] * w_ptr[2] + | |||
| t_src_ptr[src_step + 4] * w_ptr[3]; | |||
| int v1 = t_src_ptr[1] * w_ptr[0] + t_src_ptr[5] * w_ptr[1] + t_src_ptr[src_step + 1] * w_ptr[2] + | |||
| t_src_ptr[src_step + 5] * w_ptr[3]; | |||
| dst_ptr[0] = CastToFixed(v0); | |||
| dst_ptr[1] = CastToFixed(v1); | |||
| v0 = t_src_ptr[2] * w_ptr[0] + t_src_ptr[6] * w_ptr[1] + t_src_ptr[src_step + 2] * w_ptr[2] + | |||
| t_src_ptr[src_step + 6] * w_ptr[3]; | |||
| v1 = t_src_ptr[3] * w_ptr[0] + t_src_ptr[7] * w_ptr[1] + t_src_ptr[src_step + 3] * w_ptr[2] + | |||
| t_src_ptr[src_step + 7] * w_ptr[3]; | |||
| dst_ptr[2] = CastToFixed(v0); | |||
| dst_ptr[3] = CastToFixed(v1); | |||
| } | |||
| } else { | |||
| for (; dx < H1; dx++, dst_ptr += cn) { | |||
| int shx = HW[dx * 2]; | |||
| int shy = HW[dx * 2 + 1]; | |||
| const int16_t *w_ptr = wblock + FHW[dx] * 4; | |||
| const uint8_t *t_src_ptr = src_ptr + shy * src_step + shx * cn; | |||
| for (int k = 0; k < cn; k++) { | |||
| int v0 = t_src_ptr[k] * w_ptr[0] + t_src_ptr[k + cn] * w_ptr[1] + t_src_ptr[src_step + k] * w_ptr[2] + | |||
| t_src_ptr[src_step + k + cn] * w_ptr[3]; | |||
| dst_ptr[k] = CastToFixed(v0); | |||
| } | |||
| } | |||
| } | |||
| } else { | |||
| if (cn == 1) { | |||
| for (; dx < H1; dx++, dst_ptr++) { | |||
| int shx = HW[dx * 2]; | |||
| int shy = HW[dx * 2 + 1]; | |||
| if (borderType == PADD_BORDER_CONSTANT && | |||
| (shx >= _src.width_ || shx + 1 < 0 || shy >= _src.height_ || shy + 1 < 0)) { | |||
| dst_ptr[0] = borderValue[0]; | |||
| } else { | |||
| int sv0; | |||
| int sv1; | |||
| int su0; | |||
| int su1; | |||
| const int16_t *w_ptr = wblock + FHW[dx] * 4; | |||
| sv0 = BorderPolate(shx, _src.width_, borderType); | |||
| sv1 = BorderPolate(shx + 1, _src.width_, borderType); | |||
| su0 = BorderPolate(shy, _src.height_, borderType); | |||
| su1 = BorderPolate(shy + 1, _src.height_, borderType); | |||
| uint8_t v0 = sv0 >= 0 && su0 >= 0 ? src_ptr[su0 * src_step + sv0] : borderValue[0]; | |||
| uint8_t v1 = sv1 >= 0 && su0 >= 0 ? src_ptr[su0 * src_step + sv1] : borderValue[0]; | |||
| uint8_t v2 = sv0 >= 0 && su1 >= 0 ? src_ptr[su1 * src_step + sv0] : borderValue[0]; | |||
| uint8_t v3 = sv1 >= 0 && su1 >= 0 ? src_ptr[su1 * src_step + sv1] : borderValue[0]; | |||
| dst_ptr[0] = | |||
| CastToFixed(reinterpret_cast<int>(v0 * w_ptr[0] + v1 * w_ptr[1] + v2 * w_ptr[2] + v3 * w_ptr[3])); | |||
| } | |||
| } | |||
| } else { | |||
| for (; dx < H1; dx++, dst_ptr += cn) { | |||
| int shx = HW[dx * 2]; | |||
| int shy = HW[dx * 2 + 1]; | |||
| if (borderType == PADD_BORDER_CONSTANT && | |||
| (shx >= _src.width_ || shx + 1 < 0 || shy >= _src.height_ || shy + 1 < 0)) { | |||
| for (int k = 0; k < cn; k++) dst_ptr[k] = borderValue[k]; | |||
| } else { | |||
| int sv0; | |||
| int sv1; | |||
| int su0; | |||
| int su1; | |||
| const int16_t *w_ptr = wblock + FHW[dx] * 4; | |||
| sv0 = BorderPolate(shx, _src.width_, borderType); | |||
| sv1 = BorderPolate(shx + 1, _src.width_, borderType); | |||
| su0 = BorderPolate(shy, _src.height_, borderType); | |||
| su1 = BorderPolate(shy + 1, _src.height_, borderType); | |||
| const uint8_t *v0 = sv0 >= 0 && su0 >= 0 ? src_ptr + su0 * src_step + sv0 * cn : &borderValue[0]; | |||
| const uint8_t *v1 = sv1 >= 0 && su0 >= 0 ? src_ptr + su0 * src_step + sv1 * cn : &borderValue[0]; | |||
| const uint8_t *v2 = sv0 >= 0 && su1 >= 0 ? src_ptr + su1 * src_step + sv0 * cn : &borderValue[0]; | |||
| const uint8_t *v3 = sv1 >= 0 && su1 >= 0 ? src_ptr + su1 * src_step + sv1 * cn : &borderValue[0]; | |||
| for (int k = 0; k < cn; k++) | |||
| dst_ptr[k] = CastToFixed( | |||
| reinterpret_cast<int>(v0[k] * w_ptr[0] + v1[k] * w_ptr[1] + v2[k] * w_ptr[2] + v3[k] * w_ptr[3])); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| static void Remap(const LiteMat &src, LiteMat &dst, LiteMat &map1, const LiteMat &map2, // NOLINT | |||
| const PaddBorderType borderType, const std::vector<uint8_t> &borderValue) { | |||
| int x, y, x1, y1; | |||
| const int buf_size = 1 << 14; | |||
| int dst_height = std::min(128, dst.height_); | |||
| int dst_width = std::min(buf_size / dst_height, dst.width_); | |||
| dst_height = std::min(buf_size / dst_width, dst.height_); | |||
| const void *wblock = InitWBlock(); | |||
| LiteMat _xyblock(dst_width, dst_height, 2, LDataType::INT16); | |||
| LiteMat _ablock(dst_width, dst_height, 1, LDataType::UINT16); | |||
| for (y = 0; y < dst.height_; y += dst_height) { | |||
| for (x = 0; x < dst.width_; x += dst_width) { | |||
| int bheight = std::min(dst_height, dst.height_ - y); | |||
| int bwidth = std::min(dst_width, dst.width_ - x); | |||
| LiteMat lite_part; | |||
| dst.GetROI(x, y, bwidth, bheight, lite_part); | |||
| LiteMat xy_ptr; | |||
| _xyblock.GetROI(0, 0, bwidth, bheight, xy_ptr); | |||
| LiteMat a_ptr; | |||
| _ablock.GetROI(0, 0, bwidth, bheight, a_ptr); | |||
| for (y1 = 0; y1 < bheight; y1++) { | |||
| uint16_t *t_a_ptr = a_ptr.ptr<uint16_t>(y1); | |||
| map1.GetROI(x, y, bwidth, bheight, xy_ptr); | |||
| const uint16_t *sa_ptr = map2.ptr<uint16_t>(y + y1) + x; | |||
| x1 = 0; | |||
| for (; x1 < bwidth; x1++) { | |||
| t_a_ptr[x1] = (uint16_t)(sa_ptr[x1] & (TAB_SZ2 - 1)); | |||
| } | |||
| } | |||
| RemapBilinear(src, lite_part, xy_ptr, a_ptr, wblock, borderType, borderValue); | |||
| } | |||
| } | |||
| } | |||
| bool WarpAffineBilinear(const LiteMat &src, LiteMat &dst, const LiteMat &M, int dst_w, int dst_h, // NOLINT | |||
| PaddBorderType borderType, std::vector<uint8_t> &borderValue) { // NOLINT | |||
| if (!(M.height_ == 2 && M.width_ == 3)) { | |||
| return false; | |||
| } | |||
| if (borderType != PADD_BORDER_CONSTANT) { | |||
| return false; | |||
| } | |||
| if (borderValue.size() != src.channel_) { | |||
| return false; | |||
| } | |||
| if (dst.IsEmpty()) { | |||
| (void)dst.Init(dst_w, dst_h, src.channel_, LDataType::UINT8); | |||
| } else if (dst.height_ != dst_h || dst.width_ != dst_w || dst.channel_ != src.channel_) { | |||
| return false; | |||
| } else if (dst.data_type_ != LDataType::UINT8) { | |||
| return false; | |||
| } else { | |||
| } | |||
| double IM[6]; | |||
| const double *M_Ptr = M; | |||
| for (int i = 0; i < 6; i++) { | |||
| IM[i] = M_Ptr[i]; | |||
| } | |||
| double D = IM[0] * IM[4] - IM[1] * IM[3]; | |||
| D = D != 0 ? 1.0f / D : 0; | |||
| double A11 = IM[4] * D, A22 = IM[0] * D; | |||
| IM[0] = A11; | |||
| IM[1] *= -D; | |||
| IM[3] *= -D; | |||
| IM[4] = A22; | |||
| double b1 = -IM[0] * IM[2] - IM[1] * IM[5]; | |||
| double b2 = -IM[3] * IM[2] - IM[4] * IM[5]; | |||
| IM[2] = b1; | |||
| IM[5] = b2; | |||
| int *_a = new int[dst.width_ * 2]; | |||
| int *a = &_a[0], *b = a + dst.width_; | |||
| const int SCALE = 1 << 10; | |||
| const int B_SIZE = 64; | |||
| int16_t WH[B_SIZE * B_SIZE * 2]; | |||
| int16_t A_Ptr[B_SIZE * B_SIZE]; | |||
| int r_delta = SCALE / TAB_SZ / 2; | |||
| int x, y, x1, y1; | |||
| for (x = 0; x < dst.width_; x++) { | |||
| a[x] = round(IM[0] * x * SCALE); | |||
| b[x] = round(IM[3] * x * SCALE); | |||
| } | |||
| int t_bh0 = std::min(B_SIZE / 2, dst.height_); | |||
| int t_bw0 = std::min(B_SIZE * B_SIZE / t_bh0, dst.width_); | |||
| t_bh0 = std::min(B_SIZE * B_SIZE / t_bw0, dst.height_); | |||
| for (y = 0; y < dst.height_; y += t_bh0) { | |||
| for (x = 0; x < dst.width_; x += t_bw0) { | |||
| int t_bw = std::min(t_bw0, dst.width_ - x); | |||
| int t_bh = std::min(t_bh0, dst.height_ - y); | |||
| LiteMat _HW(t_bw, t_bh, 2, WH, LDataType::INT16); | |||
| LiteMat lite_part; | |||
| dst.GetROI(x, y, t_bw, t_bh, lite_part); | |||
| for (y1 = 0; y1 < t_bh; y1++) { | |||
| int16_t *t_xy = WH + y1 * t_bw * 2; | |||
| int X0 = round((IM[1] * (y + y1) + IM[2]) * SCALE) + r_delta; | |||
| int Y0 = round((IM[4] * (y + y1) + IM[5]) * SCALE) + r_delta; | |||
| int16_t *t_a = A_Ptr + y1 * t_bw; | |||
| x1 = 0; | |||
| for (; x1 < t_bw; x1++) { | |||
| int X = (X0 + a[x + x1]) >> (10 - BITS); | |||
| int Y = (Y0 + b[x + x1]) >> (10 - BITS); | |||
| t_xy[x1 * 2] = IntCastShort(X >> BITS); | |||
| t_xy[x1 * 2 + 1] = IntCastShort(Y >> BITS); | |||
| t_a[x1] = (int16_t)((Y & (TAB_SZ - 1)) * TAB_SZ + (X & (TAB_SZ - 1))); | |||
| } | |||
| } | |||
| LiteMat _matA(t_bw, t_bh, 1, A_Ptr, LDataType::UINT16); | |||
| Remap(src, lite_part, _HW, _matA, borderType, borderValue); | |||
| } | |||
| } | |||
| delete[] _a; | |||
| return true; | |||
| } | |||
| static void PerspectiveInvert(double *src, double *dst) { | |||
| double value = GetDet3(src); | |||
| if (value != 0.) { | |||
| value = 1. / value; | |||
| double v[9]; | |||
| v[0] = (SrcValue(1, 1) * SrcValue(2, 2) - SrcValue(1, 2) * SrcValue(2, 1)) * value; | |||
| v[1] = (SrcValue(0, 2) * SrcValue(2, 1) - SrcValue(0, 1) * SrcValue(2, 2)) * value; | |||
| v[2] = (SrcValue(0, 1) * SrcValue(1, 2) - SrcValue(0, 2) * SrcValue(1, 1)) * value; | |||
| v[3] = (SrcValue(1, 2) * SrcValue(2, 0) - SrcValue(1, 0) * SrcValue(2, 2)) * value; | |||
| v[4] = (SrcValue(0, 0) * SrcValue(2, 2) - SrcValue(0, 2) * SrcValue(2, 0)) * value; | |||
| v[5] = (SrcValue(0, 2) * SrcValue(1, 0) - SrcValue(0, 0) * SrcValue(1, 2)) * value; | |||
| v[6] = (SrcValue(1, 0) * SrcValue(2, 1) - SrcValue(1, 1) * SrcValue(2, 0)) * value; | |||
| v[7] = (SrcValue(0, 1) * SrcValue(2, 0) - SrcValue(0, 0) * SrcValue(2, 1)) * value; | |||
| v[8] = (SrcValue(0, 0) * SrcValue(1, 1) - SrcValue(0, 1) * SrcValue(1, 0)) * value; | |||
| DstValue(0, 0) = v[0]; | |||
| DstValue(0, 1) = v[1]; | |||
| DstValue(0, 2) = v[2]; | |||
| DstValue(1, 0) = v[3]; | |||
| DstValue(1, 1) = v[4]; | |||
| DstValue(1, 2) = v[5]; | |||
| DstValue(2, 0) = v[6]; | |||
| DstValue(2, 1) = v[7]; | |||
| DstValue(2, 2) = v[8]; | |||
| } | |||
| } | |||
| bool WarpPerspectiveBilinear(const LiteMat &src, LiteMat &dst, const LiteMat &M, int dst_w, int dst_h, // NOLINT | |||
| PaddBorderType borderType, std::vector<uint8_t> &borderValue) { // NOLINT | |||
| if (!(M.height_ == 3 && M.width_ == 3)) { | |||
| return false; | |||
| } | |||
| if (borderType != PADD_BORDER_CONSTANT) { | |||
| return false; | |||
| } | |||
| if (borderValue.size() != src.channel_) { | |||
| return false; | |||
| } | |||
| if (dst.IsEmpty()) { | |||
| (void)dst.Init(dst_w, dst_h, src.channel_, LDataType::UINT8); | |||
| } else if (dst.height_ != dst_h || dst.width_ != dst_w || dst.channel_ != src.channel_) { | |||
| return false; | |||
| } else if (dst.data_type_ != LDataType::UINT8) { | |||
| return false; | |||
| } else { | |||
| } | |||
| double IM[9]; | |||
| const double *M_Ptr = M; | |||
| for (int i = 0; i < 9; i++) { | |||
| IM[i] = M_Ptr[i]; | |||
| } | |||
| PerspectiveInvert(IM, IM); | |||
| const int B_SZ = 32; | |||
| int16_t HW[B_SZ * B_SZ * 2]; | |||
| int16_t TA[B_SZ * B_SZ]; | |||
| int x; | |||
| int y; | |||
| int y1; | |||
| int width = dst.width_; | |||
| int height = dst.height_; | |||
| int bheight = std::min(B_SZ / 2, height); | |||
| int bwidth = std::min(B_SZ * B_SZ / bheight, width); | |||
| bheight = std::min(B_SZ * B_SZ / bwidth, height); | |||
| for (y = 0; y < dst.height_; y += bheight) { | |||
| for (x = 0; x < width; x += bwidth) { | |||
| int tw = std::min(bwidth, width - x); | |||
| int th = std::min(bheight, dst.height_ - y); | |||
| LiteMat _HW(tw, th, 2, HW, LDataType::INT16); | |||
| LiteMat lite_part; | |||
| dst.GetROI(x, y, tw, th, lite_part); | |||
| for (y1 = 0; y1 < th; y1++) { | |||
| int16_t *xy = HW + y1 * tw * 2; | |||
| double XV = IM[0] * x + IM[1] * (y + y1) + IM[2]; | |||
| double YV = IM[3] * x + IM[4] * (y + y1) + IM[5]; | |||
| double WV = IM[6] * x + IM[7] * (y + y1) + IM[8]; | |||
| int16_t *t_a = TA + y1 * tw; | |||
| for (int x1 = 0; x1 < tw; x1++) { | |||
| double W = WV + IM[6] * x1; | |||
| W = W ? TAB_SZ / W : 0; | |||
| double fX = std::max((double)INT_MIN, std::min((double)INT_MAX, (XV + IM[0] * x1) * W)); // NOLINT | |||
| double fY = std::max((double)INT_MIN, std::min((double)INT_MAX, (YV + IM[3] * x1) * W)); // NOLINT | |||
| int X = round(fX); | |||
| int Y = round(fY); | |||
| xy[x1 * 2] = IntCastShort(X >> BITS); | |||
| xy[x1 * 2 + 1] = IntCastShort(Y >> BITS); | |||
| t_a[x1] = (int16_t)((Y & (TAB_SZ - 1)) * TAB_SZ + (X & (TAB_SZ - 1))); | |||
| } | |||
| } | |||
| LiteMat _matA(tw, th, 1, TA, LDataType::UINT16); | |||
| Remap(src, lite_part, _HW, _matA, borderType, borderValue); | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| } // namespace dataset | |||
| } // namespace mindspore | |||
| @@ -886,4 +886,329 @@ TEST_F(MindDataImageProcess, TestExtractChannel) { | |||
| EXPECT_FALSE(ExtractChannel(lite_mat, lite_single, 0)); | |||
| EXPECT_TRUE(lite_single.IsEmpty()); | |||
| } | |||
| } | |||
| TEST_F(MindDataImageProcess, testROI3C) { | |||
| std::string filename = "data/dataset/apple.jpg"; | |||
| cv::Mat src_image = cv::imread(filename, cv::ImreadModes::IMREAD_COLOR); | |||
| cv::Mat cv_roi = cv::Mat(src_image, cv::Rect(500, 500, 3000, 1500)); | |||
| cv::imwrite("./cv_roi.jpg", cv_roi); | |||
| bool ret = false; | |||
| LiteMat lite_mat_bgr; | |||
| ret = InitFromPixel(src_image.data, LPixelType::BGR, LDataType::UINT8, src_image.cols, src_image.rows, lite_mat_bgr); | |||
| EXPECT_TRUE(ret); | |||
| LiteMat lite_roi; | |||
| ret = lite_mat_bgr.GetROI(500, 500, 3000, 1500, lite_roi); | |||
| EXPECT_TRUE(ret); | |||
| LiteMat lite_roi_save(3000, 1500, lite_roi.channel_, LDataType::UINT8); | |||
| for (size_t i = 0; i < lite_roi.height_; i++) { | |||
| const unsigned char *ptr = lite_roi.ptr<unsigned char>(i); | |||
| size_t image_size = lite_roi.width_ * lite_roi.channel_ * sizeof(unsigned char); | |||
| unsigned char *dst_ptr = (unsigned char *)lite_roi_save.data_ptr_ + image_size * i; | |||
| (void)memcpy(dst_ptr, ptr, image_size); | |||
| } | |||
| cv::Mat dst_imageR(lite_roi_save.height_, lite_roi_save.width_, CV_8UC3, lite_roi_save.data_ptr_); | |||
| cv::imwrite("./lite_roi.jpg", dst_imageR); | |||
| } | |||
| TEST_F(MindDataImageProcess, testROI1C) { | |||
| std::string filename = "data/dataset/apple.jpg"; | |||
| cv::Mat src_image = cv::imread(filename, cv::ImreadModes::IMREAD_COLOR); | |||
| cv::Mat gray_image; | |||
| cv::cvtColor(src_image, gray_image, CV_BGR2GRAY); | |||
| cv::Mat cv_roi_gray = cv::Mat(gray_image, cv::Rect(500, 500, 3000, 1500)); | |||
| cv::imwrite("./cv_roi_gray.jpg", cv_roi_gray); | |||
| cv::Mat rgba_mat; | |||
| cv::cvtColor(src_image, rgba_mat, CV_BGR2RGBA); | |||
| bool ret = false; | |||
| LiteMat lite_mat_gray; | |||
| ret = | |||
| InitFromPixel(rgba_mat.data, LPixelType::RGBA2GRAY, LDataType::UINT8, rgba_mat.cols, rgba_mat.rows, lite_mat_gray); | |||
| EXPECT_TRUE(ret); | |||
| LiteMat lite_roi_gray; | |||
| ret = lite_mat_gray.GetROI(500, 500, 3000, 1500, lite_roi_gray); | |||
| EXPECT_TRUE(ret); | |||
| LiteMat lite_roi_gray_save(3000, 1500, lite_roi_gray.channel_, LDataType::UINT8); | |||
| for (size_t i = 0; i < lite_roi_gray.height_; i++) { | |||
| const unsigned char *ptr = lite_roi_gray.ptr<unsigned char>(i); | |||
| size_t image_size = lite_roi_gray.width_ * lite_roi_gray.channel_ * sizeof(unsigned char); | |||
| unsigned char *dst_ptr = (unsigned char *)lite_roi_gray_save.data_ptr_ + image_size * i; | |||
| (void)memcpy(dst_ptr, ptr, image_size); | |||
| } | |||
| cv::Mat dst_imageR(lite_roi_gray_save.height_, lite_roi_gray_save.width_, CV_8UC1, lite_roi_gray_save.data_ptr_); | |||
| cv::imwrite("./lite_roi.jpg", dst_imageR); | |||
| } | |||
| //warp | |||
| TEST_F(MindDataImageProcess, testWarpAffineBGR) { | |||
| std::string filename = "data/dataset/apple.jpg"; | |||
| cv::Mat src_image = cv::imread(filename, cv::ImreadModes::IMREAD_COLOR); | |||
| cv::Point2f srcTri[3]; | |||
| cv::Point2f dstTri[3]; | |||
| srcTri[0] = cv::Point2f(0, 0); | |||
| srcTri[1] = cv::Point2f(src_image.cols - 1, 0); | |||
| srcTri[2] = cv::Point2f(0, src_image.rows - 1); | |||
| dstTri[0] = cv::Point2f(src_image.cols * 0.0, src_image.rows * 0.33); | |||
| dstTri[1] = cv::Point2f(src_image.cols * 0.85, src_image.rows * 0.25); | |||
| dstTri[2] = cv::Point2f(src_image.cols * 0.15, src_image.rows * 0.7); | |||
| cv::Mat warp_mat = cv::getAffineTransform(srcTri, dstTri); | |||
| ; | |||
| cv::Mat warp_dstImage; | |||
| cv::warpAffine(src_image, warp_dstImage, warp_mat, warp_dstImage.size()); | |||
| cv::imwrite("./warpAffine_cv_bgr.png", warp_dstImage); | |||
| bool ret = false; | |||
| LiteMat lite_mat_bgr; | |||
| ret = InitFromPixel(src_image.data, LPixelType::BGR, LDataType::UINT8, src_image.cols, src_image.rows, lite_mat_bgr); | |||
| EXPECT_TRUE(ret); | |||
| double *mat_ptr = warp_mat.ptr<double>(0); | |||
| LiteMat lite_M(3, 2, 1, mat_ptr, LDataType::DOUBLE); | |||
| LiteMat lite_warp; | |||
| std::vector<uint8_t> borderValues; | |||
| borderValues.push_back(0); | |||
| borderValues.push_back(0); | |||
| borderValues.push_back(0); | |||
| ret = WarpAffineBilinear(lite_mat_bgr, lite_warp, lite_M, lite_mat_bgr.width_, lite_mat_bgr.height_, PADD_BORDER_CONSTANT, borderValues); | |||
| EXPECT_TRUE(ret); | |||
| cv::Mat dst_imageR(lite_warp.height_, lite_warp.width_, CV_8UC3, lite_warp.data_ptr_); | |||
| cv::imwrite("./warpAffine_lite_bgr.png", dst_imageR); | |||
| } | |||
| TEST_F(MindDataImageProcess, testWarpAffineBGRScale) { | |||
| std::string filename = "data/dataset/apple.jpg"; | |||
| cv::Mat src_image = cv::imread(filename, cv::ImreadModes::IMREAD_COLOR); | |||
| cv::Point2f srcTri[3]; | |||
| cv::Point2f dstTri[3]; | |||
| srcTri[0] = cv::Point2f(10, 20); | |||
| srcTri[1] = cv::Point2f(src_image.cols - 1 - 100, 0); | |||
| srcTri[2] = cv::Point2f(0, src_image.rows - 1 - 300); | |||
| dstTri[0] = cv::Point2f(src_image.cols * 0.22, src_image.rows * 0.33); | |||
| dstTri[1] = cv::Point2f(src_image.cols * 0.87, src_image.rows * 0.75); | |||
| dstTri[2] = cv::Point2f(src_image.cols * 0.35, src_image.rows * 0.37); | |||
| cv::Mat warp_mat = cv::getAffineTransform(srcTri, dstTri); | |||
| ; | |||
| cv::Mat warp_dstImage; | |||
| cv::warpAffine(src_image, warp_dstImage, warp_mat, warp_dstImage.size()); | |||
| cv::imwrite("./warpAffine_cv_bgr_scale.png", warp_dstImage); | |||
| bool ret = false; | |||
| LiteMat lite_mat_bgr; | |||
| ret = InitFromPixel(src_image.data, LPixelType::BGR, LDataType::UINT8, src_image.cols, src_image.rows, lite_mat_bgr); | |||
| EXPECT_TRUE(ret); | |||
| double *mat_ptr = warp_mat.ptr<double>(0); | |||
| LiteMat lite_M(3, 2, 1, mat_ptr, LDataType::DOUBLE); | |||
| LiteMat lite_warp; | |||
| std::vector<uint8_t> borderValues; | |||
| borderValues.push_back(0); | |||
| borderValues.push_back(0); | |||
| borderValues.push_back(0); | |||
| ret = WarpAffineBilinear(lite_mat_bgr, lite_warp, lite_M, lite_mat_bgr.width_, lite_mat_bgr.height_, PADD_BORDER_CONSTANT, borderValues); | |||
| EXPECT_TRUE(ret); | |||
| cv::Mat dst_imageR(lite_warp.height_, lite_warp.width_, CV_8UC3, lite_warp.data_ptr_); | |||
| cv::imwrite("./warpAffine_lite_bgr_scale.png", dst_imageR); | |||
| } | |||
| TEST_F(MindDataImageProcess, testWarpAffineBGRResize) { | |||
| std::string filename = "data/dataset/apple.jpg"; | |||
| cv::Mat src_image = cv::imread(filename, cv::ImreadModes::IMREAD_COLOR); | |||
| cv::Point2f srcTri[3]; | |||
| cv::Point2f dstTri[3]; | |||
| srcTri[0] = cv::Point2f(10, 20); | |||
| srcTri[1] = cv::Point2f(src_image.cols - 1 - 100, 0); | |||
| srcTri[2] = cv::Point2f(0, src_image.rows - 1 - 300); | |||
| dstTri[0] = cv::Point2f(src_image.cols * 0.22, src_image.rows * 0.33); | |||
| dstTri[1] = cv::Point2f(src_image.cols * 0.87, src_image.rows * 0.75); | |||
| dstTri[2] = cv::Point2f(src_image.cols * 0.35, src_image.rows * 0.37); | |||
| cv::Mat warp_mat = cv::getAffineTransform(srcTri, dstTri); | |||
| ; | |||
| cv::Mat warp_dstImage; | |||
| cv::warpAffine(src_image, warp_dstImage, warp_mat, cv::Size(src_image.cols + 200, src_image.rows - 300)); | |||
| cv::imwrite("./warpAffine_cv_bgr_resize.png", warp_dstImage); | |||
| bool ret = false; | |||
| LiteMat lite_mat_bgr; | |||
| ret = InitFromPixel(src_image.data, LPixelType::BGR, LDataType::UINT8, src_image.cols, src_image.rows, lite_mat_bgr); | |||
| EXPECT_TRUE(ret); | |||
| double *mat_ptr = warp_mat.ptr<double>(0); | |||
| LiteMat lite_M(3, 2, 1, mat_ptr, LDataType::DOUBLE); | |||
| LiteMat lite_warp; | |||
| std::vector<uint8_t> borderValues; | |||
| borderValues.push_back(0); | |||
| borderValues.push_back(0); | |||
| borderValues.push_back(0); | |||
| ret = WarpAffineBilinear(lite_mat_bgr, lite_warp, lite_M, lite_mat_bgr.width_ + 200, lite_mat_bgr.height_ - 300, PADD_BORDER_CONSTANT, | |||
| borderValues); | |||
| EXPECT_TRUE(ret); | |||
| cv::Mat dst_imageR(lite_warp.height_, lite_warp.width_, CV_8UC3, lite_warp.data_ptr_); | |||
| cv::imwrite("./warpAffine_lite_bgr_resize.png", dst_imageR); | |||
| } | |||
| TEST_F(MindDataImageProcess, testWarpAffineGray) { | |||
| std::string filename = "data/dataset/apple.jpg"; | |||
| cv::Mat src_image = cv::imread(filename, cv::ImreadModes::IMREAD_COLOR); | |||
| cv::Mat gray_image; | |||
| cv::cvtColor(src_image, gray_image, CV_BGR2GRAY); | |||
| cv::Point2f srcTri[3]; | |||
| cv::Point2f dstTri[3]; | |||
| srcTri[0] = cv::Point2f(0, 0); | |||
| srcTri[1] = cv::Point2f(src_image.cols - 1, 0); | |||
| srcTri[2] = cv::Point2f(0, src_image.rows - 1); | |||
| dstTri[0] = cv::Point2f(src_image.cols * 0.0, src_image.rows * 0.33); | |||
| dstTri[1] = cv::Point2f(src_image.cols * 0.85, src_image.rows * 0.25); | |||
| dstTri[2] = cv::Point2f(src_image.cols * 0.15, src_image.rows * 0.7); | |||
| cv::Mat warp_mat = cv::getAffineTransform(srcTri, dstTri); | |||
| ; | |||
| cv::Mat warp_gray_dstImage; | |||
| cv::warpAffine(gray_image, warp_gray_dstImage, warp_mat, cv::Size(src_image.cols + 200, src_image.rows - 300)); | |||
| cv::imwrite("./warpAffine_cv_gray.png", warp_gray_dstImage); | |||
| cv::Mat rgba_mat; | |||
| cv::cvtColor(src_image, rgba_mat, CV_BGR2RGBA); | |||
| bool ret = false; | |||
| LiteMat lite_mat_gray; | |||
| ret = | |||
| InitFromPixel(rgba_mat.data, LPixelType::RGBA2GRAY, LDataType::UINT8, rgba_mat.cols, rgba_mat.rows, lite_mat_gray); | |||
| EXPECT_TRUE(ret); | |||
| double *mat_ptr = warp_mat.ptr<double>(0); | |||
| LiteMat lite_M(3, 2, 1, mat_ptr, LDataType::DOUBLE); | |||
| LiteMat lite_warp; | |||
| std::vector<uint8_t> borderValues; | |||
| borderValues.push_back(0); | |||
| ret = WarpAffineBilinear(lite_mat_gray, lite_warp, lite_M, lite_mat_gray.width_ + 200, lite_mat_gray.height_ - 300, PADD_BORDER_CONSTANT, | |||
| borderValues); | |||
| EXPECT_TRUE(ret); | |||
| cv::Mat dst_imageR(lite_warp.height_, lite_warp.width_, CV_8UC1, lite_warp.data_ptr_); | |||
| cv::imwrite("./warpAffine_lite_gray.png", dst_imageR); | |||
| } | |||
| TEST_F(MindDataImageProcess, testWarpPerspectiveBGRResize) { | |||
| std::string filename = "data/dataset/apple.jpg"; | |||
| cv::Mat src_image = cv::imread(filename, cv::ImreadModes::IMREAD_COLOR); | |||
| cv::Point2f srcQuad[4], dstQuad[4]; | |||
| srcQuad[0].x = 0; | |||
| srcQuad[0].y = 0; | |||
| srcQuad[1].x = src_image.cols - 1.; | |||
| srcQuad[1].y = 0; | |||
| srcQuad[2].x = 0; | |||
| srcQuad[2].y = src_image.rows - 1; | |||
| srcQuad[3].x = src_image.cols - 1; | |||
| srcQuad[3].y = src_image.rows - 1; | |||
| dstQuad[0].x = src_image.cols * 0.05; | |||
| dstQuad[0].y = src_image.rows * 0.33; | |||
| dstQuad[1].x = src_image.cols * 0.9; | |||
| dstQuad[1].y = src_image.rows * 0.25; | |||
| dstQuad[2].x = src_image.cols * 0.2; | |||
| dstQuad[2].y = src_image.rows * 0.7; | |||
| dstQuad[3].x = src_image.cols * 0.8; | |||
| dstQuad[3].y = src_image.rows * 0.9; | |||
| cv::Mat ptran = cv::getPerspectiveTransform(srcQuad, dstQuad, cv::DECOMP_SVD); | |||
| cv::Mat warp_dstImage; | |||
| cv::warpPerspective(src_image, warp_dstImage, ptran, cv::Size(src_image.cols + 200, src_image.rows - 300)); | |||
| cv::imwrite("./warpPerspective_cv_bgr.png", warp_dstImage); | |||
| bool ret = false; | |||
| LiteMat lite_mat_bgr; | |||
| ret = InitFromPixel(src_image.data, LPixelType::BGR, LDataType::UINT8, src_image.cols, src_image.rows, lite_mat_bgr); | |||
| EXPECT_TRUE(ret); | |||
| double *mat_ptr = ptran.ptr<double>(0); | |||
| LiteMat lite_M(3, 3, 1, mat_ptr, LDataType::DOUBLE); | |||
| LiteMat lite_warp; | |||
| std::vector<uint8_t> borderValues; | |||
| borderValues.push_back(0); | |||
| borderValues.push_back(0); | |||
| borderValues.push_back(0); | |||
| ret = WarpPerspectiveBilinear(lite_mat_bgr, lite_warp, lite_M, lite_mat_bgr.width_ + 200, lite_mat_bgr.height_ - 300, PADD_BORDER_CONSTANT, | |||
| borderValues); | |||
| EXPECT_TRUE(ret); | |||
| cv::Mat dst_imageR(lite_warp.height_, lite_warp.width_, CV_8UC3, lite_warp.data_ptr_); | |||
| cv::imwrite("./warpPerspective_lite_bgr.png", dst_imageR); | |||
| } | |||
| TEST_F(MindDataImageProcess, testWarpPerspectiveGrayResize) { | |||
| std::string filename = "data/dataset/apple.jpg"; | |||
| cv::Mat src_image = cv::imread(filename, cv::ImreadModes::IMREAD_COLOR); | |||
| cv::Mat gray_image; | |||
| cv::cvtColor(src_image, gray_image, CV_BGR2GRAY); | |||
| cv::Point2f srcQuad[4], dstQuad[4]; | |||
| srcQuad[0].x = 0; | |||
| srcQuad[0].y = 0; | |||
| srcQuad[1].x = src_image.cols - 1.; | |||
| srcQuad[1].y = 0; | |||
| srcQuad[2].x = 0; | |||
| srcQuad[2].y = src_image.rows - 1; | |||
| srcQuad[3].x = src_image.cols - 1; | |||
| srcQuad[3].y = src_image.rows - 1; | |||
| dstQuad[0].x = src_image.cols * 0.05; | |||
| dstQuad[0].y = src_image.rows * 0.33; | |||
| dstQuad[1].x = src_image.cols * 0.9; | |||
| dstQuad[1].y = src_image.rows * 0.25; | |||
| dstQuad[2].x = src_image.cols * 0.2; | |||
| dstQuad[2].y = src_image.rows * 0.7; | |||
| dstQuad[3].x = src_image.cols * 0.8; | |||
| dstQuad[3].y = src_image.rows * 0.9; | |||
| cv::Mat ptran = cv::getPerspectiveTransform(srcQuad, dstQuad, cv::DECOMP_SVD); | |||
| cv::Mat warp_dstImage; | |||
| cv::warpPerspective(gray_image, warp_dstImage, ptran, cv::Size(gray_image.cols + 200, gray_image.rows - 300)); | |||
| cv::imwrite("./warpPerspective_cv_gray.png", warp_dstImage); | |||
| cv::Mat rgba_mat; | |||
| cv::cvtColor(src_image, rgba_mat, CV_BGR2RGBA); | |||
| bool ret = false; | |||
| LiteMat lite_mat_gray; | |||
| ret = | |||
| InitFromPixel(rgba_mat.data, LPixelType::RGBA2GRAY, LDataType::UINT8, rgba_mat.cols, rgba_mat.rows, lite_mat_gray); | |||
| EXPECT_TRUE(ret); | |||
| double *mat_ptr = ptran.ptr<double>(0); | |||
| LiteMat lite_M(3, 3, 1, mat_ptr, LDataType::DOUBLE); | |||
| LiteMat lite_warp; | |||
| std::vector<uint8_t> borderValues; | |||
| borderValues.push_back(0); | |||
| ret = WarpPerspectiveBilinear(lite_mat_gray, lite_warp, lite_M, lite_mat_gray.width_ + 200, lite_mat_gray.height_ - 300, PADD_BORDER_CONSTANT, | |||
| borderValues); | |||
| EXPECT_TRUE(ret); | |||
| cv::Mat dst_imageR(lite_warp.height_, lite_warp.width_, CV_8UC1, lite_warp.data_ptr_); | |||
| cv::imwrite("./warpPerspective_lite_gray.png", dst_imageR); | |||
| } | |||