add warp affine

This commit is contained in:
xulei2020 2021-01-05 10:48:44 +08:00
parent da92f1affb
commit de6356ebfa
7 changed files with 1030 additions and 20 deletions

View File

@ -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)

View File

@ -28,11 +28,34 @@
#endif
#endif
#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 {
#define Equ(a, b) ((std::fabs((a) - (b)) < 1e-6))
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;
}

View File

@ -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_

View File

@ -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++) {

View File

@ -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

View File

@ -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

View File

@ -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);
}