add Affine ut

This commit is contained in:
jiangzhiwen 2020-09-10 20:55:51 +08:00
parent 82eb2634a0
commit d4ce668b9b
5 changed files with 1085 additions and 20 deletions

View File

@ -516,18 +516,10 @@ 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) {
int boxes_num = all_boxes.size();
std::vector<float> y1(boxes_num);
std::vector<float> x1(boxes_num);
std::vector<float> y2(boxes_num);
std::vector<float> x2(boxes_num);
std::vector<float> areas(boxes_num);
std::vector<int> order(boxes_num);
for (int i = 0; i < boxes_num; i++) {
y1[i] = all_boxes[i][0];
x1[i] = all_boxes[i][1];
y2[i] = all_boxes[i][2];
x2[i] = all_boxes[i][3];
areas[i] = (x2[i] - x1[i] + 1) * (y2[i] - y1[i] + 1);
areas[i] = (all_boxes[i][3] - all_boxes[i][1] + 1) * (all_boxes[i][2] - all_boxes[i][0] + 1);
order[i] = i;
}
@ -543,10 +535,10 @@ std::vector<int> ApplyNms(const std::vector<std::vector<float>> &all_boxes, std:
int len = order.size() - 1;
std::vector<float> ovr(len);
for (int j = 0; j < len; j++) {
float xx1 = std::max(x1[i], x1[order[j + 1]]);
float yy1 = std::max(y1[i], y1[order[j + 1]]);
float xx2 = std::min(x2[i], x2[order[j + 1]]);
float yy2 = std::min(y2[i], y2[order[j + 1]]);
float xx1 = std::max(all_boxes[i][1], all_boxes[order[j + 1]][1]);
float yy1 = std::max(all_boxes[i][0], all_boxes[order[j + 1]][0]);
float xx2 = std::min(all_boxes[i][3], all_boxes[order[j + 1]][3]);
float yy2 = std::min(all_boxes[i][2], all_boxes[order[j + 1]][2]);
float w = std::max(0.0f, xx2 - xx1 + 1);
float h = std::max(0.0f, yy2 - yy1 + 1);
@ -568,14 +560,15 @@ std::vector<int> ApplyNms(const std::vector<std::vector<float>> &all_boxes, std:
return keep;
}
void WarpAffine(LiteMat &src, LiteMat &out_img, double M[6], std::vector<size_t> dsize, UINT8_C3 borderValue) {
template <typename Pixel_Type>
void ImplementAffine(LiteMat &src, LiteMat &out_img, double M[6], std::vector<size_t> &dsize, Pixel_Type borderValue) {
double IM[6];
for (int i = 0; i < 6; i++) {
IM[i] = M[i];
}
double D = IM[0] * IM[4] - IM[1] * IM[3];
D = D != 0 ? 1. / D : 0;
D = D != 0 ? 1.0f / D : 0;
double A11 = IM[4] * D, A22 = IM[0] * D;
IM[0] = A11;
IM[1] *= -D;
@ -592,13 +585,22 @@ void WarpAffine(LiteMat &src, LiteMat &out_img, double M[6], std::vector<size_t>
int src_x = IM[0] * x + IM[1] * y + IM[2];
int src_y = IM[3] * x + IM[4] * y + IM[5];
if (src_x >= 0 && src_y >= 0 && src_x < src.width_ && src_y < src.height_) {
UINT8_C3 src_pixel = static_cast<UINT8_C3 *>(src.data_ptr_)[src_y * src.width_ + src_x];
static_cast<UINT8_C3 *>(out_img.data_ptr_)[y * src.width_ + x] = src_pixel;
Pixel_Type src_pixel = static_cast<Pixel_Type *>(src.data_ptr_)[src_y * src.width_ + src_x];
static_cast<Pixel_Type *>(out_img.data_ptr_)[y * src.width_ + x] = src_pixel;
} else {
static_cast<UINT8_C3 *>(out_img.data_ptr_)[y * src.width_ + x] = borderValue;
static_cast<Pixel_Type *>(out_img.data_ptr_)[y * src.width_ + x] = borderValue;
}
}
}
}
void Affine(LiteMat &src, LiteMat &out_img, double M[6], std::vector<size_t> dsize, UINT8_C1 borderValue) {
ImplementAffine(src, out_img, M, dsize, borderValue);
}
void Affine(LiteMat &src, LiteMat &out_img, double M[6], std::vector<size_t> dsize, UINT8_C3 borderValue) {
ImplementAffine(src, out_img, M, dsize, borderValue);
}
} // namespace dataset
} // namespace mindspore

View File

@ -20,6 +20,7 @@
#include <math.h>
#include <vector>
#include <algorithm>
#include <iostream>
#include "lite_cv/lite_mat.h"
@ -68,13 +69,20 @@ bool SubStractMeanNormalize(const LiteMat &src, LiteMat &dst, float *mean, float
bool Padd(const LiteMat &src, LiteMat &dst, int top, int bottom, int left, int right, PaddBorderType pad_type,
uint8_t fill_b_or_gray, uint8_t fill_g, uint8_t fill_r);
void WarpAffine(const LiteMat &src, LiteMat &out_img, double M[6], std::vector<size_t> dsize, uint8_t borderValue[3]);
/// \brief Apply affine transformation for 1 channel image
void Affine(LiteMat &src, LiteMat &out_img, double M[6], std::vector<size_t> dsize, UINT8_C1 borderValue);
/// \brief Apply affine transformation for 3 channel image
void Affine(LiteMat &src, LiteMat &out_img, double M[6], std::vector<size_t> dsize, UINT8_C3 borderValue);
/// \brief Get default anchor boxes for Faster R-CNN, SSD, YOLO etc
std::vector<std::vector<float>> GetDefaultBoxes(const BoxesConfig config);
/// \brief Convert the prediction boxes to the actual boxes of (y, x, h, w)
void ConvertBoxes(std::vector<std::vector<float>> &boxes, const std::vector<std::vector<float>> &default_boxes,
const BoxesConfig config);
/// \brief Apply Non-Maximum Suppression
std::vector<int> ApplyNms(const std::vector<std::vector<float>> &all_boxes, std::vector<float> &all_scores, float thres,
int max_boxes);

View File

@ -27,17 +27,20 @@ namespace dataset {
template <typename T>
struct Chn1 {
Chn1(T c1) : c1(c1) {}
T c1;
};
template <typename T>
struct Chn2 {
Chn2(T c1, T c2) : c1(c1), c2(c2) {}
T c1;
T c2;
};
template <typename T>
struct Chn3 {
Chn3(T c1, T c2, T c3) : c1(c1), c2(c2), c3(c3) {}
T c1;
T c2;
T c3;
@ -45,6 +48,7 @@ struct Chn3 {
template <typename T>
struct Chn4 {
Chn4(T c1, T c2, T c3, T c4) : c1(c1), c2(c2), c3(c3), c4(c4) {}
T c1;
T c2;
T c3;

View File

@ -21,6 +21,8 @@
#include <opencv2/imgproc/types_c.h>
#include "utils/log_adapter.h"
#include <fstream>
using namespace mindspore::dataset;
class MindDataImageProcess : public UT::Common {
public:
@ -228,6 +230,7 @@ TEST_F(MindDataImageProcess, TestPadd) {
}
TEST_F(MindDataImageProcess, TestGetDefaultBoxes) {
std::string benchmark = "data/dataset/testLite/default_boxes.bin";
BoxesConfig config;
config.img_shape = {300, 300};
config.num_default = {3, 6, 6, 6, 6, 6};
@ -238,8 +241,25 @@ TEST_F(MindDataImageProcess, TestGetDefaultBoxes) {
config.steps = {16, 32, 64, 100, 150, 300};
config.prior_scaling = {0.1, 0.2};
int rows = 1917;
int cols = 4;
std::vector<double> benchmark_boxes(rows * cols);
std::ifstream in(benchmark, std::ios::in | std::ios::binary);
in.read(reinterpret_cast<char*>(benchmark_boxes.data()), benchmark_boxes.size() * sizeof(double));
in.close();
std::vector<std::vector<float>> default_boxes = GetDefaultBoxes(config);
ASSERT_TRUE(default_boxes.size() == 1917);
EXPECT_EQ(default_boxes.size(), rows);
EXPECT_EQ(default_boxes[0].size(), cols);
double distance = 0.0f;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
distance += pow(default_boxes[i][j] - benchmark_boxes[i * cols + j], 2);
}
}
distance = sqrt(distance);
EXPECT_LT(distance, 1e-5);
}
TEST_F(MindDataImageProcess, TestApplyNms) {
@ -250,3 +270,67 @@ TEST_F(MindDataImageProcess, TestApplyNms) {
ASSERT_TRUE(keep[1] == 0);
ASSERT_TRUE(keep[2] == 1);
}
TEST_F(MindDataImageProcess, TestAffine) {
// The input matrix
// 0 0 1 0 0
// 0 0 1 0 0
// 2 2 3 2 2
// 0 0 1 0 0
// 0 0 1 0 0
size_t rows = 5;
size_t cols = 5;
LiteMat src(rows, cols);
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) {
if (i == 2 && j == 2) {
static_cast<UINT8_C1*>(src.data_ptr_)[i * cols + j] = 3;
} else if (i == 2) {
static_cast<UINT8_C1*>(src.data_ptr_)[i * cols + j] = 2;
} else if (j == 2) {
static_cast<UINT8_C1*>(src.data_ptr_)[i * cols + j] = 1;
} else {
static_cast<UINT8_C1*>(src.data_ptr_)[i * cols + j] = 0;
}
}
}
// Expect output matrix
// 0 0 2 0 0
// 0 0 2 0 0
// 1 1 3 1 1
// 0 0 2 0 0
// 0 0 2 0 0
LiteMat expect(rows, cols);
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) {
if (i == 2 && j == 2) {
static_cast<UINT8_C1*>(expect.data_ptr_)[i * cols + j] = 3;
} else if (i == 2) {
static_cast<UINT8_C1*>(expect.data_ptr_)[i * cols + j] = 1;
} else if (j == 2) {
static_cast<UINT8_C1*>(expect.data_ptr_)[i * cols + j] = 2;
} else {
static_cast<UINT8_C1*>(expect.data_ptr_)[i * cols + j] = 0;
}
}
}
double angle = 90.0f;
cv::Point2f center(rows / 2, cols / 2);
cv::Mat rotate_matrix = cv::getRotationMatrix2D(center, angle, 1.0);
double M[6];
for (size_t i = 0; i < 6; i++) {
M[i] = rotate_matrix.at<double>(i);
}
std::cout << std::endl;
LiteMat dst;
Affine(src, dst, M, {rows, cols}, UINT8_C1(0));
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) {
EXPECT_EQ(static_cast<UINT8_C1*>(expect.data_ptr_)[i * cols + j].c1,
static_cast<UINT8_C1*>(dst.data_ptr_)[i * cols + j].c1);
}
}
}

File diff suppressed because one or more lines are too long