forked from mindspore-Ecosystem/mindspore
!6009 Add Affine transformation ut for Lite Dataset
Merge pull request !6009 from jiangzhiwen/lite/affine_ut
This commit is contained in:
commit
2dfb2f3578
|
@ -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,
|
std::vector<int> ApplyNms(const std::vector<std::vector<float>> &all_boxes, std::vector<float> &all_scores, float thres,
|
||||||
int max_boxes) {
|
int max_boxes) {
|
||||||
int boxes_num = all_boxes.size();
|
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<float> areas(boxes_num);
|
||||||
std::vector<int> order(boxes_num);
|
std::vector<int> order(boxes_num);
|
||||||
for (int i = 0; i < boxes_num; i++) {
|
for (int i = 0; i < boxes_num; i++) {
|
||||||
y1[i] = all_boxes[i][0];
|
areas[i] = (all_boxes[i][3] - all_boxes[i][1] + 1) * (all_boxes[i][2] - all_boxes[i][0] + 1);
|
||||||
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);
|
|
||||||
order[i] = i;
|
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;
|
int len = order.size() - 1;
|
||||||
std::vector<float> ovr(len);
|
std::vector<float> ovr(len);
|
||||||
for (int j = 0; j < len; j++) {
|
for (int j = 0; j < len; j++) {
|
||||||
float xx1 = std::max(x1[i], x1[order[j + 1]]);
|
float xx1 = std::max(all_boxes[i][1], all_boxes[order[j + 1]][1]);
|
||||||
float yy1 = std::max(y1[i], y1[order[j + 1]]);
|
float yy1 = std::max(all_boxes[i][0], all_boxes[order[j + 1]][0]);
|
||||||
float xx2 = std::min(x2[i], x2[order[j + 1]]);
|
float xx2 = std::min(all_boxes[i][3], all_boxes[order[j + 1]][3]);
|
||||||
float yy2 = std::min(y2[i], y2[order[j + 1]]);
|
float yy2 = std::min(all_boxes[i][2], all_boxes[order[j + 1]][2]);
|
||||||
|
|
||||||
float w = std::max(0.0f, xx2 - xx1 + 1);
|
float w = std::max(0.0f, xx2 - xx1 + 1);
|
||||||
float h = std::max(0.0f, yy2 - yy1 + 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;
|
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];
|
double IM[6];
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
IM[i] = M[i];
|
IM[i] = M[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
double D = IM[0] * IM[4] - IM[1] * IM[3];
|
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;
|
double A11 = IM[4] * D, A22 = IM[0] * D;
|
||||||
IM[0] = A11;
|
IM[0] = A11;
|
||||||
IM[1] *= -D;
|
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_x = IM[0] * x + IM[1] * y + IM[2];
|
||||||
int src_y = IM[3] * x + IM[4] * y + IM[5];
|
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_) {
|
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];
|
Pixel_Type src_pixel = static_cast<Pixel_Type *>(src.data_ptr_)[src_y * src.width_ + src_x];
|
||||||
static_cast<UINT8_C3 *>(out_img.data_ptr_)[y * src.width_ + x] = src_pixel;
|
static_cast<Pixel_Type *>(out_img.data_ptr_)[y * src.width_ + x] = src_pixel;
|
||||||
} else {
|
} 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 dataset
|
||||||
} // namespace mindspore
|
} // namespace mindspore
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "lite_cv/lite_mat.h"
|
#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,
|
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);
|
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);
|
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,
|
void ConvertBoxes(std::vector<std::vector<float>> &boxes, const std::vector<std::vector<float>> &default_boxes,
|
||||||
const BoxesConfig config);
|
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,
|
std::vector<int> ApplyNms(const std::vector<std::vector<float>> &all_boxes, std::vector<float> &all_scores, float thres,
|
||||||
int max_boxes);
|
int max_boxes);
|
||||||
|
|
||||||
|
|
|
@ -27,17 +27,20 @@ namespace dataset {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct Chn1 {
|
struct Chn1 {
|
||||||
|
Chn1(T c1) : c1(c1) {}
|
||||||
T c1;
|
T c1;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct Chn2 {
|
struct Chn2 {
|
||||||
|
Chn2(T c1, T c2) : c1(c1), c2(c2) {}
|
||||||
T c1;
|
T c1;
|
||||||
T c2;
|
T c2;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct Chn3 {
|
struct Chn3 {
|
||||||
|
Chn3(T c1, T c2, T c3) : c1(c1), c2(c2), c3(c3) {}
|
||||||
T c1;
|
T c1;
|
||||||
T c2;
|
T c2;
|
||||||
T c3;
|
T c3;
|
||||||
|
@ -45,6 +48,7 @@ struct Chn3 {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct Chn4 {
|
struct Chn4 {
|
||||||
|
Chn4(T c1, T c2, T c3, T c4) : c1(c1), c2(c2), c3(c3), c4(c4) {}
|
||||||
T c1;
|
T c1;
|
||||||
T c2;
|
T c2;
|
||||||
T c3;
|
T c3;
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include <opencv2/imgproc/types_c.h>
|
#include <opencv2/imgproc/types_c.h>
|
||||||
#include "utils/log_adapter.h"
|
#include "utils/log_adapter.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
using namespace mindspore::dataset;
|
using namespace mindspore::dataset;
|
||||||
class MindDataImageProcess : public UT::Common {
|
class MindDataImageProcess : public UT::Common {
|
||||||
public:
|
public:
|
||||||
|
@ -228,6 +230,7 @@ TEST_F(MindDataImageProcess, TestPadd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MindDataImageProcess, TestGetDefaultBoxes) {
|
TEST_F(MindDataImageProcess, TestGetDefaultBoxes) {
|
||||||
|
std::string benchmark = "data/dataset/testLite/default_boxes.bin";
|
||||||
BoxesConfig config;
|
BoxesConfig config;
|
||||||
config.img_shape = {300, 300};
|
config.img_shape = {300, 300};
|
||||||
config.num_default = {3, 6, 6, 6, 6, 6};
|
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.steps = {16, 32, 64, 100, 150, 300};
|
||||||
config.prior_scaling = {0.1, 0.2};
|
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);
|
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) {
|
TEST_F(MindDataImageProcess, TestApplyNms) {
|
||||||
|
@ -250,3 +270,67 @@ TEST_F(MindDataImageProcess, TestApplyNms) {
|
||||||
ASSERT_TRUE(keep[1] == 0);
|
ASSERT_TRUE(keep[1] == 0);
|
||||||
ASSERT_TRUE(keep[2] == 1);
|
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
Loading…
Reference in New Issue