未验证 提交 ba54e537 编写于 作者: H HappyAngel 提交者: GitHub

【arm】resize nv12 bug (#3155)

* fix clang v7 error
* change ut, test=develop
* fix conv ut, test=develop
上级 3501f3c2
...@@ -509,7 +509,7 @@ void act_switch_3x3s1(const float* inr0, ...@@ -509,7 +509,7 @@ void act_switch_3x3s1(const float* inr0,
"x6", "x6",
"x7"); "x7");
#else #else
#ifdef LITE_WITH_ARM_CLANG #if 1 // def LITE_WITH_ARM_CLANG
#else #else
asm volatile(COMPUTE RELU STORE asm volatile(COMPUTE RELU STORE
: [r0] "+r"(inr0), : [r0] "+r"(inr0),
...@@ -597,7 +597,7 @@ void act_switch_3x3s1(const float* inr0, ...@@ -597,7 +597,7 @@ void act_switch_3x3s1(const float* inr0,
"x6", "x6",
"x7"); "x7");
#else #else
#ifdef LITE_WITH_ARM_CLANG #if 1 // def LITE_WITH_ARM_CLANG
#else #else
asm volatile(COMPUTE RELU RELU6 STORE asm volatile(COMPUTE RELU RELU6 STORE
: [r0] "+r"(inr0), : [r0] "+r"(inr0),
...@@ -685,7 +685,7 @@ void act_switch_3x3s1(const float* inr0, ...@@ -685,7 +685,7 @@ void act_switch_3x3s1(const float* inr0,
"x6", "x6",
"x7"); "x7");
#else #else
#ifdef LITE_WITH_ARM_CLANG #if 1 // def LITE_WITH_ARM_CLANG
#else #else
asm volatile(COMPUTE LEAKY_RELU STORE asm volatile(COMPUTE LEAKY_RELU STORE
: [r0] "+r"(inr0), : [r0] "+r"(inr0),
...@@ -778,7 +778,7 @@ void act_switch_3x3s1(const float* inr0, ...@@ -778,7 +778,7 @@ void act_switch_3x3s1(const float* inr0,
"x6", "x6",
"x7"); "x7");
#else #else
#ifdef LITE_WITH_ARM_CLANG #if 1 // def LITE_WITH_ARM_CLANG
#else #else
asm volatile(COMPUTE STORE asm volatile(COMPUTE STORE
: [r0] "+r"(inr0), : [r0] "+r"(inr0),
...@@ -1001,7 +1001,7 @@ void conv_3x3s1_depthwise_fp32(const float* i_data, ...@@ -1001,7 +1001,7 @@ void conv_3x3s1_depthwise_fp32(const float* i_data,
vbias, vbias,
act_param); act_param);
#else #else
#ifdef LITE_WITH_ARM_CLANG #if 1 // def LITE_WITH_ARM_CLANG
#else #else
act_switch_3x3s1(inr0, act_switch_3x3s1(inr0,
inr1, inr1,
......
...@@ -40,7 +40,7 @@ CXX_INCLUDES = $(INCLUDES) ${OPENCV_INCLUDE} -I$(LITE_ROOT)/cxx/include ...@@ -40,7 +40,7 @@ CXX_INCLUDES = $(INCLUDES) ${OPENCV_INCLUDE} -I$(LITE_ROOT)/cxx/include
# 1. Comment above line using `libpaddle_light_api_shared.so` # 1. Comment above line using `libpaddle_light_api_shared.so`
# 2. Undo comment below line using `libpaddle_api_light_bundled.a` # 2. Undo comment below line using `libpaddle_api_light_bundled.a`
CXX_LIBS = $(LITE_ROOT)/cxx/lib/libpaddle_api_light_bundled.a $(SYSTEM_LIBS) CXX_LIBS = ${OPENCV_LIBS} $(LITE_ROOT)/cxx/lib/libpaddle_api_light_bundled.a $(SYSTEM_LIBS)
test_model_cv: fetch_opencv test_model_cv.o test_model_cv: fetch_opencv test_model_cv.o
$(CC) $(SYSROOT_LINK) $(CXXFLAGS_LINK) test_model_cv.o -o test_model_cv $(CXX_LIBS) $(LDFLAGS) $(CC) $(SYSROOT_LINK) $(CXXFLAGS_LINK) test_model_cv.o -o test_model_cv $(CXX_LIBS) $(LDFLAGS)
......
...@@ -28,362 +28,861 @@ typedef paddle::lite::utils::cv::ImagePreprocess ImagePreprocess; ...@@ -28,362 +28,861 @@ typedef paddle::lite::utils::cv::ImagePreprocess ImagePreprocess;
typedef paddle::lite_api::DataLayoutType LayoutType; typedef paddle::lite_api::DataLayoutType LayoutType;
using namespace paddle::lite_api; // NOLINT using namespace paddle::lite_api; // NOLINT
void fill_with_mat(cv::Mat& mat, uint8_t* src) { // NOLINT void fill_with_mat(cv::Mat& mat, uint8_t* src, int num) { // NOLINT
for (int i = 0; i < mat.rows; i++) { for (int i = 0; i < mat.rows; i++) {
for (int j = 0; j < mat.cols; j++) { for (int j = 0; j < mat.cols; j++) {
int tmp = (i * mat.cols + j) * 3; if (num == 1) {
cv::Vec3b& rgb = mat.at<cv::Vec3b>(i, j); int tmp = (i * mat.cols + j);
rgb[0] = src[tmp]; } else if (num == 2) {
rgb[1] = src[tmp + 1]; int tmp = (i * mat.cols + j) * 2;
rgb[2] = src[tmp + 2]; cv::Vec2b& rgb = mat.at<cv::Vec2b>(i, j);
rgb[0] = src[tmp];
rgb[1] = src[tmp + 1];
rgb[2] = src[tmp + 2];
} else if (num == 3) {
int tmp = (i * mat.cols + j) * 3;
cv::Vec3b& rgb = mat.at<cv::Vec3b>(i, j);
rgb[0] = src[tmp];
rgb[1] = src[tmp + 1];
rgb[2] = src[tmp + 2];
} else if (num == 4) {
int tmp = (i * mat.cols + j) * 4;
cv::Vec4b& rgb = mat.at<cv::Vec4b>(i, j);
rgb[0] = src[tmp];
rgb[1] = src[tmp + 1];
rgb[2] = src[tmp + 2];
rgb[3] = src[tmp + 3];
} else {
std::cout << "it is not support" << std::endl;
return;
}
} }
} }
} }
void test_img(std::vector<int> cluster_id,
std::vector<int> thread_num,
std::string img_path,
std::string dst_path,
ImageFormat srcFormat,
ImageFormat dstFormat,
int width,
int height,
float rotate,
FlipParam flip,
LayoutType layout,
std::string model_file,
int test_iter = 1) {
// init
// paddle::lite::DeviceInfo::Init();
// read img and pre-process
cv::Mat img = imread(img_path, cv::IMREAD_COLOR);
float means[3] = {0.485f, 0.456f, 0.406f};
float scales[3] = {0.229f, 0.224f, 0.225f};
int srch = img.rows;
int srcw = img.cols;
for (auto& cls : cluster_id) {
for (auto& th : thread_num) {
std::cout << "cluster: " << cls << ", threads: " << th << std::endl;
// 1. Set MobileConfig
MobileConfig config;
config.set_model_from_file(model_file);
config.set_power_mode((PowerMode)cls);
config.set_threads(th);
std::cout << "model: " << model_file;
// 2. Create PaddlePredictor by MobileConfig
std::shared_ptr<PaddlePredictor> predictor =
CreatePaddlePredictor<MobileConfig>(config);
// 3. Prepare input data from image double compare_diff(uint8_t* data1, uint8_t* data2, int size) {
std::unique_ptr<Tensor> input_tensor(predictor->GetInput(0)); double diff = 0.0;
for (int i = 0; i < size; i++) {
double val = abs(data1[i] - data2[i]);
diff = val > diff ? val : diff;
}
return diff;
}
void print_data(const uint8_t* data, int size) {
for (int i = 0; i < size; i++) {
std::cout << data[i] << " ";
if ((i + 1) % 10 == 0) {
std::cout << std::endl;
}
}
std::cout << std::endl;
}
bool test_convert(bool cv_run,
const uint8_t* src,
cv::Mat img,
ImagePreprocess image_preprocess,
int in_size,
int out_size,
ImageFormat srcFormat,
ImageFormat dstFormat,
int dsth,
int dstw,
std::string dst_path,
int test_iter = 1) {
// out
uint8_t* resize_cv = new uint8_t[out_size];
uint8_t* resize_lite = new uint8_t[out_size];
cv::Mat im_resize;
/* double to_cv = 0.0;
imread(img_path, param) double to_lite = 0.0;
IMREAD_UNCHANGED(<0) 表示加载原图,不做任何改变 std::cout << "opencv compute:" << std::endl;
IMREAD_GRAYSCALE ( 0)表示把原图作为灰度图像加载进来 if (cv_run) {
IMREAD_COLOR (>0) 表示把原图作为RGB图像加载进来 for (int i = 0; i < test_iter; i++) {
*/ clock_t begin = clock();
cv::Mat img; // convert bgr-gray
if (srcFormat == ImageFormat::BGR || srcFormat == ImageFormat::RGB) { if (dstFormat == srcFormat) {
img = imread(img_path, cv::IMREAD_COLOR); im_resize = img;
} else if (srcFormat == ImageFormat::GRAY) { } else if ((dstFormat == ImageFormat::BGR ||
img = imread(img_path, cv::IMREAD_GRAYSCALE); dstFormat == ImageFormat::RGB) &&
} else { srcFormat == ImageFormat::GRAY) {
printf("this format %d does not support \n", srcFormat); cv::cvtColor(img, im_resize, cv::COLOR_GRAY2BGR);
return; } else if ((srcFormat == ImageFormat::BGR ||
} dstFormat == ImageFormat::RGBA) &&
if (img.empty()) { dstFormat == ImageFormat::GRAY) {
std::cout << "opencv read image " << img_path.c_str() << " failed" cv::cvtColor(img, im_resize, cv::COLOR_BGR2GRAY);
<< std::endl; } else if (dstFormat == srcFormat) {
return; printf("convert format error \n");
return false;
} }
int srch = img.rows; clock_t end = clock();
int srcw = img.cols; to_cv += (end - begin);
int dsth = height; }
int dstw = width; }
std::cout << " input tensor size, num= " << 1 << ", channel= " << 1 std::cout << "lite compute:" << std::endl;
<< ", height= " << srch << ", width= " << srcw for (int i = 0; i < test_iter; i++) {
<< ", srcFormat= " << (ImageFormat)srcFormat << std::endl; clock_t begin = clock();
// RGBA = 0, BGRA, RGB, BGR, GRAY, NV21 = 11, NV12, // resize default linear
if (srcFormat == ImageFormat::GRAY) { image_preprocess.imageConvert(src, resize_lite);
std::cout << "srcFormat: GRAY" << std::endl; clock_t end = clock();
} to_lite += (end - begin);
if (srcFormat == ImageFormat::BGR) { }
std::cout << "srcFormat: BGR" << std::endl; to_cv = 1000 * to_cv / CLOCKS_PER_SEC;
} to_lite = 1000 * to_lite / CLOCKS_PER_SEC;
if (srcFormat == ImageFormat::RGB) {
std::cout << "srcFormat: RGB" << std::endl;
}
std::cout << " output tensor size, num=" << 1 << ", channel=" << 1
<< ", height=" << dsth << ", width=" << dstw
<< ", dstFormat= " << (ImageFormat)dstFormat << std::endl;
if (dstFormat == ImageFormat::GRAY) { std::cout << "---opencv convert run time: " << to_cv
std::cout << "dstFormat: GRAY" << std::endl; << "ms, avg: " << to_cv / test_iter << std::endl;
} std::cout << "---lite convert run time: " << to_lite
if (dstFormat == ImageFormat::BGR) { << "ms, avg: " << to_lite / test_iter << std::endl;
std::cout << "dstFormat: BGR" << std::endl; std::cout << "compare diff: " << std::endl;
}
if (dstFormat == ImageFormat::RGB) { if (cv_run) {
std::cout << "dstFormat: RGB" << std::endl; resize_cv = im_resize.data;
double diff = compare_diff(resize_cv, resize_lite, out_size);
if (diff > 1) {
std::cout << "din: " << std::endl;
print_data(src, in_size);
std::cout << "cv out: " << std::endl;
print_data(resize_cv, out_size);
std::cout << "lite out: " << std::endl;
print_data(resize_lite, out_size);
return false;
} else {
// save_img
std::cout << "write image: " << std::endl;
std::string resize_name = dst_path + "/convert.jpg";
cv::Mat resize_mat;
int num = 1;
if (dstFormat == ImageFormat::BGR || dstFormat == ImageFormat::RGB) {
resize_mat = cv::Mat(dsth, dstw, CV_8UC3);
num = 3;
} else if (dstFormat == ImageFormat::BGRA ||
dstFormat == ImageFormat::RGBA) {
resize_mat = cv::Mat(dsth, dstw, CV_8UC4);
num = 4;
} else if (dstFormat == ImageFormat::GRAY) {
resize_mat = cv::Mat(dsth, dstw, CV_8UC1);
num = 1;
} else if (dstFormat == ImageFormat::NV12) {
resize_mat = cv::Mat(dsth, dstw, CV_8UC2);
num = 2;
} }
fill_with_mat(resize_mat, resize_lite, num);
cv::imwrite(resize_name, resize_mat);
std::cout << "convert successed!" << std::endl;
return true;
}
}
}
bool test_flip(bool cv_run,
const uint8_t* src,
cv::Mat img,
ImagePreprocess image_preprocess,
int in_size,
int out_size,
FlipParam flip,
ImageFormat dstFormat,
int dsth,
int dstw,
std::string dst_path,
int test_iter = 1) {
// out
uint8_t* resize_cv = new uint8_t[out_size];
uint8_t* resize_lite = new uint8_t[out_size];
cv::Mat im_resize;
std::cout << "Rotate = " << rotate << ", Flip = " << flip double to_cv = 0.0;
<< ", Layout = " << static_cast<int>(layout) << std::endl; double to_lite = 0.0;
if (static_cast<int>(layout) != 1 && static_cast<int>(layout) != 3) { std::cout << "opencv compute:" << std::endl;
std::cout << "this layout" << static_cast<int>(layout) if (cv_run) {
<< " is no support" << std::endl; for (int i = 0; i < test_iter; i++) {
clock_t begin = clock();
// resize default linear
cv::flip(img, im_resize, flip);
clock_t end = clock();
to_cv += (end - begin);
}
}
std::cout << "lite compute:" << std::endl;
for (int i = 0; i < test_iter; i++) {
clock_t begin = clock();
// resize default linear
image_preprocess.imageFlip(src, resize_lite);
clock_t end = clock();
to_lite += (end - begin);
}
to_cv = 1000 * to_cv / CLOCKS_PER_SEC;
to_lite = 1000 * to_lite / CLOCKS_PER_SEC;
std::cout << "---opencv flip run time: " << to_cv
<< "ms, avg: " << to_cv / test_iter << std::endl;
std::cout << "---lite flip run time: " << to_lite
<< "ms, avg: " << to_lite / test_iter << std::endl;
std::cout << "compare diff: " << std::endl;
if (cv_run) {
resize_cv = im_resize.data;
double diff = compare_diff(resize_cv, resize_lite, out_size);
if (diff > 1) {
std::cout << "din: " << std::endl;
print_data(src, in_size);
std::cout << "cv out: " << std::endl;
print_data(resize_cv, out_size);
std::cout << "lite out: " << std::endl;
print_data(resize_lite, out_size);
return false;
} else {
// save_img
std::cout << "write image: " << std::endl;
std::string resize_name = dst_path + "/flip.jpg";
cv::Mat resize_mat;
int num = 1;
if (dstFormat == ImageFormat::BGR || dstFormat == ImageFormat::RGB) {
resize_mat = cv::Mat(dsth, dstw, CV_8UC3);
num = 3;
} else if (dstFormat == ImageFormat::BGRA ||
dstFormat == ImageFormat::RGBA) {
resize_mat = cv::Mat(dsth, dstw, CV_8UC4);
num = 4;
} else if (dstFormat == ImageFormat::GRAY) {
resize_mat = cv::Mat(dsth, dstw, CV_8UC1);
num = 1;
} else if (dstFormat == ImageFormat::NV12) {
resize_mat = cv::Mat(dsth, dstw, CV_8UC2);
num = 2;
} }
int size = 3 * srch * srcw; fill_with_mat(resize_mat, resize_lite, num);
if (srcFormat == ImageFormat::BGR || srcFormat == ImageFormat::RGB) { cv::imwrite(resize_name, resize_mat);
size = 3 * srch * srcw; std::cout << "flip successed!" << std::endl;
} else if (srcFormat == ImageFormat::GRAY) { return true;
size = srch * srcw; }
}
}
bool test_rotate(bool cv_run,
const uint8_t* src,
cv::Mat img,
ImagePreprocess image_preprocess,
int in_size,
int out_size,
float rotate,
ImageFormat dstFormat,
int dsth,
int dstw,
std::string dst_path,
int test_iter = 1) {
// out
uint8_t* resize_cv = new uint8_t[out_size];
uint8_t* resize_lite = new uint8_t[out_size];
cv::Mat im_resize;
double to_cv = 0.0;
double to_lite = 0.0;
std::cout << "opencv compute:" << std::endl;
if (cv_run) {
for (int i = 0; i < test_iter; i++) {
clock_t begin = clock();
// rotate 90
if (rotate == 90) {
cv::flip(img.t(), im_resize, 1);
} else if (rotate == 180) {
cv::flip(img, im_resize, -1);
} else if (rotate == 270) {
cv::flip(img.t(), im_resize, 0);
} }
uint8_t* src = img.data; clock_t end = clock();
to_cv += (end - begin);
}
}
// lite
std::cout << "lite compute:" << std::endl;
for (int i = 0; i < test_iter; i++) {
clock_t begin = clock();
// resize default linear
image_preprocess.imageRotate(src, resize_lite);
clock_t end = clock();
to_lite += (end - begin);
}
to_cv = 1000 * to_cv / CLOCKS_PER_SEC;
to_lite = 1000 * to_lite / CLOCKS_PER_SEC;
int out_size = srch * srcw; std::cout << "---opencv rotate run time: " << to_cv
int resize = dstw * dsth; << "ms, avg: " << to_cv / test_iter << std::endl;
std::cout << "---lite rotate run time: " << to_lite
<< "ms, avg: " << to_lite / test_iter << std::endl;
std::cout << "compare diff: " << std::endl;
if (cv_run) {
resize_cv = im_resize.data;
double diff = compare_diff(resize_cv, resize_lite, out_size);
if (diff > 1) {
std::cout << "din: " << std::endl;
print_data(src, in_size);
std::cout << "cv out: " << std::endl;
print_data(resize_cv, out_size);
std::cout << "lite out: " << std::endl;
print_data(resize_lite, out_size);
return false;
} else {
// save_img
std::cout << "write image: " << std::endl;
std::string resize_name = dst_path + "/rotate.jpg";
cv::Mat resize_mat;
int num = 1;
if (dstFormat == ImageFormat::BGR || dstFormat == ImageFormat::RGB) { if (dstFormat == ImageFormat::BGR || dstFormat == ImageFormat::RGB) {
out_size = 3 * srch * srcw; resize_mat = cv::Mat(dsth, dstw, CV_8UC3);
resize = 3 * dsth * dstw; num = 3;
} else if (dstFormat == ImageFormat::BGRA ||
dstFormat == ImageFormat::RGBA) {
resize_mat = cv::Mat(dsth, dstw, CV_8UC4);
num = 4;
} else if (dstFormat == ImageFormat::GRAY) { } else if (dstFormat == ImageFormat::GRAY) {
out_size = srch * srcw; resize_mat = cv::Mat(dsth, dstw, CV_8UC1);
resize = dsth * dstw; num = 1;
} else if (dstFormat == ImageFormat::NV12) {
resize_mat = cv::Mat(dsth, dstw, CV_8UC2);
num = 2;
} }
// out fill_with_mat(resize_mat, resize_lite, num);
uint8_t* lite_dst = new uint8_t[out_size]; cv::imwrite(resize_name, resize_mat);
uint8_t* resize_tmp = new uint8_t[resize]; std::cout << "rotate successed!" << std::endl;
uint8_t* tv_out_ratote = new uint8_t[out_size]; return true;
uint8_t* tv_out_flip = new uint8_t[out_size]; }
std::vector<int64_t> shape_out = {1, 3, srch, srcw}; }
}
input_tensor->Resize(shape_out); bool test_resize(bool cv_run,
Tensor dst_tensor = *input_tensor; const uint8_t* src,
std::cout << "opencv compute" << std::endl; cv::Mat img,
cv::Mat im_convert; ImagePreprocess image_preprocess,
cv::Mat im_resize; int in_size,
cv::Mat im_rotate; int out_size,
cv::Mat im_flip; ImageFormat dstFormat,
double to_1 = 0; int dsth,
double to_2 = 0; int dstw,
double to_3 = 0; std::string dst_path,
double to_4 = 0; int test_iter = 1) {
double to1 = 0; // out
for (int i = 0; i < test_iter; i++) { uint8_t* resize_cv = new uint8_t[out_size];
clock_t start = clock(); uint8_t* resize_lite = new uint8_t[out_size];
clock_t begin = clock(); cv::Mat im_resize;
// convert bgr-gray
if (dstFormat == srcFormat) {
im_convert = img;
} else if (dstFormat == ImageFormat::BGR &&
srcFormat == ImageFormat::GRAY) {
cv::cvtColor(img, im_convert, cv::COLOR_GRAY2BGR);
} else if (srcFormat == ImageFormat::BGR &&
dstFormat == ImageFormat::GRAY) {
cv::cvtColor(img, im_convert, cv::COLOR_BGR2GRAY);
} else if (dstFormat == srcFormat) {
printf("convert format error \n");
return;
}
clock_t end = clock();
to_1 += (end - begin);
begin = clock(); double to_cv = 0.0;
// resize default linear double to_lite = 0.0;
cv::resize(im_convert, im_resize, cv::Size(dstw, dsth), 0.f, 0.f); std::cout << "opencv compute:" << std::endl;
end = clock(); if (cv_run) {
to_2 += (end - begin); for (int i = 0; i < test_iter; i++) {
clock_t begin = clock();
// resize default linear
cv::resize(img, im_resize, cv::Size(dstw, dsth), 0.f, 0.f);
clock_t end = clock();
to_cv += (end - begin);
}
}
// param
std::cout << "lite compute:" << std::endl;
for (int i = 0; i < test_iter; i++) {
clock_t begin = clock();
// resize default linear
image_preprocess.imageResize(src, resize_lite);
clock_t end = clock();
to_lite += (end - begin);
}
to_cv = 1000 * to_cv / CLOCKS_PER_SEC;
to_lite = 1000 * to_lite / CLOCKS_PER_SEC;
begin = clock(); std::cout << "---opencv resize run time: " << to_cv
// rotate 90 << "ms, avg: " << to_cv / test_iter << std::endl;
if (rotate == 90) { std::cout << "---lite resize run time: " << to_lite
cv::flip(im_convert.t(), im_rotate, 1); << "ms, avg: " << to_lite / test_iter << std::endl;
} else if (rotate == 180) { std::cout << "compare diff: " << std::endl;
cv::flip(im_convert, im_rotate, -1);
} else if (rotate == 270) {
cv::flip(im_convert.t(), im_rotate, 0);
}
end = clock();
to_3 += (end - begin);
begin = clock(); if (cv_run) {
// flip resize_cv = im_resize.data;
cv::flip(im_convert, im_flip, flip); double diff = compare_diff(resize_cv, resize_lite, out_size);
end = clock(); if (diff > 1) {
to_4 += (end - begin); std::cout << "din: " << std::endl;
clock_t ovet = clock(); print_data(src, in_size);
to1 += (ovet - start); std::cout << "cv out: " << std::endl;
print_data(resize_cv, out_size);
std::cout << "lite out: " << std::endl;
print_data(resize_lite, out_size);
return false;
} else {
// save_img
std::cout << "write image: " << std::endl;
std::string resize_name = dst_path + "/resize.jpg";
cv::Mat resize_mat;
int num = 1;
if (dstFormat == ImageFormat::BGR || dstFormat == ImageFormat::RGB) {
resize_mat = cv::Mat(dsth, dstw, CV_8UC3);
num = 3;
} else if (dstFormat == ImageFormat::BGRA ||
dstFormat == ImageFormat::RGBA) {
resize_mat = cv::Mat(dsth, dstw, CV_8UC4);
num = 4;
} else if (dstFormat == ImageFormat::GRAY) {
resize_mat = cv::Mat(dsth, dstw, CV_8UC1);
num = 1;
} else if (dstFormat == ImageFormat::NV12) {
resize_mat = cv::Mat(dsth, dstw, CV_8UC2);
num = 2;
} }
fill_with_mat(resize_mat, resize_lite, num);
cv::imwrite(resize_name, resize_mat);
std::cout << "resize successed!" << std::endl;
return true;
}
}
}
void test_custom(bool has_img, // input is image
std::string img_path,
std::string in_txt,
std::string dst_path,
ImageFormat srcFormat,
ImageFormat dstFormat,
int srcw,
int srch,
int dstw,
int dsth,
float rotate,
FlipParam flip,
int test_iter = 1) {
// RGBA = 0, BGRA, RGB, BGR, GRAY, NV21 = 11, NV12,
cv::Mat img;
uint8_t* src = nullptr;
int in_size = 0;
if (has_img) {
if (srcFormat == ImageFormat::BGR || srcFormat == ImageFormat::RGB) {
img = imread(img_path, cv::IMREAD_COLOR);
} else if (srcFormat == ImageFormat::GRAY) {
img = imread(img_path, cv::IMREAD_GRAYSCALE);
} else {
printf("this format %d does not support \n", srcFormat);
return;
}
srcw = img.cols;
srch = img.rows;
src = img.data;
}
bool cv_run = true;
if (srcFormat == ImageFormat::GRAY) {
std::cout << "srcFormat: GRAY" << std::endl;
cv_run = false;
} else if (srcFormat == ImageFormat::BGR || srcFormat == ImageFormat::RGB) {
in_size = 3 * srch * srcw;
std::cout << "srcFormat: BGR/RGB" << std::endl;
} else if (srcFormat == ImageFormat::RGBA || srcFormat == ImageFormat::BGRA) {
in_size = 4 * srch * srcw;
std::cout << "srcFormat: BGRA/RGBA" << std::endl;
} else if (srcFormat == ImageFormat::NV12 || srcFormat == ImageFormat::NV21) {
in_size = (3 * srch * srcw) / 2;
cv_run = false;
std::cout << "srcFormat: NV12/NV12" << std::endl;
}
int out_size = dstw * dsth;
// out
if (dstFormat == ImageFormat::GRAY) {
std::cout << "dstFormat: GRAY" << std::endl;
} else if (dstFormat == ImageFormat::BGR || dstFormat == ImageFormat::RGB) {
out_size = 3 * dsth * dstw;
std::cout << "dstFormat: BGR/RGB" << std::endl;
} else if (dstFormat == ImageFormat::RGBA || dstFormat == ImageFormat::BGRA) {
out_size = 4 * dsth * dstw;
std::cout << "dstFormat: BGRA/RGBA" << std::endl;
} else if (dstFormat == ImageFormat::NV12 || dstFormat == ImageFormat::NV21) {
out_size = (3 * dsth * dstw) / 2;
cv_run = false;
std::cout << "dstFormat: NV12/NV12" << std::endl;
}
std::cout << "Paddle-lite compute" << std::endl; if (!has_img) {
double lite_to = 0; src = new uint8_t[in_size];
double lite_to_1 = 0; // read txt
double lite_to_2 = 0; FILE* fp = fopen(in_txt.c_str(), "r");
double lite_to_3 = 0; for (int i = 0; i < in_size; i++) {
double lite_to_4 = 0; fscanf(fp, "%d\n", &src[i]);
double lite_to_5 = 0; }
TransParam tparam; fclose(fp);
tparam.ih = srch; int num = 1;
tparam.iw = srcw; if (srcFormat == ImageFormat::GRAY) {
tparam.oh = dsth; img = cv::Mat(srch, srcw, CV_8UC1);
tparam.ow = dstw; } else if (srcFormat == ImageFormat::BGR || srcFormat == ImageFormat::RGB) {
tparam.flip_param = flip; img = cv::Mat(srch, srcw, CV_8UC3);
tparam.rotate_param = rotate; num = 3;
} else if (srcFormat == ImageFormat::BGRA ||
srcFormat == ImageFormat::RGBA) {
img = cv::Mat(srch, srcw, CV_8UC4);
num = 4;
} else if (srcFormat == ImageFormat::NV12 ||
srcFormat == ImageFormat::NV21) {
img = cv::Mat(srch, srcw, CV_8UC2);
num = 2;
std::cout << "CV not support NV12";
}
fill_with_mat(img, src, num);
std::string name = dst_path + "input.jpg";
cv::imwrite(name, img); // shurutup
}
ImagePreprocess image_preprocess(srcFormat, dstFormat, tparam); TransParam tparam;
tparam.ih = srch;
tparam.iw = srcw;
tparam.oh = srch;
tparam.ow = srcw;
tparam.flip_param = flip;
tparam.rotate_param = rotate;
for (int i = 0; i < test_iter; ++i) { TransParam tparam1;
clock_t start = clock(); tparam1.ih = srch;
clock_t begin = clock(); tparam1.iw = srcw;
image_preprocess.imageConvert(src, lite_dst); tparam1.oh = dsth;
clock_t end = clock(); tparam1.ow = dstw;
lite_to_1 += (end - begin); tparam1.flip_param = flip;
tparam1.rotate_param = rotate;
begin = clock(); ImagePreprocess image_preprocess(srcFormat, dstFormat, tparam);
image_preprocess.imageResize(lite_dst, resize_tmp); std::cout << "image convert testing";
end = clock(); bool re = test_convert(cv_run,
lite_to_2 += (end - begin); src,
img,
image_preprocess,
in_size,
out_size,
srcFormat,
dstFormat,
srch,
srcw,
dst_path,
test_iter);
if (!re) {
return;
}
std::cout << "image resize testing";
tparam.oh = dsth;
tparam.ow = dstw;
ImagePreprocess image_preprocess1(srcFormat, srcFormat, tparam1);
re = test_resize(cv_run,
src,
img,
image_preprocess1,
in_size,
out_size,
srcFormat,
dsth,
dstw,
dst_path,
test_iter);
if (!re) {
return;
}
begin = clock(); std::cout << "image rotate testing";
image_preprocess.imageRotate( if (rotate == 90 || rotate == 270) {
lite_dst, tv_out_ratote, (ImageFormat)dstFormat, srcw, srch, 90); tparam.oh = srcw;
end = clock(); tparam.ow = srch;
lite_to_3 += (end - begin); dsth = srcw;
dstw = srch;
} else {
tparam.oh = srch;
tparam.ow = srcw;
dsth = srch;
dstw = srcw;
}
ImagePreprocess image_preprocess2(srcFormat, srcFormat, tparam);
re = test_rotate(cv_run,
src,
img,
image_preprocess2,
in_size,
out_size,
rotate,
srcFormat,
dsth,
dstw,
dst_path,
test_iter);
if (!re) {
return;
}
tparam.oh = srch;
tparam.ow = srcw;
ImagePreprocess image_preprocess3(srcFormat, srcFormat, tparam);
std::cout << "image flip testing";
re = test_flip(cv_run,
src,
img,
image_preprocess3,
in_size,
out_size,
flip,
srcFormat,
srch,
srcw,
dst_path,
test_iter);
if (!re) {
return;
}
}
begin = clock(); #if 0
image_preprocess.imageFlip( void test_all_r(std::string dst_path, int test_iter = 1) {
lite_dst, tv_out_flip, (ImageFormat)dstFormat, srcw, srch, flip); // RGBA = 0, BGRA, RGB, BGR, GRAY, NV21 = 11, NV12,
end = clock(); cv::Mat img;
lite_to_4 += (end - begin); uint8_t* src = nullptr;
int in_size = 0;
for (auto& srcFormat : {1, 3, 4, 11}) {
for (auto& dstFormat : {1, 3, 4, 11}) {
for (auto& srcw : {10, 112, 200}) {
for (auto& srch : {10, 224, 400}) {
for (auto& dstw : {12, 224, 180}) {
for (auto& dsth : {12, 224, 320}) {
for (auto& flip : {-1, 0, 1}) {
for (auto& rotate : {90, 180, 270}) {
TransParam tparam;
tparam.ih = srch;
tparam.iw = srcw;
tparam.oh = srch;
tparam.ow = srcw;
tparam.flip_param = (FlipParam)flip;
tparam.rotate_param = rotate;
clock_t over = clock(); TransParam tparam1;
lite_to += (over - start); tparam1.ih = srch;
tparam1.iw = srcw;
tparam1.oh = dsth;
tparam1.ow = dstw;
tparam1.flip_param = (FlipParam)flip;
tparam.rotate_param = rotate;
begin = clock(); ImagePreprocess image_preprocess(
image_preprocess.image2Tensor(lite_dst, (ImageFormat)srcFormat, (ImageFormat)dstFormat, tparam);
&dst_tensor, ImagePreprocess image_preprocess1(
(ImageFormat)dstFormat, (ImageFormat)srcFormat, (ImageFormat)srcFormat, tparam1);
srcw, ImagePreprocess image_preprocess2(
srch, (ImageFormat)srcFormat, (ImageFormat)srcFormat, tparam);
layout, int h = srch;
means, int w = srcw;
scales); if (rotate == 90 || rotate == 270) {
end = clock(); tparam.oh = srcw;
lite_to_5 += (end - begin); h = srcw;
} tparam.ow = srch;
to_1 = 1000 * to_1 / CLOCKS_PER_SEC; w = srch;
to_2 = 1000 * to_2 / CLOCKS_PER_SEC; }
to_3 = 1000 * to_3 / CLOCKS_PER_SEC; ImagePreprocess image_preprocess3(
to_4 = 1000 * to_4 / CLOCKS_PER_SEC; (ImageFormat)srcFormat, (ImageFormat)srcFormat, tparam);
to1 = 1000 * to1 / CLOCKS_PER_SEC; int in_size = srcw * srch;
std::cout << "opencv convert run time: " << to_1 int out_size = dstw * dsth;
<< "ms, avg: " << to_1 / test_iter << std::endl; if (srcFormat == ImageFormat::GRAY) {
std::cout << "opencv resize run time: " << to_2 std::cout << "srcFormat: GRAY" << std::endl;
<< "ms, avg: " << to_2 / test_iter << std::endl; } else if (srcFormat == ImageFormat::BGR ||
std::cout << "opencv rotate run time: " << to_3 srcFormat == ImageFormat::RGB) {
<< "ms, avg: " << to_3 / test_iter << std::endl; in_size = 3 * srch * srcw;
std::cout << "opencv flip time: " << to_4 std::cout << "srcFormat: BGR/RGB" << std::endl;
<< "ms, avg: " << to_4 / test_iter << std::endl; } else if (srcFormat == ImageFormat::RGBA ||
std::cout << "opencv total run time: " << to1 srcFormat == ImageFormat::BGRA) {
<< "ms, avg: " << to1 / test_iter << std::endl; in_size = 4 * srch * srcw;
std::cout << "------" << std::endl; std::cout << "srcFormat: BGRA/RGBA" << std::endl;
} else if (srcFormat == ImageFormat::NV12 ||
srcFormat == ImageFormat::NV21) {
in_size = (3 * srch * srcw) / 2;
std::cout << "srcFormat: NV12/NV12" << std::endl;
}
// out
if (dstFormat == ImageFormat::GRAY) {
std::cout << "dstFormat: GRAY" << std::endl;
} else if (dstFormat == ImageFormat::BGR ||
dstFormat == ImageFormat::RGB) {
out_size = 3 * dsth * dstw;
std::cout << "dstFormat: BGR/RGB" << std::endl;
} else if (dstFormat == ImageFormat::RGBA ||
dstFormat == ImageFormat::BGRA) {
out_size = 4 * dsth * dstw;
std::cout << "dstFormat: BGRA/RGBA" << std::endl;
} else if (dstFormat == ImageFormat::NV12 ||
dstFormat == ImageFormat::NV21) {
out_size = (3 * dsth * dstw) / 2;
std::cout << "dstFormat: NV12/NV12" << std::endl;
}
// init
uint8_t* src = new uint8_t[in_size];
for (int i = 0; i < in_size; i++) {
src[i] = i % 255;
}
cv::Mat img;
int num = 1;
bool cv_run = true;
if (srcFormat == ImageFormat::GRAY) {
img = cv::Mat(srch, srcw, CV_8UC1);
cv_run = false;
} else if (srcFormat == ImageFormat::BGR ||
srcFormat == ImageFormat::RGB) {
img = cv::Mat(srch, srcw, CV_8UC3);
num = 3;
} else if (srcFormat == ImageFormat::BGRA ||
srcFormat == ImageFormat::RGBA) {
img = cv::Mat(srch, srcw, CV_8UC4);
num = 4;
} else if (srcFormat == ImageFormat::NV12 ||
srcFormat == ImageFormat::NV21) {
img = cv::Mat(srch, srcw, CV_8UC2);
num = 2;
cv_run = false;
}
fill_with_mat(img, src, num);
std::string name = dst_path + "input.jpg";
cv::imwrite(name, img); // shurutup
// convert
bool convert = true;
if (srcFormat == 11 || dstFormat == 11) {
// NV12, cv not support
convert = false;
cv_run = false;
}
if (convert) {
std::cout << "image convert testing";
bool re = test_convert(cv_run,
src,
img,
image_preprocess,
in_size,
out_size,
(ImageFormat)srcFormat,
(ImageFormat)dstFormat,
srch,
srcw,
dst_path,
test_iter);
if (!re) {
return;
}
}
lite_to_1 = 1000 * lite_to_1 / CLOCKS_PER_SEC; // resize
lite_to_2 = 1000 * lite_to_2 / CLOCKS_PER_SEC; std::cout << "image resize testing";
lite_to_3 = 1000 * lite_to_3 / CLOCKS_PER_SEC; bool re = test_resize(cv_run,
lite_to_4 = 1000 * lite_to_4 / CLOCKS_PER_SEC; src,
lite_to_5 = 1000 * lite_to_5 / CLOCKS_PER_SEC; img,
lite_to = 1000 * lite_to / CLOCKS_PER_SEC; image_preprocess1,
std::cout << "lite convert run time: " << lite_to_1 in_size,
<< "ms, avg: " << lite_to_1 / test_iter << std::endl; out_size,
std::cout << "lite resize run time: " << lite_to_2 (ImageFormat)srcFormat,
<< "ms, avg: " << lite_to_2 / test_iter << std::endl; dsth,
std::cout << "lite rotate run time: " << lite_to_3 dstw,
<< "ms, avg: " << lite_to_3 / test_iter << std::endl; dst_path,
std::cout << "lite flip time: " << lite_to_4 test_iter);
<< "ms, avg: " << lite_to_4 / test_iter << std::endl; if (convert && !re) {
std::cout << "lite total run time: " << lite_to return;
<< "ms, avg: " << lite_to / test_iter << std::endl; }
std::cout << "lite img2tensor time: " << lite_to_5 // rotate
<< "ms, avg: " << lite_to_5 / test_iter << std::endl; std::cout << "image rotate testing";
std::cout << "------" << std::endl;
double max_ratio = 0; re = test_rotate(cv_run,
double max_diff = 0; src,
const double eps = 1e-6f; img,
// save_img image_preprocess3,
std::cout << "write image: " << std::endl; in_size,
std::string resize_name = dst_path + "/resize.jpg"; out_size,
std::string convert_name = dst_path + "/convert.jpg"; rotate,
std::string rotate_name = dst_path + "/rotate.jpg"; (ImageFormat)srcFormat,
std::string flip_name = dst_path + "/flip.jpg"; h,
cv::Mat resize_mat(dsth, dstw, CV_8UC3); w,
cv::Mat convert_mat(srch, srcw, CV_8UC3); dst_path,
cv::Mat rotate_mat; test_iter);
if (rotate == 90 || rotate == 270) { if (convert && !re) {
rotate_mat = cv::Mat(srcw, srch, CV_8UC3); return;
} else { }
rotate_mat = cv::Mat(srch, srcw, CV_8UC3); // flip
std::cout << "image rotate testing";
re = test_flip(cv_run,
src,
img,
image_preprocess2,
in_size,
out_size,
(FlipParam)flip,
(ImageFormat)srcFormat,
srch,
srcw,
dst_path,
test_iter);
if (convert && !re) {
return;
}
}
}
}
}
}
} }
cv::Mat flip_mat(srch, srcw, CV_8UC3);
fill_with_mat(resize_mat, resize_tmp);
fill_with_mat(convert_mat, lite_dst);
fill_with_mat(rotate_mat, tv_out_ratote);
fill_with_mat(flip_mat, tv_out_flip);
cv::imwrite(convert_name, convert_mat);
cv::imwrite(resize_name, resize_mat);
cv::imwrite(rotate_name, rotate_mat);
cv::imwrite(flip_name, flip_mat);
delete[] lite_dst;
delete[] resize_tmp;
delete[] tv_out_ratote;
delete[] tv_out_flip;
} }
} }
} }
#endif
int main(int argc, char** argv) { int main(int argc, char** argv) {
if (argc < 7) { if (argc < 7) {
std::cerr << "[ERROR] usage: " << argv[0] std::cerr << "[ERROR] usage: " << argv[0]
<< " image_path dst_apth srcFormat dstFormat width height\n"; << " has_img image_path/txt_path dst_apth srcFormat dstFormat "
"dstw dsth "
<< "[options] srcw srch flip rotate test_iter\n ";
exit(1); exit(1);
} }
std::string image_path = argv[1]; bool has_img = atoi(argv[1]);
std::string dst_path = argv[2]; std::string path = argv[2];
int srcFormat = atoi(argv[3]); std::string dst_path = argv[3];
int dstFormat = atoi(argv[4]); int srcFormat = atoi(argv[4]);
int width = atoi(argv[5]); int dstFormat = atoi(argv[5]);
int height = atoi(argv[6]); int dstw = atoi(argv[6]);
int dsth = atoi(argv[7]);
int srcw = 100;
int srch = 100;
int flip = -1; int flip = -1;
float rotate = 90; float rotate = 90;
int layout = 1; int test_iter = 10;
std::string model_file = "mobilenet_v1.nb"; if (!has_img) {
if (argc > 7) { std::cout << "It needs srcw and srch";
model_file = argv[7]; srcw = atoi(argv[8]);
} srch = atoi(argv[9]);
if (argc > 8) { if (argc > 10) {
flip = atoi(argv[8]); flip = atoi(argv[10]);
} }
if (argc > 9) { if (argc > 11) {
rotate = atoi(argv[9]); rotate = atoi(argv[11]);
} }
if (argc > 10) { if (argc > 12) {
layout = atoi(argv[10]); test_iter = atoi(argv[12]);
}
} else {
if (argc > 8) {
flip = atoi(argv[8]);
}
if (argc > 9) {
rotate = atoi(argv[9]);
}
if (argc > 10) {
test_iter = atoi(argv[10]);
}
} }
test_img({3}, test_custom(has_img,
{1, 2, 4}, path,
image_path, path,
dst_path, dst_path,
(ImageFormat)srcFormat, (ImageFormat)srcFormat,
(ImageFormat)dstFormat, (ImageFormat)dstFormat,
width, srcw,
height, srch,
rotate, dstw,
(FlipParam)flip, dsth,
(LayoutType)layout, rotate,
model_file, (FlipParam)flip,
20); test_iter);
#if 0
test_all_r(dst_path, test_iter);
#endif
return 0; return 0;
} }
...@@ -59,9 +59,11 @@ void ConvCompute<PRECISION(kFloat), PRECISION(kFloat)>::PrepareForRun() { ...@@ -59,9 +59,11 @@ void ConvCompute<PRECISION(kFloat), PRECISION(kFloat)>::PrepareForRun() {
bool flag_dw_3x3 = (kw == 3) && (kh == 3) && (stride == 1 || stride == 2); bool flag_dw_3x3 = (kw == 3) && (kh == 3) && (stride == 1 || stride == 2);
bool flag_dw_5x5 = (kw == 5) && (kh == 5) && (stride == 1 || stride == 2); bool flag_dw_5x5 = (kw == 5) && (kh == 5) && (stride == 1 || stride == 2);
#ifdef LITE_WITH_ARM_CLANG // clang #ifdef __aarch64__
flag_dw_3x3 = #else
bool flag =
(stride == 1 && (paddings[0] > 1 || paddings[2] > 1)) ? false : true; (stride == 1 && (paddings[0] > 1 || paddings[2] > 1)) ? false : true;
flag_dw_3x3 = flag_dw_3x3 && flag;
#endif #endif
bool flag_dw = flag_dw_3x3 || flag_dw_5x5; bool flag_dw = flag_dw_3x3 || flag_dw_5x5;
......
...@@ -307,7 +307,7 @@ void test_conv_fp32(const std::vector<DDim>& input_dims, ...@@ -307,7 +307,7 @@ void test_conv_fp32(const std::vector<DDim>& input_dims,
#endif // LITE_WITH_ARM #endif // LITE_WITH_ARM
// TODO(chenjiaoAngel): fix multi-threds, diff: 3x3 depthwise conv // TODO(chenjiaoAngel): fix multi-threds, diff: 3x3 depthwise conv
#if 1 // 3x3dw #if 0 // 3x3dw
TEST(TestConv3x3DW, test_conv3x3_depthwise) { TEST(TestConv3x3DW, test_conv3x3_depthwise) {
if (FLAGS_basic_test) { if (FLAGS_basic_test) {
for (auto& stride : {1, 2}) { for (auto& stride : {1, 2}) {
...@@ -325,6 +325,13 @@ TEST(TestConv3x3DW, test_conv3x3_depthwise) { ...@@ -325,6 +325,13 @@ TEST(TestConv3x3DW, test_conv3x3_depthwise) {
dims.push_back(DDim({batch, c, h, h})); dims.push_back(DDim({batch, c, h, h}));
} }
} }
#ifdef __aarch64__
#else
if (stride == 1 && (pad_bottom == 2 || pad_right == 2 ||
pad_top == 2 || pad_left == 2)) {
continue;
}
#endif
const float leakey_relu_scale = 8.88; const float leakey_relu_scale = 8.88;
test_conv_fp32(dims, test_conv_fp32(dims,
weights_dim, weights_dim,
......
...@@ -125,7 +125,7 @@ void resize(const uint8_t* src, ...@@ -125,7 +125,7 @@ void resize(const uint8_t* src,
srch / 2, srch / 2,
w, w,
tmp, tmp,
num, 2,
scale_x, scale_x,
scale_y, scale_y,
xofs1, xofs1,
...@@ -146,6 +146,8 @@ void resize(const uint8_t* src, ...@@ -146,6 +146,8 @@ void resize(const uint8_t* src,
xofs = xofs1; xofs = xofs1;
yofs = yofs1; yofs = yofs1;
ialpha = ialpha1; ialpha = ialpha1;
num = 2;
sy = yofs1[dy - orih];
} }
// hresize two rows // hresize two rows
...@@ -154,8 +156,8 @@ void resize(const uint8_t* src, ...@@ -154,8 +156,8 @@ void resize(const uint8_t* src,
const int16_t* ialphap = ialpha; const int16_t* ialphap = ialpha;
int16_t* rows0p = rowsbuf0; int16_t* rows0p = rowsbuf0;
int16_t* rows1p = rowsbuf1; int16_t* rows1p = rowsbuf1;
for (int dx = 0; dx < dstw; dx++) { for (int dx = 0; dx < w_out; dx += num) {
int sx = xofs[dx]; int sx = xofs[dx / num];
int16_t a0 = ialphap[0]; int16_t a0 = ialphap[0];
int16_t a1 = ialphap[1]; int16_t a1 = ialphap[1];
...@@ -314,7 +316,6 @@ void compute_xy(int srcw, ...@@ -314,7 +316,6 @@ void compute_xy(int srcw,
float a0 = (1.f - fx) * resize_coef_scale; float a0 = (1.f - fx) * resize_coef_scale;
float a1 = fx * resize_coef_scale; float a1 = fx * resize_coef_scale;
ialpha[dx * 2] = SATURATE_CAST_SHORT(a0); ialpha[dx * 2] = SATURATE_CAST_SHORT(a0);
ialpha[dx * 2 + 1] = SATURATE_CAST_SHORT(a1); ialpha[dx * 2 + 1] = SATURATE_CAST_SHORT(a1);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册