mirror of
https://github.com/PaddlePaddle/FastDeploy.git
synced 2025-10-05 16:48:03 +08:00
Optimize ocr system code (#209)
* Support PPYOLOE plus model * Optimize ocr system code * modify example code * fix patchelf of openvino * optimize demo code of ocr * remove debug code * update demo code of ocr Co-authored-by: Jack Zhou <zhoushunjie@baidu.com>
This commit is contained in:
@@ -199,13 +199,8 @@ if(ENABLE_TRT_BACKEND)
|
|||||||
list(APPEND ALL_DEPLOY_SRCS ${DEPLOY_TRT_SRCS})
|
list(APPEND ALL_DEPLOY_SRCS ${DEPLOY_TRT_SRCS})
|
||||||
find_library(TRT_INFER_LIB nvinfer ${TRT_DIRECTORY}/lib)
|
find_library(TRT_INFER_LIB nvinfer ${TRT_DIRECTORY}/lib)
|
||||||
find_library(TRT_ONNX_LIB nvonnxparser ${TRT_DIRECTORY}/lib)
|
find_library(TRT_ONNX_LIB nvonnxparser ${TRT_DIRECTORY}/lib)
|
||||||
if(NOT WIN32)
|
|
||||||
find_library(TRT_CAFFE_LIB nvcaffe_parser ${TRT_DIRECTORY}/lib)
|
|
||||||
else()
|
|
||||||
set(TRT_CAFFE_LIB "")
|
|
||||||
endif()
|
|
||||||
find_library(TRT_PLUGIN_LIB nvinfer_plugin ${TRT_DIRECTORY}/lib)
|
find_library(TRT_PLUGIN_LIB nvinfer_plugin ${TRT_DIRECTORY}/lib)
|
||||||
list(APPEND DEPEND_LIBS ${TRT_INFER_LIB} ${TRT_ONNX_LIB} ${TRT_CAFFE_LIB} ${TRT_PLUGIN_LIB})
|
list(APPEND DEPEND_LIBS ${TRT_INFER_LIB} ${TRT_ONNX_LIB} ${TRT_PLUGIN_LIB})
|
||||||
|
|
||||||
if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/third_libs/install/tensorrt")
|
if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/third_libs/install/tensorrt")
|
||||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/third_libs/install/tensorrt")
|
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/third_libs/install/tensorrt")
|
||||||
|
@@ -70,12 +70,7 @@ if(WITH_GPU)
|
|||||||
find_library(TRT_INFER_LIB nvinfer ${CMAKE_CURRENT_LIST_DIR}/third_libs/install/tensorrt/lib)
|
find_library(TRT_INFER_LIB nvinfer ${CMAKE_CURRENT_LIST_DIR}/third_libs/install/tensorrt/lib)
|
||||||
find_library(TRT_ONNX_LIB nvonnxparser ${CMAKE_CURRENT_LIST_DIR}/third_libs/install/tensorrt/lib)
|
find_library(TRT_ONNX_LIB nvonnxparser ${CMAKE_CURRENT_LIST_DIR}/third_libs/install/tensorrt/lib)
|
||||||
find_library(TRT_PLUGIN_LIB nvinfer_plugin ${CMAKE_CURRENT_LIST_DIR}/third_libs/install/tensorrt/lib)
|
find_library(TRT_PLUGIN_LIB nvinfer_plugin ${CMAKE_CURRENT_LIST_DIR}/third_libs/install/tensorrt/lib)
|
||||||
if (NOT WIN32)
|
list(APPEND FASTDEPLOY_LIBS ${TRT_INFER_LIB} ${TRT_ONNX_LIB} ${TRT_PLUGIN_LIB})
|
||||||
find_library(TRT_CAFFE_LIB nvcaffe_parser ${CMAKE_CURRENT_LIST_DIR}/third_libs/install/tensorrt/lib)
|
|
||||||
list(APPEND FASTDEPLOY_LIBS ${TRT_INFER_LIB} ${TRT_ONNX_LIB} ${TRT_CAFFE_LIB} ${TRT_PLUGIN_LIB})
|
|
||||||
else()
|
|
||||||
list(APPEND FASTDEPLOY_LIBS ${TRT_INFER_LIB} ${TRT_ONNX_LIB} ${TRT_PLUGIN_LIB})
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
15
build_scripts/patch_lib.sh
Executable file
15
build_scripts/patch_lib.sh
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
patchelf --set-rpath '${ORIGIN}' $1/*.so*
|
@@ -144,6 +144,9 @@ def process_libraries(current_dir):
|
|||||||
for flt in filters:
|
for flt in filters:
|
||||||
if f.count(flt) > 0:
|
if f.count(flt) > 0:
|
||||||
remain = False
|
remain = False
|
||||||
|
filename = os.path.split(f)[-1]
|
||||||
|
if filename in ["libnvinfer_plugin.so", "libnvinfer_plugin.so.8.4.1", "libnvinfer.so", "libnvinfer.so.8.4.1", "libnvonnxparser.so", "libnvonnxparser.so.8.4.1", "libnvparsers.so", "libnvparsers.so.8.4.1"]:
|
||||||
|
continue
|
||||||
if remain:
|
if remain:
|
||||||
package_data.append(
|
package_data.append(
|
||||||
os.path.relpath(f, os.path.join(current_dir, "fastdeploy")))
|
os.path.relpath(f, os.path.join(current_dir, "fastdeploy")))
|
||||||
|
@@ -261,12 +261,12 @@ bool Runtime::Init(const RuntimeOption& _option) {
|
|||||||
FDASSERT(option.device == Device::CPU || option.device == Device::GPU,
|
FDASSERT(option.device == Device::CPU || option.device == Device::GPU,
|
||||||
"Backend::ORT only supports Device::CPU/Device::GPU.");
|
"Backend::ORT only supports Device::CPU/Device::GPU.");
|
||||||
CreateOrtBackend();
|
CreateOrtBackend();
|
||||||
FDINFO << "Runtime initialized with Backend::ORT." << std::endl;
|
FDINFO << "Runtime initialized with Backend::ORT in device " << Str(option.device) << "." << std::endl;
|
||||||
} else if (option.backend == Backend::TRT) {
|
} else if (option.backend == Backend::TRT) {
|
||||||
FDASSERT(option.device == Device::GPU,
|
FDASSERT(option.device == Device::GPU,
|
||||||
"Backend::TRT only supports Device::GPU.");
|
"Backend::TRT only supports Device::GPU.");
|
||||||
CreateTrtBackend();
|
CreateTrtBackend();
|
||||||
FDINFO << "Runtime initialized with Backend::TRT." << std::endl;
|
FDINFO << "Runtime initialized with Backend::TRT in device " << Str(option.device) << "." << std::endl;
|
||||||
} else if (option.backend == Backend::PDINFER) {
|
} else if (option.backend == Backend::PDINFER) {
|
||||||
FDASSERT(option.device == Device::CPU || option.device == Device::GPU,
|
FDASSERT(option.device == Device::CPU || option.device == Device::GPU,
|
||||||
"Backend::TRT only supports Device::CPU/Device::GPU.");
|
"Backend::TRT only supports Device::CPU/Device::GPU.");
|
||||||
@@ -274,12 +274,12 @@ bool Runtime::Init(const RuntimeOption& _option) {
|
|||||||
option.model_format == Frontend::PADDLE,
|
option.model_format == Frontend::PADDLE,
|
||||||
"Backend::PDINFER only supports model format of Frontend::PADDLE.");
|
"Backend::PDINFER only supports model format of Frontend::PADDLE.");
|
||||||
CreatePaddleBackend();
|
CreatePaddleBackend();
|
||||||
FDINFO << "Runtime initialized with Backend::PDINFER." << std::endl;
|
FDINFO << "Runtime initialized with Backend::PDINFER in device " << Str(option.device) << "." << std::endl;
|
||||||
} else if (option.backend == Backend::OPENVINO) {
|
} else if (option.backend == Backend::OPENVINO) {
|
||||||
FDASSERT(option.device == Device::CPU,
|
FDASSERT(option.device == Device::CPU,
|
||||||
"Backend::OPENVINO only supports Device::CPU");
|
"Backend::OPENVINO only supports Device::CPU");
|
||||||
CreateOpenVINOBackend();
|
CreateOpenVINOBackend();
|
||||||
FDINFO << "Runtime initialized with Backend::OPENVINO." << std::endl;
|
FDINFO << "Runtime initialized with Backend::OPENVINO in device " << Str(option.device) << "." << std::endl;
|
||||||
} else {
|
} else {
|
||||||
FDERROR << "Runtime only support "
|
FDERROR << "Runtime only support "
|
||||||
"Backend::ORT/Backend::TRT/Backend::PDINFER as backend now."
|
"Backend::ORT/Backend::TRT/Backend::PDINFER as backend now."
|
||||||
|
@@ -72,6 +72,14 @@ std::string DetectionResult::Str() {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OCRResult::Clear() {
|
||||||
|
boxes.clear();
|
||||||
|
text.clear();
|
||||||
|
rec_scores.clear();
|
||||||
|
cls_scores.clear();
|
||||||
|
cls_labels.clear();
|
||||||
|
}
|
||||||
|
|
||||||
FaceDetectionResult::FaceDetectionResult(const FaceDetectionResult& res) {
|
FaceDetectionResult::FaceDetectionResult(const FaceDetectionResult& res) {
|
||||||
boxes.assign(res.boxes.begin(), res.boxes.end());
|
boxes.assign(res.boxes.begin(), res.boxes.end());
|
||||||
landmarks.assign(res.landmarks.begin(), res.landmarks.end());
|
landmarks.assign(res.landmarks.begin(), res.landmarks.end());
|
||||||
|
@@ -71,6 +71,8 @@ struct FASTDEPLOY_DECL OCRResult : public BaseResult {
|
|||||||
|
|
||||||
ResultType type = ResultType::OCR;
|
ResultType type = ResultType::OCR;
|
||||||
|
|
||||||
|
void Clear();
|
||||||
|
|
||||||
std::string Str();
|
std::string Str();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -26,10 +26,10 @@ Classifier::Classifier(const std::string& model_file,
|
|||||||
const RuntimeOption& custom_option,
|
const RuntimeOption& custom_option,
|
||||||
const Frontend& model_format) {
|
const Frontend& model_format) {
|
||||||
if (model_format == Frontend::ONNX) {
|
if (model_format == Frontend::ONNX) {
|
||||||
valid_cpu_backends = {Backend::ORT}; // 指定可用的CPU后端
|
valid_cpu_backends = {Backend::ORT, Backend::OPENVINO}; // 指定可用的CPU后端
|
||||||
valid_gpu_backends = {Backend::ORT, Backend::TRT}; // 指定可用的GPU后端
|
valid_gpu_backends = {Backend::ORT, Backend::TRT}; // 指定可用的GPU后端
|
||||||
} else {
|
} else {
|
||||||
valid_cpu_backends = {Backend::PDINFER, Backend::ORT};
|
valid_cpu_backends = {Backend::PDINFER, Backend::ORT, Backend::OPENVINO};
|
||||||
valid_gpu_backends = {Backend::PDINFER, Backend::TRT, Backend::ORT};
|
valid_gpu_backends = {Backend::PDINFER, Backend::TRT, Backend::ORT};
|
||||||
}
|
}
|
||||||
runtime_option = custom_option;
|
runtime_option = custom_option;
|
||||||
|
@@ -26,10 +26,10 @@ DBDetector::DBDetector(const std::string& model_file,
|
|||||||
const RuntimeOption& custom_option,
|
const RuntimeOption& custom_option,
|
||||||
const Frontend& model_format) {
|
const Frontend& model_format) {
|
||||||
if (model_format == Frontend::ONNX) {
|
if (model_format == Frontend::ONNX) {
|
||||||
valid_cpu_backends = {Backend::ORT}; // 指定可用的CPU后端
|
valid_cpu_backends = {Backend::ORT, Backend::OPENVINO}; // 指定可用的CPU后端
|
||||||
valid_gpu_backends = {Backend::ORT, Backend::TRT}; // 指定可用的GPU后端
|
valid_gpu_backends = {Backend::ORT, Backend::TRT}; // 指定可用的GPU后端
|
||||||
} else {
|
} else {
|
||||||
valid_cpu_backends = {Backend::PDINFER, Backend::ORT};
|
valid_cpu_backends = {Backend::PDINFER, Backend::ORT, Backend::OPENVINO};
|
||||||
valid_gpu_backends = {Backend::PDINFER, Backend::ORT, Backend::TRT};
|
valid_gpu_backends = {Backend::PDINFER, Backend::ORT, Backend::TRT};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,10 +23,10 @@ void BindPPOCRSystemv3(pybind11::module& m) {
|
|||||||
.def(pybind11::init<fastdeploy::vision::ocr::DBDetector*,
|
.def(pybind11::init<fastdeploy::vision::ocr::DBDetector*,
|
||||||
fastdeploy::vision::ocr::Classifier*,
|
fastdeploy::vision::ocr::Classifier*,
|
||||||
fastdeploy::vision::ocr::Recognizer*>())
|
fastdeploy::vision::ocr::Recognizer*>())
|
||||||
|
.def(pybind11::init<fastdeploy::vision::ocr::DBDetector*,
|
||||||
|
fastdeploy::vision::ocr::Recognizer*>())
|
||||||
.def("predict", [](application::ocrsystem::PPOCRSystemv3& self,
|
.def("predict", [](application::ocrsystem::PPOCRSystemv3& self,
|
||||||
pybind11::array& data) {
|
pybind11::array& data) {
|
||||||
|
|
||||||
auto mat = PyArrayToCvMat(data);
|
auto mat = PyArrayToCvMat(data);
|
||||||
vision::OCRResult res;
|
vision::OCRResult res;
|
||||||
self.Predict(&mat, &res);
|
self.Predict(&mat, &res);
|
||||||
@@ -38,14 +38,13 @@ void BindPPOCRSystemv2(pybind11::module& m) {
|
|||||||
// OCRSys
|
// OCRSys
|
||||||
pybind11::class_<application::ocrsystem::PPOCRSystemv2, FastDeployModel>(
|
pybind11::class_<application::ocrsystem::PPOCRSystemv2, FastDeployModel>(
|
||||||
m, "PPOCRSystemv2")
|
m, "PPOCRSystemv2")
|
||||||
|
|
||||||
.def(pybind11::init<fastdeploy::vision::ocr::DBDetector*,
|
.def(pybind11::init<fastdeploy::vision::ocr::DBDetector*,
|
||||||
fastdeploy::vision::ocr::Classifier*,
|
fastdeploy::vision::ocr::Classifier*,
|
||||||
fastdeploy::vision::ocr::Recognizer*>())
|
fastdeploy::vision::ocr::Recognizer*>())
|
||||||
|
.def(pybind11::init<fastdeploy::vision::ocr::DBDetector*,
|
||||||
|
fastdeploy::vision::ocr::Recognizer*>())
|
||||||
.def("predict", [](application::ocrsystem::PPOCRSystemv2& self,
|
.def("predict", [](application::ocrsystem::PPOCRSystemv2& self,
|
||||||
pybind11::array& data) {
|
pybind11::array& data) {
|
||||||
|
|
||||||
auto mat = PyArrayToCvMat(data);
|
auto mat = PyArrayToCvMat(data);
|
||||||
vision::OCRResult res;
|
vision::OCRResult res;
|
||||||
self.Predict(&mat, &res);
|
self.Predict(&mat, &res);
|
||||||
|
@@ -19,92 +19,88 @@
|
|||||||
namespace fastdeploy {
|
namespace fastdeploy {
|
||||||
namespace application {
|
namespace application {
|
||||||
namespace ocrsystem {
|
namespace ocrsystem {
|
||||||
PPOCRSystemv2::PPOCRSystemv2(fastdeploy::vision::ocr::DBDetector* ocr_det,
|
PPOCRSystemv2::PPOCRSystemv2(fastdeploy::vision::ocr::DBDetector* det_model,
|
||||||
fastdeploy::vision::ocr::Classifier* ocr_cls,
|
fastdeploy::vision::ocr::Classifier* cls_model,
|
||||||
fastdeploy::vision::ocr::Recognizer* ocr_rec)
|
fastdeploy::vision::ocr::Recognizer* rec_model)
|
||||||
: detector(ocr_det), classifier(ocr_cls), recognizer(ocr_rec) {}
|
: detector_(det_model), classifier_(cls_model), recognizer_(rec_model) {
|
||||||
|
recognizer_->rec_image_shape[1] = 32;
|
||||||
void PPOCRSystemv2::Detect(cv::Mat* img,
|
|
||||||
fastdeploy::vision::OCRResult* result) {
|
|
||||||
std::vector<std::array<int, 8>> boxes;
|
|
||||||
|
|
||||||
this->detector->Predict(img, &boxes);
|
|
||||||
|
|
||||||
result->boxes = boxes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPOCRSystemv2::Recognize(cv::Mat* img,
|
PPOCRSystemv2::PPOCRSystemv2(fastdeploy::vision::ocr::DBDetector* det_model,
|
||||||
|
fastdeploy::vision::ocr::Recognizer* rec_model)
|
||||||
|
: detector_(det_model), recognizer_(rec_model) {
|
||||||
|
recognizer_->rec_image_shape[1] = 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PPOCRSystemv2::Detect(cv::Mat* img,
|
||||||
|
fastdeploy::vision::OCRResult* result) {
|
||||||
|
if (!detector_->Predict(img, &(result->boxes))) {
|
||||||
|
FDERROR << "There's error while detecting image in PPOCRSystem." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vision::ocr::SortBoxes(result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PPOCRSystemv2::Recognize(cv::Mat* img,
|
||||||
fastdeploy::vision::OCRResult* result) {
|
fastdeploy::vision::OCRResult* result) {
|
||||||
std::tuple<std::string, float> rec_result;
|
std::tuple<std::string, float> rec_result;
|
||||||
this->recognizer->rec_image_shape[1] = 32;
|
if (!recognizer_->Predict(img, &rec_result)) {
|
||||||
this->recognizer->Predict(img, &rec_result);
|
FDERROR << "There's error while recognizing image in PPOCRSystem." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
result->text.push_back(std::get<0>(rec_result));
|
result->text.push_back(std::get<0>(rec_result));
|
||||||
result->rec_scores.push_back(std::get<1>(rec_result));
|
result->rec_scores.push_back(std::get<1>(rec_result));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPOCRSystemv2::Classify(cv::Mat* img,
|
bool PPOCRSystemv2::Classify(cv::Mat* img,
|
||||||
fastdeploy::vision::OCRResult* result) {
|
fastdeploy::vision::OCRResult* result) {
|
||||||
std::tuple<int, float> cls_result;
|
std::tuple<int, float> cls_result;
|
||||||
|
|
||||||
this->classifier->Predict(img, &cls_result);
|
if (!classifier_->Predict(img, &cls_result)) {
|
||||||
|
FDERROR << "There's error while classifying image in PPOCRSystem." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
result->cls_labels.push_back(std::get<0>(cls_result));
|
result->cls_labels.push_back(std::get<0>(cls_result));
|
||||||
result->cls_scores.push_back(std::get<1>(cls_result));
|
result->cls_scores.push_back(std::get<1>(cls_result));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPOCRSystemv2::Predict(cv::Mat* img,
|
bool PPOCRSystemv2::Predict(cv::Mat* img,
|
||||||
fastdeploy::vision::OCRResult* result) {
|
fastdeploy::vision::OCRResult* result) {
|
||||||
if (this->detector->initialized == 0) { //没det
|
result->Clear();
|
||||||
//输入单张“小图片”给分类器
|
if (nullptr != detector_ && !Detect(img, result)) {
|
||||||
if (this->classifier->initialized != 0) {
|
FDERROR << "Failed to detect image." << std::endl;
|
||||||
this->Classify(img, result);
|
return false;
|
||||||
//摆正单张图像
|
|
||||||
if ((result->cls_labels)[0] % 2 == 1 &&
|
|
||||||
(result->cls_scores)[0] > this->classifier->cls_thresh) {
|
|
||||||
cv::rotate(*img, *img, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//输入单张“小图片”给识别器
|
|
||||||
if (this->recognizer->initialized != 0) {
|
|
||||||
this->Recognize(img, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
//从DET模型开始
|
|
||||||
//一张图,会输出多个“小图片”,送给后续模型
|
|
||||||
this->Detect(img, result);
|
|
||||||
// crop image
|
|
||||||
std::vector<cv::Mat> img_list;
|
|
||||||
|
|
||||||
for (int j = 0; j < (result->boxes).size(); j++) {
|
|
||||||
cv::Mat crop_img;
|
|
||||||
crop_img =
|
|
||||||
fastdeploy::vision::ocr::GetRotateCropImage(*img, (result->boxes)[j]);
|
|
||||||
img_list.push_back(crop_img);
|
|
||||||
}
|
|
||||||
// cls
|
|
||||||
if (this->classifier->initialized != 0) {
|
|
||||||
for (int i = 0; i < img_list.size(); i++) {
|
|
||||||
this->Classify(&img_list[0], result);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < img_list.size(); i++) {
|
|
||||||
if ((result->cls_labels)[i] % 2 == 1 &&
|
|
||||||
(result->cls_scores)[i] > this->classifier->cls_thresh) {
|
|
||||||
std::cout << "Rotate this image " << std::endl;
|
|
||||||
cv::rotate(img_list[i], img_list[i], 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// rec
|
|
||||||
if (this->recognizer->initialized != 0) {
|
|
||||||
for (int i = 0; i < img_list.size(); i++) {
|
|
||||||
this->Recognize(&img_list[i], result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get croped images by detection result
|
||||||
|
std::vector<cv::Mat> image_list;
|
||||||
|
for (size_t i = 0; i < result->boxes.size(); ++i) {
|
||||||
|
auto crop_im = vision::ocr::GetRotateCropImage(*img, (result->boxes)[i]);
|
||||||
|
image_list.push_back(crop_im);
|
||||||
|
}
|
||||||
|
if (result->boxes.size() == 0) {
|
||||||
|
image_list.push_back(*img);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < image_list.size(); ++i) {
|
||||||
|
if (nullptr != classifier_ && !Classify(&(image_list[i]), result)) {
|
||||||
|
FDERROR << "Failed to classify croped image of index " << i << "." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (nullptr != classifier_ && result->cls_labels[i] % 2 == 1 && result->cls_scores[i] > classifier_->cls_thresh) {
|
||||||
|
cv::rotate(image_list[i], image_list[i], 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nullptr != recognizer_ && !Recognize(&(image_list[i]), result)) {
|
||||||
|
FDERROR << "Failed to recgnize croped image of index " << i << "." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -31,20 +31,23 @@ namespace ocrsystem {
|
|||||||
|
|
||||||
class FASTDEPLOY_DECL PPOCRSystemv2 : public FastDeployModel {
|
class FASTDEPLOY_DECL PPOCRSystemv2 : public FastDeployModel {
|
||||||
public:
|
public:
|
||||||
PPOCRSystemv2(fastdeploy::vision::ocr::DBDetector* ocr_det = nullptr,
|
PPOCRSystemv2(fastdeploy::vision::ocr::DBDetector* det_model,
|
||||||
fastdeploy::vision::ocr::Classifier* ocr_cls = nullptr,
|
fastdeploy::vision::ocr::Classifier* cls_model,
|
||||||
fastdeploy::vision::ocr::Recognizer* ocr_rec = nullptr);
|
fastdeploy::vision::ocr::Recognizer* rec_model);
|
||||||
|
|
||||||
fastdeploy::vision::ocr::DBDetector* detector = nullptr;
|
PPOCRSystemv2(fastdeploy::vision::ocr::DBDetector* det_model,
|
||||||
fastdeploy::vision::ocr::Classifier* classifier = nullptr;
|
fastdeploy::vision::ocr::Recognizer* rec_model);
|
||||||
fastdeploy::vision::ocr::Recognizer* recognizer = nullptr;
|
|
||||||
|
|
||||||
bool Predict(cv::Mat* img, fastdeploy::vision::OCRResult* result);
|
virtual bool Predict(cv::Mat* img, fastdeploy::vision::OCRResult* result);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
void Detect(cv::Mat* img, fastdeploy::vision::OCRResult* result);
|
fastdeploy::vision::ocr::DBDetector* detector_ = nullptr;
|
||||||
void Recognize(cv::Mat* img, fastdeploy::vision::OCRResult* result);
|
fastdeploy::vision::ocr::Classifier* classifier_ = nullptr;
|
||||||
void Classify(cv::Mat* img, fastdeploy::vision::OCRResult* result);
|
fastdeploy::vision::ocr::Recognizer* recognizer_ = nullptr;
|
||||||
|
|
||||||
|
virtual bool Detect(cv::Mat* img, fastdeploy::vision::OCRResult* result);
|
||||||
|
virtual bool Recognize(cv::Mat* img, fastdeploy::vision::OCRResult* result);
|
||||||
|
virtual bool Classify(cv::Mat* img, fastdeploy::vision::OCRResult* result);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ocrsystem
|
} // namespace ocrsystem
|
||||||
|
@@ -1,114 +0,0 @@
|
|||||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// 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 "fastdeploy/vision/ocr/ppocr/ppocr_system_v3.h"
|
|
||||||
#include "fastdeploy/utils/perf.h"
|
|
||||||
#include "fastdeploy/vision/ocr/ppocr/utils/ocr_utils.h"
|
|
||||||
|
|
||||||
namespace fastdeploy {
|
|
||||||
namespace application {
|
|
||||||
namespace ocrsystem {
|
|
||||||
PPOCRSystemv3::PPOCRSystemv3(fastdeploy::vision::ocr::DBDetector* ocr_det,
|
|
||||||
fastdeploy::vision::ocr::Classifier* ocr_cls,
|
|
||||||
fastdeploy::vision::ocr::Recognizer* ocr_rec)
|
|
||||||
: detector(ocr_det), classifier(ocr_cls), recognizer(ocr_rec) {}
|
|
||||||
|
|
||||||
void PPOCRSystemv3::Detect(cv::Mat* img,
|
|
||||||
fastdeploy::vision::OCRResult* result) {
|
|
||||||
std::vector<std::array<int, 8>> boxes_result;
|
|
||||||
|
|
||||||
this->detector->Predict(img, &boxes_result);
|
|
||||||
|
|
||||||
result->boxes = boxes_result;
|
|
||||||
|
|
||||||
fastdeploy::vision::ocr::SortBoxes(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PPOCRSystemv3::Recognize(cv::Mat* img,
|
|
||||||
fastdeploy::vision::OCRResult* result) {
|
|
||||||
std::tuple<std::string, float> rec_result;
|
|
||||||
|
|
||||||
this->recognizer->Predict(img, &rec_result);
|
|
||||||
|
|
||||||
result->text.push_back(std::get<0>(rec_result));
|
|
||||||
result->rec_scores.push_back(std::get<1>(rec_result));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PPOCRSystemv3::Classify(cv::Mat* img,
|
|
||||||
fastdeploy::vision::OCRResult* result) {
|
|
||||||
std::tuple<int, float> cls_result;
|
|
||||||
|
|
||||||
this->classifier->Predict(img, &cls_result);
|
|
||||||
|
|
||||||
result->cls_labels.push_back(std::get<0>(cls_result));
|
|
||||||
result->cls_scores.push_back(std::get<1>(cls_result));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PPOCRSystemv3::Predict(cv::Mat* img,
|
|
||||||
fastdeploy::vision::OCRResult* result) {
|
|
||||||
if (this->detector->initialized == 0) { //没det
|
|
||||||
//输入单张“小图片”给分类器
|
|
||||||
if (this->classifier->initialized != 0) {
|
|
||||||
this->Classify(img, result);
|
|
||||||
//摆正单张图像
|
|
||||||
if ((result->cls_labels)[0] % 2 == 1 &&
|
|
||||||
(result->cls_scores)[0] > this->classifier->cls_thresh) {
|
|
||||||
cv::rotate(*img, *img, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//输入单张“小图片”给识别器
|
|
||||||
if (this->recognizer->initialized != 0) {
|
|
||||||
this->Recognize(img, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
//从DET模型开始
|
|
||||||
//一张图,会输出多个“小图片”,送给后续模型
|
|
||||||
this->Detect(img, result);
|
|
||||||
// crop image
|
|
||||||
std::vector<cv::Mat> img_list;
|
|
||||||
|
|
||||||
for (int j = 0; j < (result->boxes).size(); j++) {
|
|
||||||
cv::Mat crop_img;
|
|
||||||
crop_img =
|
|
||||||
fastdeploy::vision::ocr::GetRotateCropImage(*img, (result->boxes)[j]);
|
|
||||||
img_list.push_back(crop_img);
|
|
||||||
}
|
|
||||||
// cls
|
|
||||||
if (this->classifier->initialized != 0) {
|
|
||||||
for (int i = 0; i < img_list.size(); i++) {
|
|
||||||
this->Classify(&img_list[i], result);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < img_list.size(); i++) {
|
|
||||||
if ((result->cls_labels)[i] % 2 == 1 &&
|
|
||||||
(result->cls_scores)[i] > this->classifier->cls_thresh) {
|
|
||||||
cv::rotate(img_list[i], img_list[i], 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// rec
|
|
||||||
if (this->recognizer->initialized != 0) {
|
|
||||||
for (int i = 0; i < img_list.size(); i++) {
|
|
||||||
this->Recognize(&img_list[i], result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namesapce ocrsystem
|
|
||||||
} // namespace application
|
|
||||||
} // namespace fastdeploy
|
|
@@ -14,37 +14,25 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include "fastdeploy/vision/ocr/ppocr/ppocr_system_v2.h"
|
||||||
|
|
||||||
#include "fastdeploy/fastdeploy_model.h"
|
|
||||||
#include "fastdeploy/vision/common/processors/transform.h"
|
|
||||||
#include "fastdeploy/vision/common/result.h"
|
|
||||||
|
|
||||||
#include "fastdeploy/vision/ocr/ppocr/classifier.h"
|
|
||||||
#include "fastdeploy/vision/ocr/ppocr/dbdetector.h"
|
|
||||||
#include "fastdeploy/vision/ocr/ppocr/recognizer.h"
|
|
||||||
#include "fastdeploy/vision/ocr/ppocr/utils/ocr_postprocess_op.h"
|
|
||||||
|
|
||||||
namespace fastdeploy {
|
namespace fastdeploy {
|
||||||
namespace application {
|
namespace application {
|
||||||
namespace ocrsystem {
|
namespace ocrsystem {
|
||||||
|
|
||||||
class FASTDEPLOY_DECL PPOCRSystemv3 : public FastDeployModel {
|
class FASTDEPLOY_DECL PPOCRSystemv3 : public PPOCRSystemv2 {
|
||||||
public:
|
public:
|
||||||
PPOCRSystemv3(fastdeploy::vision::ocr::DBDetector* ocr_det = nullptr,
|
PPOCRSystemv3(fastdeploy::vision::ocr::DBDetector* det_model,
|
||||||
fastdeploy::vision::ocr::Classifier* ocr_cls = nullptr,
|
fastdeploy::vision::ocr::Classifier* cls_model,
|
||||||
fastdeploy::vision::ocr::Recognizer* ocr_rec = nullptr);
|
fastdeploy::vision::ocr::Recognizer* rec_model) : PPOCRSystemv2(det_model, cls_model, rec_model) {
|
||||||
|
// The only difference between v2 and v3
|
||||||
|
recognizer_->rec_image_shape[1] = 48;
|
||||||
|
}
|
||||||
|
|
||||||
fastdeploy::vision::ocr::DBDetector* detector = nullptr;
|
PPOCRSystemv3(fastdeploy::vision::ocr::DBDetector* det_model,
|
||||||
fastdeploy::vision::ocr::Classifier* classifier = nullptr;
|
fastdeploy::vision::ocr::Recognizer* rec_model) : PPOCRSystemv2(det_model, rec_model) {
|
||||||
fastdeploy::vision::ocr::Recognizer* recognizer = nullptr;
|
recognizer_->rec_image_shape[1] = 48;
|
||||||
|
}
|
||||||
bool Predict(cv::Mat* img, fastdeploy::vision::OCRResult* result);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void Detect(cv::Mat* img, fastdeploy::vision::OCRResult* result);
|
|
||||||
void Recognize(cv::Mat* img, fastdeploy::vision::OCRResult* result);
|
|
||||||
void Classify(cv::Mat* img, fastdeploy::vision::OCRResult* result);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ocrsystem
|
} // namespace ocrsystem
|
||||||
|
@@ -44,11 +44,11 @@ Recognizer::Recognizer(const std::string& model_file,
|
|||||||
const RuntimeOption& custom_option,
|
const RuntimeOption& custom_option,
|
||||||
const Frontend& model_format) {
|
const Frontend& model_format) {
|
||||||
if (model_format == Frontend::ONNX) {
|
if (model_format == Frontend::ONNX) {
|
||||||
valid_cpu_backends = {Backend::ORT}; // 指定可用的CPU后端
|
valid_cpu_backends = {Backend::ORT, Backend::OPENVINO}; // 指定可用的CPU后端
|
||||||
valid_gpu_backends = {Backend::ORT, Backend::TRT}; // 指定可用的GPU后端
|
valid_gpu_backends = {Backend::ORT, Backend::TRT}; // 指定可用的GPU后端
|
||||||
} else {
|
} else {
|
||||||
// NOTE:此模型暂不支持paddle-inference-Gpu推理
|
// NOTE:此模型暂不支持paddle-inference-Gpu推理
|
||||||
valid_cpu_backends = {Backend::ORT, Backend::PDINFER};
|
valid_cpu_backends = {Backend::ORT, Backend::PDINFER, Backend::OPENVINO};
|
||||||
valid_gpu_backends = {Backend::ORT, Backend::TRT};
|
valid_gpu_backends = {Backend::ORT, Backend::TRT};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,6 +32,10 @@ bool CompareBox(const std::array<int, 8>& result1,
|
|||||||
void SortBoxes(OCRResult* result) {
|
void SortBoxes(OCRResult* result) {
|
||||||
std::sort(result->boxes.begin(), result->boxes.end(), CompareBox);
|
std::sort(result->boxes.begin(), result->boxes.end(), CompareBox);
|
||||||
|
|
||||||
|
if (result->boxes.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < result->boxes.size() - 1; i++) {
|
for (int i = 0; i < result->boxes.size() - 1; i++) {
|
||||||
if (abs(result->boxes[i + 1][1] - result->boxes[i][1]) < 10 &&
|
if (abs(result->boxes[i + 1][1] - result->boxes[i][1]) < 10 &&
|
||||||
(result->boxes[i + 1][0] < result->boxes[i][0])) {
|
(result->boxes[i + 1][0] < result->boxes[i][0])) {
|
||||||
|
84
docs/api/runtime/runtime.md
Normal file
84
docs/api/runtime/runtime.md
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
# Runtime
|
||||||
|
|
||||||
|
在配置`RuntimeOption`后,即可基于不同后端在不同硬件上创建Runtime用于模型推理。
|
||||||
|
|
||||||
|
## Python 类
|
||||||
|
|
||||||
|
```
|
||||||
|
class Runtime(runtime_option)
|
||||||
|
```
|
||||||
|
**参数**
|
||||||
|
> * **runtime_option**(fastdeploy.RuntimeOption): 配置好的RuntimeOption类实例
|
||||||
|
|
||||||
|
### 成员函数
|
||||||
|
|
||||||
|
```
|
||||||
|
infer(data)
|
||||||
|
```
|
||||||
|
根据输入数据进行模型推理
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
|
||||||
|
> * **data**(dict({str: np.ndarray}): 输入数据,字典dict类型,key为输入名,value为np.ndarray数据类型
|
||||||
|
|
||||||
|
**返回值**
|
||||||
|
|
||||||
|
返回list, list的长度与原始模型输出个数一致;list中元素为np.ndarray类型
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
num_inputs()
|
||||||
|
```
|
||||||
|
返回模型的输入个数
|
||||||
|
|
||||||
|
```
|
||||||
|
num_outputs()
|
||||||
|
```
|
||||||
|
返回模型的输出个数
|
||||||
|
|
||||||
|
|
||||||
|
## C++ 类
|
||||||
|
|
||||||
|
```
|
||||||
|
class Runtime
|
||||||
|
```
|
||||||
|
|
||||||
|
### 成员函数
|
||||||
|
|
||||||
|
```
|
||||||
|
bool Init(const RuntimeOption& runtime_option)
|
||||||
|
```
|
||||||
|
模型加载初始化
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
|
||||||
|
> * **runtime_option**: 配置好的RuntimeOption实例
|
||||||
|
|
||||||
|
**返回值**
|
||||||
|
|
||||||
|
初始化成功返回true,否则返回false
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
bool Infer(vector<FDTensor>& inputs, vector<FDTensor>* outputs)
|
||||||
|
```
|
||||||
|
根据输入进行推理,并将结果写回到outputs
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
|
||||||
|
> * **inputs**: 输入数据
|
||||||
|
> * **outputs**: 输出数据
|
||||||
|
|
||||||
|
**返回值**
|
||||||
|
|
||||||
|
推理成功返回true,否则返回false
|
||||||
|
|
||||||
|
```
|
||||||
|
int NumInputs()
|
||||||
|
```
|
||||||
|
返回模型输入个数
|
||||||
|
|
||||||
|
```
|
||||||
|
input NumOutputs()
|
||||||
|
```
|
||||||
|
返回模型输出个数
|
233
docs/api/runtime/runtime_option.md
Normal file
233
docs/api/runtime/runtime_option.md
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
# RuntimeOption
|
||||||
|
|
||||||
|
`RuntimeOption`用于配置模型在不同后端、硬件上的推理参数。
|
||||||
|
|
||||||
|
## Python 类
|
||||||
|
|
||||||
|
```
|
||||||
|
class RuntimeOption()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 成员函数
|
||||||
|
|
||||||
|
```
|
||||||
|
set_model_path(model_file, params_file="", model_format="paddle")
|
||||||
|
```
|
||||||
|
设定加载的模型路径
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
|
||||||
|
> * **model_file**(str): 模型文件路径
|
||||||
|
> * **params_file**(str): 参数文件路径,当为onnx模型格式时,无需指定
|
||||||
|
> * **model_format**(str): 模型格式,支持paddle, onnx, 默认paddle
|
||||||
|
|
||||||
|
```
|
||||||
|
use_gpu(device_id=0)
|
||||||
|
```
|
||||||
|
设定使用GPU推理
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
|
||||||
|
> * **device_id**(int): 环境中存在多个GPU卡时,此参数指定推理的卡,默认为0
|
||||||
|
|
||||||
|
```
|
||||||
|
use_cpu()
|
||||||
|
```
|
||||||
|
设定使用CPU推理
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
set_cpu_thread_num(thread_num=-1)
|
||||||
|
```
|
||||||
|
设置CPU上推理时线程数量
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
|
||||||
|
> * **thread_num**(int): 线程数量,当小于或等于0时为后端自动分配,默认-1
|
||||||
|
|
||||||
|
```
|
||||||
|
use_paddle_backend()
|
||||||
|
```
|
||||||
|
使用Paddle Inference后端进行推理,支持CPU/GPU,支持Paddle模型格式
|
||||||
|
|
||||||
|
```
|
||||||
|
use_ort_backend()
|
||||||
|
```
|
||||||
|
使用ONNX Runtime后端进行推理,支持CPU/GPU,支持Paddle/ONNX模型格式
|
||||||
|
|
||||||
|
```
|
||||||
|
use_trt_backend()
|
||||||
|
```
|
||||||
|
使用TensorRT后端进行推理,支持GPU,支持Paddle/ONNX模型格式
|
||||||
|
|
||||||
|
```
|
||||||
|
use_openvino_backend()
|
||||||
|
```
|
||||||
|
使用OpenVINO后端进行推理,支持CPU, 支持Paddle/ONNX模型格式
|
||||||
|
|
||||||
|
```
|
||||||
|
enable_paddle_mkldnn()
|
||||||
|
disable_paddle_mkldnn()
|
||||||
|
```
|
||||||
|
当使用Paddle Inference后端时,通过此开关开启或关闭CPU上MKLDNN推理加速,后端默认为开启
|
||||||
|
|
||||||
|
```
|
||||||
|
enable_paddle_log_info()
|
||||||
|
disable_paddle_log_info()
|
||||||
|
```
|
||||||
|
当使用Paddle Inference后端时,通过此开关开启或关闭模型加载时的优化日志,后端默认为关闭
|
||||||
|
|
||||||
|
```
|
||||||
|
set_paddle_mkldnn_cache_size(cache_size)
|
||||||
|
```
|
||||||
|
当使用Paddle Inference后端时,通过此接口控制MKLDNN加速时的Shape缓存大小
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
> * **cache_size**(int): 缓存大小
|
||||||
|
|
||||||
|
```
|
||||||
|
set_trt_input_shape(tensor_name, min_shape, opt_shape=None, max_shape=None)
|
||||||
|
```
|
||||||
|
当使用TensorRT后端时,通过此接口设置模型各个输入的Shape范围,当只设置min_shape时,会自动将opt_shape和max_shape设定为与min_shape一致。
|
||||||
|
|
||||||
|
此接口用户也可以无需自行调用,FastDeploy在推理过程中,会根据推理真实数据自动更新Shape范围,但每次遇到新的shape更新范围后,会重新构造后端引擎,带来一定的耗时。可能过此接口提前配置,来避免推理过程中的引擎重新构建。
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
> * **tensor_name**(str): 需要设定输入范围的tensor名
|
||||||
|
> * **min_shape(list of int): 对应tensor的最小shape,例如[1, 3, 224, 224]
|
||||||
|
> * **opt_shape(list of int): 对应tensor的最常用shape,例如[2, 3, 224, 224], 当为None时,即保持与min_shape一致,默认为None
|
||||||
|
> * **max_shape(list of int): 对应tensor的最大shape,例如[8, 3, 224, 224], 当为None时,即保持与min_shape一致,默认为None
|
||||||
|
|
||||||
|
```
|
||||||
|
set_trt_cache_file(cache_file_path)
|
||||||
|
```
|
||||||
|
当使用TensorRT后端时,通过此接口将构建好的TensorRT模型引擎缓存到指定路径,或跳过构造引擎步骤,直接加载本地缓存的TensorRT模型
|
||||||
|
- 当调用此接口,且`cache_file_path`不存在时,FastDeploy将构建TensorRT模型,并将构建好的模型保持至`cache_file_path`
|
||||||
|
- 当调用此接口,且`cache_file_path`存在时,FastDeploy将直接加载`cache_file_path`存储的已构建好的TensorRT模型,从而大大减少模型加载初始化的耗时
|
||||||
|
|
||||||
|
通过此接口,可以在第二次运行代码时,加速模型加载初始化的时间,但因此也需注意,如需您修改了模型加载配置,例如TensorRT的max_workspace_size,或重新设置了`set_trt_input_shape`,以及更换了原始的paddle或onnx模型,需先删除已缓存在本地的`cache_file_path`文件,避免重新加载旧的缓存,影响程序正确性。
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
> * **cache_file_path**(str): 缓存文件路径,例如`/Downloads/resnet50.trt`
|
||||||
|
|
||||||
|
```
|
||||||
|
enable_trt_fp16()
|
||||||
|
disable_trt_fp16()
|
||||||
|
```
|
||||||
|
当使用TensorRT后端时,通过此接口开启或关闭半精度推理加速,会带来明显的性能提升,但并非所有GPU都支持半精度推理。 在不支持半精度推理的GPU上,将会回退到FP32推理,并给出提示`Detected FP16 is not supported in the current GPU, will use FP32 instead.`
|
||||||
|
|
||||||
|
## C++ 结构体
|
||||||
|
|
||||||
|
```
|
||||||
|
struct RuntimeOption
|
||||||
|
```
|
||||||
|
|
||||||
|
### 成员函数
|
||||||
|
|
||||||
|
```
|
||||||
|
void SetModelPath(const string& model_file, const string& params_file = "", const string& model_format = "paddle")
|
||||||
|
```
|
||||||
|
设定加载的模型路径
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
|
||||||
|
> * **model_file**: 模型文件路径
|
||||||
|
> * **params_file**: 参数文件路径,当为onnx模型格式时,指定为""即可
|
||||||
|
> * **model_format**: 模型格式,支持"paddle", "onnx", 默认"paddle"
|
||||||
|
|
||||||
|
```
|
||||||
|
void UseGpu(int device_id = 0)
|
||||||
|
```
|
||||||
|
设定使用GPU推理
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
|
||||||
|
> * **device_id**: 环境中存在多个GPU卡时,此参数指定推理的卡,默认为0
|
||||||
|
|
||||||
|
```
|
||||||
|
void UseCpu()
|
||||||
|
```
|
||||||
|
设定使用CPU推理
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
void SetCpuThreadNum(int thread_num=-1)
|
||||||
|
```
|
||||||
|
设置CPU上推理时线程数量
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
|
||||||
|
> * **thread_num**: 线程数量,当小于或等于0时为后端自动分配,默认-1
|
||||||
|
|
||||||
|
```
|
||||||
|
void UsePaddleBackend()
|
||||||
|
```
|
||||||
|
使用Paddle Inference后端进行推理,支持CPU/GPU,支持Paddle模型格式
|
||||||
|
|
||||||
|
```
|
||||||
|
void UseOrtBackend()
|
||||||
|
```
|
||||||
|
使用ONNX Runtime后端进行推理,支持CPU/GPU,支持Paddle/ONNX模型格式
|
||||||
|
|
||||||
|
```
|
||||||
|
void UseTrtBackend()
|
||||||
|
```
|
||||||
|
使用TensorRT后端进行推理,支持GPU,支持Paddle/ONNX模型格式
|
||||||
|
|
||||||
|
```
|
||||||
|
void UseOpenVINOBackend()
|
||||||
|
```
|
||||||
|
使用OpenVINO后端进行推理,支持CPU, 支持Paddle/ONNX模型格式
|
||||||
|
|
||||||
|
```
|
||||||
|
void EnablePaddleMKLDNN()
|
||||||
|
void DisablePaddleMKLDNN()
|
||||||
|
```
|
||||||
|
当使用Paddle Inference后端时,通过此开关开启或关闭CPU上MKLDNN推理加速,后端默认为开启
|
||||||
|
|
||||||
|
```
|
||||||
|
void EnablePaddleLogInfo()
|
||||||
|
void DisablePaddleLogInfo()
|
||||||
|
```
|
||||||
|
当使用Paddle Inference后端时,通过此开关开启或关闭模型加载时的优化日志,后端默认为关闭
|
||||||
|
|
||||||
|
```
|
||||||
|
void SetPaddleMKLDNNCacheSize(int cache_size)
|
||||||
|
```
|
||||||
|
当使用Paddle Inference后端时,通过此接口控制MKLDNN加速时的Shape缓存大小
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
> * **cache_size**: 缓存大小
|
||||||
|
|
||||||
|
```
|
||||||
|
void SetTrtInputShape(const string& tensor_name, const vector<int32_t>& min_shape,
|
||||||
|
const vector<int32_t>& opt_shape = vector<int32_t>(),
|
||||||
|
const vector<int32_t>& opt_shape = vector<int32_t>())
|
||||||
|
```
|
||||||
|
当使用TensorRT后端时,通过此接口设置模型各个输入的Shape范围,当只设置min_shape时,会自动将opt_shape和max_shape设定为与min_shape一致。
|
||||||
|
|
||||||
|
此接口用户也可以无需自行调用,FastDeploy在推理过程中,会根据推理真实数据自动更新Shape范围,但每次遇到新的shape更新范围后,会重新构造后端引擎,带来一定的耗时。可能过此接口提前配置,来避免推理过程中的引擎重新构建。
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
> * **tensor_name**: 需要设定输入范围的tensor名
|
||||||
|
> * **min_shape: 对应tensor的最小shape,例如[1, 3, 224, 224]
|
||||||
|
> * **opt_shape: 对应tensor的最常用shape,例如[2, 3, 224, 224], 当为默认参数即空vector时,则视为保持与min_shape一致,默认为空vector
|
||||||
|
> * **max_shape: 对应tensor的最大shape,例如[8, 3, 224, 224], 当为默认参数即空vector时,则视为保持与min_shape一致,默认为空vector
|
||||||
|
|
||||||
|
```
|
||||||
|
void SetTrtCacheFile(const string& cache_file_path)
|
||||||
|
```
|
||||||
|
当使用TensorRT后端时,通过此接口将构建好的TensorRT模型引擎缓存到指定路径,或跳过构造引擎步骤,直接加载本地缓存的TensorRT模型
|
||||||
|
- 当调用此接口,且`cache_file_path`不存在时,FastDeploy将构建TensorRT模型,并将构建好的模型保持至`cache_file_path`
|
||||||
|
- 当调用此接口,且`cache_file_path`存在时,FastDeploy将直接加载`cache_file_path`存储的已构建好的TensorRT模型,从而大大减少模型加载初始化的耗时
|
||||||
|
|
||||||
|
通过此接口,可以在第二次运行代码时,加速模型加载初始化的时间,但因此也需注意,如需您修改了模型加载配置,例如TensorRT的max_workspace_size,或重新设置了`SetTrtInputShape`,以及更换了原始的paddle或onnx模型,需先删除已缓存在本地的`cache_file_path`文件,避免重新加载旧的缓存,影响程序正确性。
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
> * **cache_file_path**: 缓存文件路径,例如`/Downloads/resnet50.trt`
|
||||||
|
|
||||||
|
```
|
||||||
|
void EnableTrtFp16()
|
||||||
|
void DisableTrtFp16()
|
||||||
|
```
|
||||||
|
当使用TensorRT后端时,通过此接口开启或关闭半精度推理加速,会带来明显的性能提升,但并非所有GPU都支持半精度推理。 在不支持半精度推理的GPU上,将会回退到FP32推理,并给出提示`Detected FP16 is not supported in the current GPU, will use FP32 instead.`
|
@@ -11,11 +11,13 @@
|
|||||||
|:---- | :--- | :--- |
|
|:---- | :--- | :--- |
|
||||||
| ENABLE_ORT_BACKEND | 启用ONNXRuntime推理后端,默认ON | 默认支持CPU,开启WITH_GPU后,同时支持GPU |
|
| ENABLE_ORT_BACKEND | 启用ONNXRuntime推理后端,默认ON | 默认支持CPU,开启WITH_GPU后,同时支持GPU |
|
||||||
| ENABLE_PADDLE_BACKEND | 启用Paddle Inference推理后端,默认OFF | 默认支持CPU,开启WITH_GPU后,同时支持GPU |
|
| ENABLE_PADDLE_BACKEND | 启用Paddle Inference推理后端,默认OFF | 默认支持CPU,开启WITH_GPU后,同时支持GPU |
|
||||||
|
| ENABLE_OPENVINO_BACKEND | 启用OpenVINO推理后端,默认OFF | 仅支持 CPU |
|
||||||
| ENABLE_TRT_BACKEND | 启用TensorRT推理后端,默认OFF | 仅支持GPU |
|
| ENABLE_TRT_BACKEND | 启用TensorRT推理后端,默认OFF | 仅支持GPU |
|
||||||
| WITH_GPU | 是否开启GPU使用,默认OFF | 当设为TRUE,编译后将支持Nvidia GPU部署 |
|
| WITH_GPU | 是否开启GPU使用,默认OFF | 当设为TRUE,编译后将支持Nvidia GPU部署 |
|
||||||
| CUDA_DIRECTORY | 指定编译时的CUDA路径,默认为/usr/local/cuda | CUDA 11.2及以上 |
|
| CUDA_DIRECTORY | 指定编译时的CUDA路径,默认为/usr/local/cuda | CUDA 11.2及以上 |
|
||||||
| TRT_DIRECTORY | 当启用TensorRT推理后端时,需通过此参数指定TensorRT路径 | TensorRT 8.4及以上 |
|
| TRT_DIRECTORY | 当启用TensorRT推理后端时,需通过此参数指定TensorRT路径 | TensorRT 8.4及以上 |
|
||||||
| ENABLE_VISION | 启用视觉模型模块,默认为ON | |
|
| ENABLE_VISION | 启用视觉模型模块,默认为ON | |
|
||||||
|
| ENABLE_TEXT | 启用文本模型模块,默认为ON | |
|
||||||
|
|
||||||
|
|
||||||
FastDeploy支持在编译时,用户选择自己的后端进行编译, 目前已经支持Paddle Inference、ONNXRuntime、TensorRT(加载ONNX格式)。FastDeploy已支持的模型已完成在不同后端上的验证工作,会自动根据编译时支持的后端进行选择,如若无可用后端则会给出相应提示(如YOLOv7目前仅支持ONNXRuntime/TensorRT后端,如若编译时未开启这两个后端,则推理时会提示无可用后端)。
|
FastDeploy支持在编译时,用户选择自己的后端进行编译, 目前已经支持Paddle Inference、ONNXRuntime、TensorRT(加载ONNX格式)。FastDeploy已支持的模型已完成在不同后端上的验证工作,会自动根据编译时支持的后端进行选择,如若无可用后端则会给出相应提示(如YOLOv7目前仅支持ONNXRuntime/TensorRT后端,如若编译时未开启这两个后端,则推理时会提示无可用后端)。
|
||||||
|
18
docs/runtime/README.md
Normal file
18
docs/runtime/README.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# FastDeploy推理后端
|
||||||
|
|
||||||
|
FastDeploy当前已集成多种推理后端,如下表格列出FastDeploy集成的各后端,与在FastDeploy中其支持的平台、硬件等信息
|
||||||
|
|
||||||
|
| 推理后端 | 支持平台 | 支持硬件 | 支持模型格式 |
|
||||||
|
| :------- | :------- | :------- | :---- | :----- |
|
||||||
|
| Paddle Inference | Windows(x64)/Linux(x64) | GPU/CPU | Paddle |
|
||||||
|
| ONNX Runtime | Windows(x64)/Linux(x64/aarch64) | GPU/CPU | Paddle/ONNX |
|
||||||
|
| TensorRT | Windows(x64)/Linux(x64/jetson) | GPU | Paddle/ONNX |
|
||||||
|
| OpenVINO | Windows(x64)/Linux(x64) | CPU | Paddle/ONNX |
|
||||||
|
| Poros[进行中] | Linux(x64) | CPU/GPU | TorchScript |
|
||||||
|
|
||||||
|
FastDeploy中各后端独立,用户在自行编译时可以选择开启其中一种或多种后端,FastDeploy中的`Runtime`模块为所有后端提供了统一的使用API,Runtime使用方式参阅文档[FastDeploy Runtime使用文档](usage.md)
|
||||||
|
|
||||||
|
|
||||||
|
## 其它文档
|
||||||
|
|
||||||
|
- [FastDeploy编译](../compile)
|
44
docs/runtime/usage.md
Normal file
44
docs/runtime/usage.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# FastDeploy Runtime使用文档
|
||||||
|
|
||||||
|
`Runtime`作为FastDeploy中模型推理的模块,目前集成了多种后端,用户通过统一的后端即可快速完成不同格式的模型,在各硬件、平台、后端上的推理。本文档通过如下示例展示各硬件、后端上的推理
|
||||||
|
|
||||||
|
## CPU推理
|
||||||
|
|
||||||
|
Python示例
|
||||||
|
|
||||||
|
```
|
||||||
|
import fastdeploy as fd
|
||||||
|
import numpy as np
|
||||||
|
option = fd.RuntimeOption()
|
||||||
|
# 设定模型路径
|
||||||
|
option.set_model_path("resnet50/inference.pdmodel", "resnet50/inference.pdiparams")
|
||||||
|
# 使用OpenVINO后端
|
||||||
|
option.use_openvino_backend()
|
||||||
|
# 初始化runtime
|
||||||
|
runtime = fd.Runtime(option)
|
||||||
|
# 获取输入名
|
||||||
|
input_name = runtime.get_input_info(0).name
|
||||||
|
# 构造数据进行推理
|
||||||
|
results = runtime.infer({input_name: np.random.rand(1, 3, 224, 224).astype("float32")})
|
||||||
|
```
|
||||||
|
|
||||||
|
## GPU推理
|
||||||
|
```
|
||||||
|
import fastdeploy as fd
|
||||||
|
import numpy as np
|
||||||
|
option = fd.RuntimeOption()
|
||||||
|
# 设定模型路径
|
||||||
|
option.set_model_path("resnet50/inference.pdmodel", "resnet50/inference.pdiparams")
|
||||||
|
# 使用GPU,并且使用第0张GPU卡
|
||||||
|
option.use_gpu(0)
|
||||||
|
# 使用Paddle Inference后端
|
||||||
|
option.use_openvino_backend()
|
||||||
|
# 初始化runtime
|
||||||
|
runtime = fd.Runtime(option)
|
||||||
|
# 获取输入名
|
||||||
|
input_name = runtime.get_input_info(0).name
|
||||||
|
# 构造数据进行推理
|
||||||
|
results = runtime.infer({input_name: np.random.rand(1, 3, 224, 224).astype("float32")})
|
||||||
|
```
|
||||||
|
|
||||||
|
更多Python/C++推理示例请直接参考[FastDeploy/examples/runtime](../../examples/runtime)
|
16
examples/runtime/README.md
Normal file
16
examples/runtime/README.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# FastDeploy Runtime推理示例
|
||||||
|
|
||||||
|
| 示例代码 | 编程语言 | 说明 |
|
||||||
|
| :------- | :------- | :---- |
|
||||||
|
| python/infer_paddle_paddle_inference.py | Python | paddle模型通过paddle inference在cpu/gpu上的推理 |
|
||||||
|
| python/infer_paddle_tensorrt.py | Python | paddle模型通过tensorrt在gpu上的推理 |
|
||||||
|
| python/infer_paddle_openvino.py | Python | paddle模型通过openvino在cpu上的推理 |
|
||||||
|
| python/infer_paddle_onnxruntime.py | Python | paddle模型通过onnx runtime在cpu/gpu上的推理 |
|
||||||
|
| python/infer_onnx_openvino.py | Python | onnx模型通过openvino在cpu上的推理 |
|
||||||
|
| python/infer_onnx_tensorrt.py | Python | onnx模型通过tensorrt在gpu上的推理 |
|
||||||
|
| cpp/infer_paddle_paddle_inference.cc | C++ | paddle模型通过paddle inference在cpu/gpu上的推理 |
|
||||||
|
| cpp/infer_paddle_tensorrt.cc | C++ | paddle模型通过tensorrt在gpu上的推理 |
|
||||||
|
| cpp/infer_paddle_openvino.cc | C++ | paddle模型通过openvino在cpu上的推理 |
|
||||||
|
| cpp/infer_paddle_onnxruntime.cc | C++ | paddle模型通过onnx runtime在cpu/gpu上的推理 |
|
||||||
|
| cpp/infer_onnx_openvino.cc | C++ | onnx模型通过openvino在cpu上的推理 |
|
||||||
|
| cpp/infer_onnx_tensorrt.cc | C++ | onnx模型通过tensorrt在gpu上的推理 |
|
39
examples/runtime/python/infer_onnx_openvino.py
Normal file
39
examples/runtime/python/infer_onnx_openvino.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import fastdeploy as fd
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
# 下载模型并解压
|
||||||
|
model_url = "https://bj.bcebos.com/fastdeploy/models/mobilenetv2.onnx"
|
||||||
|
fd.download(model_url, path=".")
|
||||||
|
|
||||||
|
option = fd.RuntimeOption()
|
||||||
|
|
||||||
|
option.set_model_path("mobilenetv2.onnx", model_format="onnx")
|
||||||
|
|
||||||
|
option.use_openvino_backend()
|
||||||
|
|
||||||
|
# 初始化构造runtime
|
||||||
|
runtime = fd.Runtime(option)
|
||||||
|
|
||||||
|
# 获取模型输入名
|
||||||
|
input_name = runtime.get_input_info(0).name
|
||||||
|
|
||||||
|
# 构造随机数据进行推理
|
||||||
|
results = runtime.infer({
|
||||||
|
input_name: np.random.rand(1, 3, 224, 224).astype("float32")
|
||||||
|
})
|
||||||
|
|
||||||
|
print(results[0].shape)
|
41
examples/runtime/python/infer_onnx_tensorrt.py
Normal file
41
examples/runtime/python/infer_onnx_tensorrt.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import fastdeploy as fd
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
# 下载模型并解压
|
||||||
|
model_url = "https://bj.bcebos.com/fastdeploy/models/mobilenetv2.onnx"
|
||||||
|
fd.download(model_url, path=".")
|
||||||
|
|
||||||
|
option = fd.RuntimeOption()
|
||||||
|
|
||||||
|
option.set_model_path("mobilenetv2.onnx", model_format="onnx")
|
||||||
|
|
||||||
|
# **** GPU 配置 ***
|
||||||
|
option.use_gpu(0)
|
||||||
|
option.use_trt_backend()
|
||||||
|
|
||||||
|
# 初始化构造runtime
|
||||||
|
runtime = fd.Runtime(option)
|
||||||
|
|
||||||
|
# 获取模型输入名
|
||||||
|
input_name = runtime.get_input_info(0).name
|
||||||
|
|
||||||
|
# 构造随机数据进行推理
|
||||||
|
results = runtime.infer({
|
||||||
|
input_name: np.random.rand(1, 3, 224, 224).astype("float32")
|
||||||
|
})
|
||||||
|
|
||||||
|
print(results[0].shape)
|
47
examples/runtime/python/infer_paddle_onnxruntime.py
Normal file
47
examples/runtime/python/infer_paddle_onnxruntime.py
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import fastdeploy as fd
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
# 下载模型并解压
|
||||||
|
model_url = "https://bj.bcebos.com/fastdeploy/models/mobilenetv2.tgz"
|
||||||
|
fd.download_and_decompress(model_url)
|
||||||
|
|
||||||
|
option = fd.RuntimeOption()
|
||||||
|
|
||||||
|
option.set_model_path("mobilenetv2/inference.pdmodel",
|
||||||
|
"mobilenetv2/inference.pdiparams")
|
||||||
|
|
||||||
|
# **** CPU 配置 ****
|
||||||
|
option.use_cpu()
|
||||||
|
option.use_ort_backend()
|
||||||
|
option.set_cpu_thread_num(12)
|
||||||
|
|
||||||
|
# **** GPU 配置 ***
|
||||||
|
# 如需使用GPU,使用如下注释代码
|
||||||
|
# option.use_gpu(0)
|
||||||
|
|
||||||
|
# 初始化构造runtime
|
||||||
|
runtime = fd.Runtime(option)
|
||||||
|
|
||||||
|
# 获取模型输入名
|
||||||
|
input_name = runtime.get_input_info(0).name
|
||||||
|
|
||||||
|
# 构造随机数据进行推理
|
||||||
|
results = runtime.infer({
|
||||||
|
input_name: np.random.rand(1, 3, 224, 224).astype("float32")
|
||||||
|
})
|
||||||
|
|
||||||
|
print(results[0].shape)
|
42
examples/runtime/python/infer_paddle_openvino.py
Normal file
42
examples/runtime/python/infer_paddle_openvino.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import fastdeploy as fd
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
# 下载模型并解压
|
||||||
|
model_url = "https://bj.bcebos.com/fastdeploy/models/mobilenetv2.tgz"
|
||||||
|
fd.download_and_decompress(model_url)
|
||||||
|
|
||||||
|
option = fd.RuntimeOption()
|
||||||
|
|
||||||
|
option.set_model_path("mobilenetv2/inference.pdmodel",
|
||||||
|
"mobilenetv2/inference.pdiparams")
|
||||||
|
|
||||||
|
option.use_cpu()
|
||||||
|
option.use_openvino_backend()
|
||||||
|
option.set_cpu_thread_num(12)
|
||||||
|
|
||||||
|
# 初始化构造runtime
|
||||||
|
runtime = fd.Runtime(option)
|
||||||
|
|
||||||
|
# 获取模型输入名
|
||||||
|
input_name = runtime.get_input_info(0).name
|
||||||
|
|
||||||
|
# 构造随机数据进行推理
|
||||||
|
results = runtime.infer({
|
||||||
|
input_name: np.random.rand(1, 3, 224, 224).astype("float32")
|
||||||
|
})
|
||||||
|
|
||||||
|
print(results[0].shape)
|
47
examples/runtime/python/infer_paddle_paddle_inference.py
Normal file
47
examples/runtime/python/infer_paddle_paddle_inference.py
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import fastdeploy as fd
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
# 下载模型并解压
|
||||||
|
model_url = "https://bj.bcebos.com/fastdeploy/models/mobilenetv2.tgz"
|
||||||
|
fd.download_and_decompress(model_url)
|
||||||
|
|
||||||
|
option = fd.RuntimeOption()
|
||||||
|
|
||||||
|
option.set_model_path("mobilenetv2/inference.pdmodel",
|
||||||
|
"mobilenetv2/inference.pdiparams")
|
||||||
|
|
||||||
|
# **** CPU 配置 ****
|
||||||
|
option.use_cpu()
|
||||||
|
option.use_paddle_backend()
|
||||||
|
option.set_cpu_thread_num(12)
|
||||||
|
|
||||||
|
# **** GPU 配置 ***
|
||||||
|
# 如需使用GPU,使用如下注释代码
|
||||||
|
# option.use_gpu(0)
|
||||||
|
|
||||||
|
# 初始化构造runtime
|
||||||
|
runtime = fd.Runtime(option)
|
||||||
|
|
||||||
|
# 获取模型输入名
|
||||||
|
input_name = runtime.get_input_info(0).name
|
||||||
|
|
||||||
|
# 构造随机数据进行推理
|
||||||
|
results = runtime.infer({
|
||||||
|
input_name: np.random.rand(1, 3, 224, 224).astype("float32")
|
||||||
|
})
|
||||||
|
|
||||||
|
print(results[0].shape)
|
42
examples/runtime/python/infer_paddle_tensorrt.py
Normal file
42
examples/runtime/python/infer_paddle_tensorrt.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import fastdeploy as fd
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
# 下载模型并解压
|
||||||
|
model_url = "https://bj.bcebos.com/fastdeploy/models/mobilenetv2.tgz"
|
||||||
|
fd.download_and_decompress(model_url)
|
||||||
|
|
||||||
|
option = fd.RuntimeOption()
|
||||||
|
|
||||||
|
option.set_model_path("mobilenetv2/inference.pdmodel",
|
||||||
|
"mobilenetv2/inference.pdiparams")
|
||||||
|
|
||||||
|
# **** GPU 配置 ***
|
||||||
|
option.use_gpu(0)
|
||||||
|
option.use_trt_backend()
|
||||||
|
|
||||||
|
# 初始化构造runtime
|
||||||
|
runtime = fd.Runtime(option)
|
||||||
|
|
||||||
|
# 获取模型输入名
|
||||||
|
input_name = runtime.get_input_info(0).name
|
||||||
|
|
||||||
|
# 构造随机数据进行推理
|
||||||
|
results = runtime.infer({
|
||||||
|
input_name: np.random.rand(1, 3, 224, 224).astype("float32")
|
||||||
|
})
|
||||||
|
|
||||||
|
print(results[0].shape)
|
@@ -28,10 +28,9 @@ tar -xvf ch_ppocr_mobile_v2.0_cls_infer.tar.gz
|
|||||||
wget https://bj.bcebos.com/paddlehub/fastdeploy/ch_PP-OCRv2_rec_infer.tar.gz
|
wget https://bj.bcebos.com/paddlehub/fastdeploy/ch_PP-OCRv2_rec_infer.tar.gz
|
||||||
tar -xvf ch_PP-OCRv2_rec_infer.tar.gz
|
tar -xvf ch_PP-OCRv2_rec_infer.tar.gz
|
||||||
|
|
||||||
wget https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/release/2.6/doc/imgs/12.jpg
|
wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/doc/imgs/12.jpg
|
||||||
|
|
||||||
wget https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/release/2.6/ppocr/utils/ppocr_keys_v1.txt
|
|
||||||
|
|
||||||
|
wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/ppocr/utils/ppocr_keys_v1.txt
|
||||||
|
|
||||||
# CPU推理
|
# CPU推理
|
||||||
./infer_demo ./ch_PP-OCRv2_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv2_rec_infer ./ppocr_keys_v1.txt ./12.jpg 0
|
./infer_demo ./ch_PP-OCRv2_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv2_rec_infer ./ppocr_keys_v1.txt ./12.jpg 0
|
||||||
@@ -39,8 +38,6 @@ wget https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/release/2.6/ppocr/
|
|||||||
./infer_demo ./ch_PP-OCRv2_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv2_rec_infer ./ppocr_keys_v1.txt ./12.jpg 1
|
./infer_demo ./ch_PP-OCRv2_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv2_rec_infer ./ppocr_keys_v1.txt ./12.jpg 1
|
||||||
# GPU上TensorRT推理
|
# GPU上TensorRT推理
|
||||||
./infer_demo ./ch_PP-OCRv2_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv2_rec_infer ./ppocr_keys_v1.txt ./12.jpg 2
|
./infer_demo ./ch_PP-OCRv2_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv2_rec_infer ./ppocr_keys_v1.txt ./12.jpg 2
|
||||||
# OCR还支持det/cls/rec三个模型的组合使用,例如当我们不想使用cls模型的时候,只需要给cls模型路径的位置,传入一个空的字符串, 例子如下
|
|
||||||
./infer_demo ./ch_PP-OCRv2_det_infer "" ./ch_PP-OCRv2_rec_infer ./ppocr_keys_v1.txt ./12.jpg 0
|
|
||||||
```
|
```
|
||||||
|
|
||||||
运行完成可视化结果如下图所示
|
运行完成可视化结果如下图所示
|
||||||
@@ -53,9 +50,9 @@ wget https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/release/2.6/ppocr/
|
|||||||
### PPOCRSystemv2类
|
### PPOCRSystemv2类
|
||||||
|
|
||||||
```
|
```
|
||||||
fastdeploy::application::ocrsystem::PPOCRSystemv2(fastdeploy::vision::ocr::DBDetector* ocr_det = nullptr,
|
fastdeploy::application::ocrsystem::PPOCRSystemv2(fastdeploy::vision::ocr::DBDetector* det_model,
|
||||||
fastdeploy::vision::ocr::Classifier* ocr_cls = nullptr,
|
fastdeploy::vision::ocr::Classifier* cls_model,
|
||||||
fastdeploy::vision::ocr::Recognizer* ocr_rec = nullptr);
|
fastdeploy::vision::ocr::Recognizer* rec_model);
|
||||||
```
|
```
|
||||||
|
|
||||||
PPOCRSystemv2 的初始化,由检测,分类和识别模型串联构成
|
PPOCRSystemv2 的初始化,由检测,分类和识别模型串联构成
|
||||||
@@ -66,6 +63,18 @@ PPOCRSystemv2 的初始化,由检测,分类和识别模型串联构成
|
|||||||
> * **Classifier**(model): OCR中的分类模型
|
> * **Classifier**(model): OCR中的分类模型
|
||||||
> * **Recognizer**(model): OCR中的识别模型
|
> * **Recognizer**(model): OCR中的识别模型
|
||||||
|
|
||||||
|
```
|
||||||
|
fastdeploy::application::ocrsystem::PPOCRSystemv2(fastdeploy::vision::ocr::DBDetector* det_model,
|
||||||
|
fastdeploy::vision::ocr::Recognizer* rec_model);
|
||||||
|
```
|
||||||
|
PPOCRSystemv2 的初始化,由检测,识别模型串联构成(无分类器)
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
|
||||||
|
> * **DBDetector**(model): OCR中的检测模型
|
||||||
|
> * **Recognizer**(model): OCR中的识别模型
|
||||||
|
|
||||||
|
|
||||||
#### Predict函数
|
#### Predict函数
|
||||||
|
|
||||||
> ```
|
> ```
|
||||||
|
@@ -19,11 +19,7 @@ const char sep = '\\';
|
|||||||
const char sep = '/';
|
const char sep = '/';
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void CpuInfer(const std::string& det_model_dir,
|
void InitAndInfer(const std::string& det_model_dir, const std::string& cls_model_dir, const std::string& rec_model_dir, const std::string& rec_label_file, const std::string& image_file, const fastdeploy::RuntimeOption& option) {
|
||||||
const std::string& cls_model_dir,
|
|
||||||
const std::string& rec_model_dir,
|
|
||||||
const std::string& rec_label_file,
|
|
||||||
const std::string& image_file) {
|
|
||||||
auto det_model_file = det_model_dir + sep + "inference.pdmodel";
|
auto det_model_file = det_model_dir + sep + "inference.pdmodel";
|
||||||
auto det_params_file = det_model_dir + sep + "inference.pdiparams";
|
auto det_params_file = det_model_dir + sep + "inference.pdiparams";
|
||||||
|
|
||||||
@@ -32,238 +28,32 @@ void CpuInfer(const std::string& det_model_dir,
|
|||||||
|
|
||||||
auto rec_model_file = rec_model_dir + sep + "inference.pdmodel";
|
auto rec_model_file = rec_model_dir + sep + "inference.pdmodel";
|
||||||
auto rec_params_file = rec_model_dir + sep + "inference.pdiparams";
|
auto rec_params_file = rec_model_dir + sep + "inference.pdiparams";
|
||||||
auto rec_label = rec_label_file;
|
|
||||||
|
|
||||||
fastdeploy::vision::ocr::DBDetector det_model;
|
auto det_model = fastdeploy::vision::ocr::DBDetector(det_model_file, det_params_file, option);
|
||||||
fastdeploy::vision::ocr::Classifier cls_model;
|
auto cls_model = fastdeploy::vision::ocr::Classifier(cls_model_file, cls_params_file, option);
|
||||||
fastdeploy::vision::ocr::Recognizer rec_model;
|
auto rec_model = fastdeploy::vision::ocr::Recognizer(rec_model_file, rec_params_file, rec_label_file, option);
|
||||||
|
|
||||||
if (!det_model_dir.empty()) {
|
assert(det_model.Initialized());
|
||||||
auto det_option = fastdeploy::RuntimeOption();
|
assert(cls_model.Initialized());
|
||||||
det_option.UseCpu();
|
assert(rec_model.Initialized());
|
||||||
det_model = fastdeploy::vision::ocr::DBDetector(
|
|
||||||
det_model_file, det_params_file, det_option);
|
|
||||||
|
|
||||||
if (!det_model.Initialized()) {
|
// 其中分类模型可选,因此也可使用如下方式串联OCR系统
|
||||||
std::cerr << "Failed to initialize det_model." << std::endl;
|
// auto ocr_system_v2 = fastdeploy::application::ocrsystem::PPOCRSystemv2(&det_model, &rec_model);
|
||||||
return;
|
auto ocr_system_v2 = fastdeploy::application::ocrsystem::PPOCRSystemv2(&det_model, &cls_model, &rec_model);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cls_model_dir.empty()) {
|
|
||||||
auto cls_option = fastdeploy::RuntimeOption();
|
|
||||||
cls_option.UseCpu();
|
|
||||||
cls_model = fastdeploy::vision::ocr::Classifier(
|
|
||||||
cls_model_file, cls_params_file, cls_option);
|
|
||||||
|
|
||||||
if (!cls_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize cls_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rec_model_dir.empty()) {
|
|
||||||
auto rec_option = fastdeploy::RuntimeOption();
|
|
||||||
rec_option.UseCpu();
|
|
||||||
rec_model = fastdeploy::vision::ocr::Recognizer(
|
|
||||||
rec_model_file, rec_params_file, rec_label, rec_option);
|
|
||||||
|
|
||||||
if (!rec_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize rec_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ocrv2_app = fastdeploy::application::ocrsystem::PPOCRSystemv2(
|
|
||||||
&det_model, &cls_model, &rec_model);
|
|
||||||
|
|
||||||
auto im = cv::imread(image_file);
|
auto im = cv::imread(image_file);
|
||||||
auto im_bak = im.clone();
|
auto im_bak = im.clone();
|
||||||
|
|
||||||
fastdeploy::vision::OCRResult res;
|
fastdeploy::vision::OCRResult result;
|
||||||
//开始预测
|
if (!ocr_system_v2.Predict(&im, &result)) {
|
||||||
if (!ocrv2_app.Predict(&im, &res)) {
|
|
||||||
std::cerr << "Failed to predict." << std::endl;
|
std::cerr << "Failed to predict." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//输出预测信息
|
std::cout << result.Str() << std::endl;
|
||||||
std::cout << res.Str() << std::endl;
|
|
||||||
|
|
||||||
//可视化
|
auto vis_im = fastdeploy::vision::Visualize::VisOcr(im_bak, result);
|
||||||
auto vis_img = fastdeploy::vision::Visualize::VisOcr(im_bak, res);
|
cv::imwrite("vis_result.jpg", vis_im);
|
||||||
|
|
||||||
cv::imwrite("vis_result.jpg", vis_img);
|
|
||||||
std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GpuInfer(const std::string& det_model_dir,
|
|
||||||
const std::string& cls_model_dir,
|
|
||||||
const std::string& rec_model_dir,
|
|
||||||
const std::string& rec_label_file,
|
|
||||||
const std::string& image_file) {
|
|
||||||
auto det_model_file = det_model_dir + sep + "inference.pdmodel";
|
|
||||||
auto det_params_file = det_model_dir + sep + "inference.pdiparams";
|
|
||||||
|
|
||||||
auto cls_model_file = cls_model_dir + sep + "inference.pdmodel";
|
|
||||||
auto cls_params_file = cls_model_dir + sep + "inference.pdiparams";
|
|
||||||
|
|
||||||
auto rec_model_file = rec_model_dir + sep + "inference.pdmodel";
|
|
||||||
auto rec_params_file = rec_model_dir + sep + "inference.pdiparams";
|
|
||||||
auto rec_label = rec_label_file;
|
|
||||||
|
|
||||||
fastdeploy::vision::ocr::DBDetector det_model;
|
|
||||||
fastdeploy::vision::ocr::Classifier cls_model;
|
|
||||||
fastdeploy::vision::ocr::Recognizer rec_model;
|
|
||||||
|
|
||||||
//准备模型
|
|
||||||
if (!det_model_dir.empty()) {
|
|
||||||
auto det_option = fastdeploy::RuntimeOption();
|
|
||||||
det_option.UseGpu();
|
|
||||||
det_model = fastdeploy::vision::ocr::DBDetector(
|
|
||||||
det_model_file, det_params_file, det_option);
|
|
||||||
|
|
||||||
if (!det_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize det_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cls_model_dir.empty()) {
|
|
||||||
auto cls_option = fastdeploy::RuntimeOption();
|
|
||||||
cls_option.UseGpu();
|
|
||||||
cls_model = fastdeploy::vision::ocr::Classifier(
|
|
||||||
cls_model_file, cls_params_file, cls_option);
|
|
||||||
|
|
||||||
if (!cls_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize cls_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rec_model_dir.empty()) {
|
|
||||||
auto rec_option = fastdeploy::RuntimeOption();
|
|
||||||
rec_option.UseGpu();
|
|
||||||
rec_option
|
|
||||||
.UsePaddleBackend(); // OCRv2的rec模型暂不支持ORT后端与PaddleInference
|
|
||||||
// v2.3.2
|
|
||||||
rec_model = fastdeploy::vision::ocr::Recognizer(
|
|
||||||
rec_model_file, rec_params_file, rec_label, rec_option);
|
|
||||||
|
|
||||||
if (!rec_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize rec_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ocrv2_app = fastdeploy::application::ocrsystem::PPOCRSystemv2(
|
|
||||||
&det_model, &cls_model, &rec_model);
|
|
||||||
|
|
||||||
auto im = cv::imread(image_file);
|
|
||||||
auto im_bak = im.clone();
|
|
||||||
|
|
||||||
fastdeploy::vision::OCRResult res;
|
|
||||||
//开始预测
|
|
||||||
if (!ocrv2_app.Predict(&im, &res)) {
|
|
||||||
std::cerr << "Failed to predict." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//输出预测信息
|
|
||||||
std::cout << res.Str() << std::endl;
|
|
||||||
|
|
||||||
//可视化
|
|
||||||
auto vis_img = fastdeploy::vision::Visualize::VisOcr(im_bak, res);
|
|
||||||
|
|
||||||
cv::imwrite("vis_result.jpg", vis_img);
|
|
||||||
std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrtInfer(const std::string& det_model_dir,
|
|
||||||
const std::string& cls_model_dir,
|
|
||||||
const std::string& rec_model_dir,
|
|
||||||
const std::string& rec_label_file,
|
|
||||||
const std::string& image_file) {
|
|
||||||
auto det_model_file = det_model_dir + sep + "inference.pdmodel";
|
|
||||||
auto det_params_file = det_model_dir + sep + "inference.pdiparams";
|
|
||||||
|
|
||||||
auto cls_model_file = cls_model_dir + sep + "inference.pdmodel";
|
|
||||||
auto cls_params_file = cls_model_dir + sep + "inference.pdiparams";
|
|
||||||
|
|
||||||
auto rec_model_file = rec_model_dir + sep + "inference.pdmodel";
|
|
||||||
auto rec_params_file = rec_model_dir + sep + "inference.pdiparams";
|
|
||||||
auto rec_label = rec_label_file;
|
|
||||||
|
|
||||||
fastdeploy::vision::ocr::DBDetector det_model;
|
|
||||||
fastdeploy::vision::ocr::Classifier cls_model;
|
|
||||||
fastdeploy::vision::ocr::Recognizer rec_model;
|
|
||||||
|
|
||||||
//准备模型
|
|
||||||
if (!det_model_dir.empty()) {
|
|
||||||
auto det_option = fastdeploy::RuntimeOption();
|
|
||||||
det_option.UseGpu();
|
|
||||||
det_option.UseTrtBackend();
|
|
||||||
det_option.SetTrtInputShape("x", {1, 3, 50, 50}, {1, 3, 640, 640},
|
|
||||||
{1, 3, 960, 960});
|
|
||||||
|
|
||||||
det_model = fastdeploy::vision::ocr::DBDetector(
|
|
||||||
det_model_file, det_params_file, det_option);
|
|
||||||
|
|
||||||
if (!det_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize det_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cls_model_dir.empty()) {
|
|
||||||
auto cls_option = fastdeploy::RuntimeOption();
|
|
||||||
cls_option.UseGpu();
|
|
||||||
cls_option.UseTrtBackend();
|
|
||||||
cls_option.SetTrtInputShape("x", {1, 3, 48, 192});
|
|
||||||
|
|
||||||
cls_model = fastdeploy::vision::ocr::Classifier(
|
|
||||||
cls_model_file, cls_params_file, cls_option);
|
|
||||||
|
|
||||||
if (!cls_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize cls_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rec_model_dir.empty()) {
|
|
||||||
auto rec_option = fastdeploy::RuntimeOption();
|
|
||||||
rec_option.UseGpu();
|
|
||||||
rec_option.UseTrtBackend();
|
|
||||||
rec_option.SetTrtInputShape("x", {1, 3, 48, 10}, {1, 3, 48, 320},
|
|
||||||
{1, 3, 48, 2000});
|
|
||||||
|
|
||||||
rec_model = fastdeploy::vision::ocr::Recognizer(
|
|
||||||
rec_model_file, rec_params_file, rec_label, rec_option);
|
|
||||||
|
|
||||||
if (!rec_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize rec_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ocrv2_app = fastdeploy::application::ocrsystem::PPOCRSystemv2(
|
|
||||||
&det_model, &cls_model, &rec_model);
|
|
||||||
|
|
||||||
auto im = cv::imread(image_file);
|
|
||||||
auto im_bak = im.clone();
|
|
||||||
|
|
||||||
fastdeploy::vision::OCRResult res;
|
|
||||||
//开始预测
|
|
||||||
if (!ocrv2_app.Predict(&im, &res)) {
|
|
||||||
std::cerr << "Failed to predict." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//输出预测信息
|
|
||||||
std::cout << res.Str() << std::endl;
|
|
||||||
|
|
||||||
//可视化
|
|
||||||
auto vis_img = fastdeploy::vision::Visualize::VisOcr(im_bak, res);
|
|
||||||
|
|
||||||
cv::imwrite("vis_result.jpg", vis_img);
|
|
||||||
std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl;
|
std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,12 +72,23 @@ int main(int argc, char* argv[]) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::atoi(argv[6]) == 0) {
|
fastdeploy::RuntimeOption option;
|
||||||
CpuInfer(argv[1], argv[2], argv[3], argv[4], argv[5]);
|
int flag = std::atoi(argv[6]);
|
||||||
} else if (std::atoi(argv[6]) == 1) {
|
|
||||||
GpuInfer(argv[1], argv[2], argv[3], argv[4], argv[5]);
|
if (flag == 0) {
|
||||||
} else if (std::atoi(argv[6]) == 2) {
|
option.UseCpu();
|
||||||
TrtInfer(argv[1], argv[2], argv[3], argv[4], argv[5]);
|
} else if (flag == 1) {
|
||||||
|
option.UseGpu();
|
||||||
|
} else if (flag == 2) {
|
||||||
|
option.UseGpu();
|
||||||
|
option.UseTrtBackend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string det_model_dir = argv[1];
|
||||||
|
std::string cls_model_dir = argv[2];
|
||||||
|
std::string rec_model_dir = argv[3];
|
||||||
|
std::string rec_label_file = argv[4];
|
||||||
|
std::string test_image = argv[5];
|
||||||
|
InitAndInfer(det_model_dir, cls_model_dir, rec_model_dir, rec_label_file, test_image, option);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@@ -19,9 +19,9 @@ tar -xvf ch_ppocr_mobile_v2.0_cls_infer.tar.gz
|
|||||||
wget https://bj.bcebos.com/paddlehub/fastdeploy/ch_PP-OCRv2_rec_infer.tar.gz
|
wget https://bj.bcebos.com/paddlehub/fastdeploy/ch_PP-OCRv2_rec_infer.tar.gz
|
||||||
tar -xvf ch_PP-OCRv2_rec_infer.tar.gz
|
tar -xvf ch_PP-OCRv2_rec_infer.tar.gz
|
||||||
|
|
||||||
wget https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/release/2.6/doc/imgs/12.jpg
|
wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/doc/imgs/12.jpg
|
||||||
|
|
||||||
wget https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/release/2.6/ppocr/utils/ppocr_keys_v1.txt
|
wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/ppocr/utils/ppocr_keys_v1.txt
|
||||||
|
|
||||||
|
|
||||||
#下载部署示例代码
|
#下载部署示例代码
|
||||||
@@ -33,9 +33,7 @@ python infer.py --det_model ch_PP-OCRv2_det_infer --cls_model ch_ppocr_mobile_v2
|
|||||||
# GPU推理
|
# GPU推理
|
||||||
python infer.py --det_model ch_PP-OCRv2_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv2_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu
|
python infer.py --det_model ch_PP-OCRv2_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv2_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu
|
||||||
# GPU上使用TensorRT推理
|
# GPU上使用TensorRT推理
|
||||||
python infer.py --det_model ch_PP-OCRv2_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv2_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --det_use_trt True --cls_use_trt True --rec_use_trt True
|
python infer.py --det_model ch_PP-OCRv2_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv2_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend trt
|
||||||
# OCR还支持det/cls/rec三个模型的组合使用,例如当我们不想使用cls模型的时候,只需要给--cls_model传入一个空的字符串, 例子如下:
|
|
||||||
python infer.py --det_model ch_PP-OCRv2_det_infer --cls_model "" --rec_model ch_PP-OCRv2_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu
|
|
||||||
```
|
```
|
||||||
|
|
||||||
运行完成可视化结果如下图所示
|
运行完成可视化结果如下图所示
|
||||||
|
@@ -1,3 +1,17 @@
|
|||||||
|
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
import fastdeploy as fd
|
import fastdeploy as fd
|
||||||
import cv2
|
import cv2
|
||||||
import os
|
import os
|
||||||
@@ -21,7 +35,6 @@ def parse_arguments():
|
|||||||
"--rec_label_file",
|
"--rec_label_file",
|
||||||
required=True,
|
required=True,
|
||||||
help="Path of Recognization model of PPOCR.")
|
help="Path of Recognization model of PPOCR.")
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--image", type=str, required=True, help="Path of test image file.")
|
"--image", type=str, required=True, help="Path of test image file.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
@@ -30,114 +43,83 @@ def parse_arguments():
|
|||||||
default='cpu',
|
default='cpu',
|
||||||
help="Type of inference device, support 'cpu' or 'gpu'.")
|
help="Type of inference device, support 'cpu' or 'gpu'.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--det_use_trt",
|
"--backend",
|
||||||
type=ast.literal_eval,
|
type=str,
|
||||||
default=False,
|
default="default",
|
||||||
help="Wether to use tensorrt.")
|
help="Type of inference backend, support ort/trt/paddle/openvino, default 'openvino' for cpu, 'tensorrt' for gpu"
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--cls_use_trt",
|
"--device_id",
|
||||||
type=ast.literal_eval,
|
type=int,
|
||||||
default=False,
|
default=0,
|
||||||
help="Wether to use tensorrt.")
|
help="Define which GPU card used to run model.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--rec_use_trt",
|
"--cpu_thread_num",
|
||||||
type=ast.literal_eval,
|
type=int,
|
||||||
default=False,
|
default=9,
|
||||||
help="Wether to use tensorrt.")
|
help="Number of threads while inference on CPU.")
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
def build_det_option(args):
|
def build_option(args):
|
||||||
option = fd.RuntimeOption()
|
option = fd.RuntimeOption()
|
||||||
|
|
||||||
if args.device.lower() == "gpu":
|
if args.device.lower() == "gpu":
|
||||||
option.use_gpu()
|
option.use_gpu(0)
|
||||||
|
|
||||||
if args.det_use_trt:
|
option.set_cpu_thread_num(args.cpu_thread_num)
|
||||||
|
|
||||||
|
if args.backend.lower() == "trt":
|
||||||
|
assert args.device.lower(
|
||||||
|
) == "gpu", "TensorRT backend require inference on device GPU."
|
||||||
option.use_trt_backend()
|
option.use_trt_backend()
|
||||||
#det_max_side_len 默认为960,当用户更改DET模型的max_side_len参数时,请将此参数同时更改
|
elif args.backend.lower() == "ort":
|
||||||
det_max_side_len = 960
|
option.use_ort_backend()
|
||||||
option.set_trt_input_shape("x", [1, 3, 50, 50], [1, 3, 640, 640],
|
elif args.backend.lower() == "paddle":
|
||||||
[1, 3, det_max_side_len, det_max_side_len])
|
option.use_paddle_backend()
|
||||||
|
elif args.backend.lower() == "openvino":
|
||||||
return option
|
assert args.device.lower(
|
||||||
|
) == "cpu", "OpenVINO backend require inference on device CPU."
|
||||||
|
option.use_openvino_backend()
|
||||||
def build_cls_option(args):
|
|
||||||
option = fd.RuntimeOption()
|
|
||||||
option.use_paddle_backend()
|
|
||||||
|
|
||||||
if args.device.lower() == "gpu":
|
|
||||||
option.use_gpu()
|
|
||||||
|
|
||||||
if args.cls_use_trt:
|
|
||||||
option.use_trt_backend()
|
|
||||||
option.set_trt_input_shape("x", [1, 3, 32, 100])
|
|
||||||
|
|
||||||
return option
|
|
||||||
|
|
||||||
|
|
||||||
def build_rec_option(args):
|
|
||||||
option = fd.RuntimeOption()
|
|
||||||
option.use_paddle_backend()
|
|
||||||
|
|
||||||
if args.device.lower() == "gpu":
|
|
||||||
option.use_gpu()
|
|
||||||
|
|
||||||
if args.rec_use_trt:
|
|
||||||
option.use_trt_backend()
|
|
||||||
option.set_trt_input_shape("x", [1, 3, 48, 10], [1, 3, 48, 320],
|
|
||||||
[1, 3, 48, 2000])
|
|
||||||
return option
|
return option
|
||||||
|
|
||||||
|
|
||||||
args = parse_arguments()
|
args = parse_arguments()
|
||||||
|
|
||||||
#Det模型
|
# Detection模型, 检测文字框
|
||||||
det_model_file = os.path.join(args.det_model, "inference.pdmodel")
|
det_model_file = os.path.join(args.det_model, "inference.pdmodel")
|
||||||
det_params_file = os.path.join(args.det_model, "inference.pdiparams")
|
det_params_file = os.path.join(args.det_model, "inference.pdiparams")
|
||||||
#Cls模型
|
# Classification模型,方向分类,可选
|
||||||
cls_model_file = os.path.join(args.cls_model, "inference.pdmodel")
|
cls_model_file = os.path.join(args.cls_model, "inference.pdmodel")
|
||||||
cls_params_file = os.path.join(args.cls_model, "inference.pdiparams")
|
cls_params_file = os.path.join(args.cls_model, "inference.pdiparams")
|
||||||
#Rec模型
|
# Recognition模型,文字识别模型
|
||||||
rec_model_file = os.path.join(args.rec_model, "inference.pdmodel")
|
rec_model_file = os.path.join(args.rec_model, "inference.pdmodel")
|
||||||
rec_params_file = os.path.join(args.rec_model, "inference.pdiparams")
|
rec_params_file = os.path.join(args.rec_model, "inference.pdiparams")
|
||||||
rec_label_file = args.rec_label_file
|
rec_label_file = args.rec_label_file
|
||||||
|
|
||||||
#默认
|
# 对于三个模型,均采用同样的部署配置
|
||||||
det_model = fd.vision.ocr.DBDetector()
|
# 用户也可根据自行需求分别配置
|
||||||
cls_model = fd.vision.ocr.Classifier()
|
runtime_option = build_option(args)
|
||||||
rec_model = fd.vision.ocr.Recognizer()
|
|
||||||
|
|
||||||
#模型初始化
|
det_model = fd.vision.ocr.DBDetector(
|
||||||
if (len(args.det_model) != 0):
|
det_model_file, det_params_file, runtime_option=runtime_option)
|
||||||
det_runtime_option = build_det_option(args)
|
cls_model = fd.vision.ocr.Classifier(
|
||||||
det_model = fd.vision.ocr.DBDetector(
|
cls_model_file, cls_params_file, runtime_option=runtime_option)
|
||||||
det_model_file, det_params_file, runtime_option=det_runtime_option)
|
rec_model = fd.vision.ocr.Recognizer(
|
||||||
|
rec_model_file,
|
||||||
|
rec_params_file,
|
||||||
|
rec_label_file,
|
||||||
|
runtime_option=runtime_option)
|
||||||
|
|
||||||
if (len(args.cls_model) != 0):
|
# 创建OCR系统,串联3个模型,其中cls_model可选,如无需求,可设置为None
|
||||||
cls_runtime_option = build_cls_option(args)
|
ocr_system = fd.vision.ocr.PPOCRSystemv2(
|
||||||
cls_model = fd.vision.ocr.Classifier(
|
det_model=det_model, cls_model=cls_model, rec_model=rec_model)
|
||||||
cls_model_file, cls_params_file, runtime_option=cls_runtime_option)
|
|
||||||
|
|
||||||
if (len(args.rec_model) != 0):
|
|
||||||
rec_runtime_option = build_rec_option(args)
|
|
||||||
rec_model = fd.vision.ocr.Recognizer(
|
|
||||||
rec_model_file,
|
|
||||||
rec_params_file,
|
|
||||||
rec_label_file,
|
|
||||||
runtime_option=rec_runtime_option)
|
|
||||||
|
|
||||||
ppocrsysv2 = fd.vision.ocr.PPOCRSystemv2(
|
|
||||||
ocr_det=det_model._model,
|
|
||||||
ocr_cls=cls_model._model,
|
|
||||||
ocr_rec=rec_model._model)
|
|
||||||
|
|
||||||
# 预测图片准备
|
# 预测图片准备
|
||||||
im = cv2.imread(args.image)
|
im = cv2.imread(args.image)
|
||||||
|
|
||||||
#预测并打印结果
|
#预测并打印结果
|
||||||
result = ppocrsysv2.predict(im)
|
result = ocr_system.predict(im)
|
||||||
|
|
||||||
print(result)
|
print(result)
|
||||||
|
|
||||||
# 可视化结果
|
# 可视化结果
|
||||||
|
@@ -28,10 +28,9 @@ tar -xvf ch_ppocr_mobile_v2.0_cls_infer.tar.gz
|
|||||||
wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_infer.tar
|
wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_infer.tar
|
||||||
tar -xvf ch_PP-OCRv3_rec_infer.tar
|
tar -xvf ch_PP-OCRv3_rec_infer.tar
|
||||||
|
|
||||||
wget https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/release/2.6/doc/imgs/12.jpg
|
wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/doc/imgs/12.jpg
|
||||||
|
|
||||||
wget https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/release/2.6/ppocr/utils/ppocr_keys_v1.txt
|
|
||||||
|
|
||||||
|
wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/ppocr/utils/ppocr_keys_v1.txt
|
||||||
|
|
||||||
# CPU推理
|
# CPU推理
|
||||||
./infer_demo ./ch_PP-OCRv3_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv3_rec_infer ./ppocr_keys_v1.txt ./12.jpg 0
|
./infer_demo ./ch_PP-OCRv3_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv3_rec_infer ./ppocr_keys_v1.txt ./12.jpg 0
|
||||||
@@ -39,8 +38,6 @@ wget https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/release/2.6/ppocr/
|
|||||||
./infer_demo ./ch_PP-OCRv3_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv3_rec_infer ./ppocr_keys_v1.txt ./12.jpg 1
|
./infer_demo ./ch_PP-OCRv3_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv3_rec_infer ./ppocr_keys_v1.txt ./12.jpg 1
|
||||||
# GPU上TensorRT推理
|
# GPU上TensorRT推理
|
||||||
./infer_demo ./ch_PP-OCRv3_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv3_rec_infer ./ppocr_keys_v1.txt ./12.jpg 2
|
./infer_demo ./ch_PP-OCRv3_det_infer ./ch_ppocr_mobile_v2.0_cls_infer ./ch_PP-OCRv3_rec_infer ./ppocr_keys_v1.txt ./12.jpg 2
|
||||||
# OCR还支持det/cls/rec三个模型的组合使用,例如当我们不想使用cls模型的时候,只需要给cls模型路径的位置,传入一个空的字符串, 例子如下
|
|
||||||
./infer_demo ./ch_PP-OCRv3_det_infer "" ./ch_PP-OCRv3_rec_infer ./ppocr_keys_v1.txt ./12.jpg 0
|
|
||||||
```
|
```
|
||||||
|
|
||||||
运行完成可视化结果如下图所示
|
运行完成可视化结果如下图所示
|
||||||
@@ -53,12 +50,12 @@ wget https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/release/2.6/ppocr/
|
|||||||
### PPOCRSystemv3类
|
### PPOCRSystemv3类
|
||||||
|
|
||||||
```
|
```
|
||||||
fastdeploy::application::ocrsystem::PPOCRSystemv3(fastdeploy::vision::ocr::DBDetector* ocr_det = nullptr,
|
fastdeploy::application::ocrsystem::PPOCRSystemv3(fastdeploy::vision::ocr::DBDetector* det_model,
|
||||||
fastdeploy::vision::ocr::Classifier* ocr_cls = nullptr,
|
fastdeploy::vision::ocr::Classifier* cls_model,
|
||||||
fastdeploy::vision::ocr::Recognizer* ocr_rec = nullptr);
|
fastdeploy::vision::ocr::Recognizer* rec_model);
|
||||||
```
|
```
|
||||||
|
|
||||||
PPOCRSystemv3 的初始化,由检测,分类和识别模型串联构成
|
PPOCRSystemv2 的初始化,由检测,分类和识别模型串联构成
|
||||||
|
|
||||||
**参数**
|
**参数**
|
||||||
|
|
||||||
@@ -66,6 +63,17 @@ PPOCRSystemv3 的初始化,由检测,分类和识别模型串联构成
|
|||||||
> * **Classifier**(model): OCR中的分类模型
|
> * **Classifier**(model): OCR中的分类模型
|
||||||
> * **Recognizer**(model): OCR中的识别模型
|
> * **Recognizer**(model): OCR中的识别模型
|
||||||
|
|
||||||
|
```
|
||||||
|
fastdeploy::application::ocrsystem::PPOCRSystemv3(fastdeploy::vision::ocr::DBDetector* det_model,
|
||||||
|
fastdeploy::vision::ocr::Recognizer* rec_model);
|
||||||
|
```
|
||||||
|
PPOCRSystemv2 的初始化,由检测,识别模型串联构成(无分类器)
|
||||||
|
|
||||||
|
**参数**
|
||||||
|
|
||||||
|
> * **DBDetector**(model): OCR中的检测模型
|
||||||
|
> * **Recognizer**(model): OCR中的识别模型
|
||||||
|
|
||||||
#### Predict函数
|
#### Predict函数
|
||||||
|
|
||||||
> ```
|
> ```
|
||||||
|
@@ -19,11 +19,7 @@ const char sep = '\\';
|
|||||||
const char sep = '/';
|
const char sep = '/';
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void CpuInfer(const std::string& det_model_dir,
|
void InitAndInfer(const std::string& det_model_dir, const std::string& cls_model_dir, const std::string& rec_model_dir, const std::string& rec_label_file, const std::string& image_file, const fastdeploy::RuntimeOption& option) {
|
||||||
const std::string& cls_model_dir,
|
|
||||||
const std::string& rec_model_dir,
|
|
||||||
const std::string& rec_label_file,
|
|
||||||
const std::string& image_file) {
|
|
||||||
auto det_model_file = det_model_dir + sep + "inference.pdmodel";
|
auto det_model_file = det_model_dir + sep + "inference.pdmodel";
|
||||||
auto det_params_file = det_model_dir + sep + "inference.pdiparams";
|
auto det_params_file = det_model_dir + sep + "inference.pdiparams";
|
||||||
|
|
||||||
@@ -32,235 +28,32 @@ void CpuInfer(const std::string& det_model_dir,
|
|||||||
|
|
||||||
auto rec_model_file = rec_model_dir + sep + "inference.pdmodel";
|
auto rec_model_file = rec_model_dir + sep + "inference.pdmodel";
|
||||||
auto rec_params_file = rec_model_dir + sep + "inference.pdiparams";
|
auto rec_params_file = rec_model_dir + sep + "inference.pdiparams";
|
||||||
auto rec_label = rec_label_file;
|
|
||||||
|
|
||||||
fastdeploy::vision::ocr::DBDetector det_model;
|
auto det_model = fastdeploy::vision::ocr::DBDetector(det_model_file, det_params_file, option);
|
||||||
fastdeploy::vision::ocr::Classifier cls_model;
|
auto cls_model = fastdeploy::vision::ocr::Classifier(cls_model_file, cls_params_file, option);
|
||||||
fastdeploy::vision::ocr::Recognizer rec_model;
|
auto rec_model = fastdeploy::vision::ocr::Recognizer(rec_model_file, rec_params_file, rec_label_file, option);
|
||||||
|
|
||||||
if (!det_model_dir.empty()) {
|
assert(det_model.Initialized());
|
||||||
auto det_option = fastdeploy::RuntimeOption();
|
assert(cls_model.Initialized());
|
||||||
det_option.UseCpu();
|
assert(rec_model.Initialized());
|
||||||
det_model = fastdeploy::vision::ocr::DBDetector(
|
|
||||||
det_model_file, det_params_file, det_option);
|
|
||||||
|
|
||||||
if (!det_model.Initialized()) {
|
// 其中分类模型可选,因此也可使用如下方式串联OCR系统
|
||||||
std::cerr << "Failed to initialize det_model." << std::endl;
|
// auto ocr_system_v3 = fastdeploy::application::ocrsystem::PPOCRSystemv3(&det_model, &rec_model);
|
||||||
return;
|
auto ocr_system_v3 = fastdeploy::application::ocrsystem::PPOCRSystemv3(&det_model, &cls_model, &rec_model);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cls_model_dir.empty()) {
|
|
||||||
auto cls_option = fastdeploy::RuntimeOption();
|
|
||||||
cls_option.UseCpu();
|
|
||||||
cls_model = fastdeploy::vision::ocr::Classifier(
|
|
||||||
cls_model_file, cls_params_file, cls_option);
|
|
||||||
|
|
||||||
if (!cls_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize cls_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rec_model_dir.empty()) {
|
|
||||||
auto rec_option = fastdeploy::RuntimeOption();
|
|
||||||
rec_option.UseCpu();
|
|
||||||
rec_model = fastdeploy::vision::ocr::Recognizer(
|
|
||||||
rec_model_file, rec_params_file, rec_label, rec_option);
|
|
||||||
|
|
||||||
if (!rec_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize rec_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ocrv3_app = fastdeploy::application::ocrsystem::PPOCRSystemv3(
|
|
||||||
&det_model, &cls_model, &rec_model);
|
|
||||||
|
|
||||||
auto im = cv::imread(image_file);
|
auto im = cv::imread(image_file);
|
||||||
auto im_bak = im.clone();
|
auto im_bak = im.clone();
|
||||||
|
|
||||||
fastdeploy::vision::OCRResult res;
|
fastdeploy::vision::OCRResult result;
|
||||||
//开始预测
|
if (!ocr_system_v3.Predict(&im, &result)) {
|
||||||
if (!ocrv3_app.Predict(&im, &res)) {
|
|
||||||
std::cerr << "Failed to predict." << std::endl;
|
std::cerr << "Failed to predict." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//输出预测信息
|
std::cout << result.Str() << std::endl;
|
||||||
std::cout << res.Str() << std::endl;
|
|
||||||
|
|
||||||
//可视化
|
auto vis_im = fastdeploy::vision::Visualize::VisOcr(im_bak, result);
|
||||||
auto vis_img = fastdeploy::vision::Visualize::VisOcr(im_bak, res);
|
cv::imwrite("vis_result.jpg", vis_im);
|
||||||
|
|
||||||
cv::imwrite("vis_result.jpg", vis_img);
|
|
||||||
std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GpuInfer(const std::string& det_model_dir,
|
|
||||||
const std::string& cls_model_dir,
|
|
||||||
const std::string& rec_model_dir,
|
|
||||||
const std::string& rec_label_file,
|
|
||||||
const std::string& image_file) {
|
|
||||||
auto det_model_file = det_model_dir + sep + "inference.pdmodel";
|
|
||||||
auto det_params_file = det_model_dir + sep + "inference.pdiparams";
|
|
||||||
|
|
||||||
auto cls_model_file = cls_model_dir + sep + "inference.pdmodel";
|
|
||||||
auto cls_params_file = cls_model_dir + sep + "inference.pdiparams";
|
|
||||||
|
|
||||||
auto rec_model_file = rec_model_dir + sep + "inference.pdmodel";
|
|
||||||
auto rec_params_file = rec_model_dir + sep + "inference.pdiparams";
|
|
||||||
auto rec_label = rec_label_file;
|
|
||||||
|
|
||||||
fastdeploy::vision::ocr::DBDetector det_model;
|
|
||||||
fastdeploy::vision::ocr::Classifier cls_model;
|
|
||||||
fastdeploy::vision::ocr::Recognizer rec_model;
|
|
||||||
|
|
||||||
//准备模型
|
|
||||||
if (!det_model_dir.empty()) {
|
|
||||||
auto det_option = fastdeploy::RuntimeOption();
|
|
||||||
det_option.UseGpu();
|
|
||||||
det_model = fastdeploy::vision::ocr::DBDetector(
|
|
||||||
det_model_file, det_params_file, det_option);
|
|
||||||
|
|
||||||
if (!det_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize det_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cls_model_dir.empty()) {
|
|
||||||
auto cls_option = fastdeploy::RuntimeOption();
|
|
||||||
cls_option.UseGpu();
|
|
||||||
cls_model = fastdeploy::vision::ocr::Classifier(
|
|
||||||
cls_model_file, cls_params_file, cls_option);
|
|
||||||
|
|
||||||
if (!cls_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize cls_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rec_model_dir.empty()) {
|
|
||||||
auto rec_option = fastdeploy::RuntimeOption();
|
|
||||||
rec_option.UseGpu();
|
|
||||||
rec_model = fastdeploy::vision::ocr::Recognizer(
|
|
||||||
rec_model_file, rec_params_file, rec_label, rec_option);
|
|
||||||
|
|
||||||
if (!rec_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize rec_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ocrv3_app = fastdeploy::application::ocrsystem::PPOCRSystemv3(
|
|
||||||
&det_model, &cls_model, &rec_model);
|
|
||||||
|
|
||||||
auto im = cv::imread(image_file);
|
|
||||||
auto im_bak = im.clone();
|
|
||||||
|
|
||||||
fastdeploy::vision::OCRResult res;
|
|
||||||
//开始预测
|
|
||||||
if (!ocrv3_app.Predict(&im, &res)) {
|
|
||||||
std::cerr << "Failed to predict." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//输出预测信息
|
|
||||||
std::cout << res.Str() << std::endl;
|
|
||||||
|
|
||||||
//可视化
|
|
||||||
auto vis_img = fastdeploy::vision::Visualize::VisOcr(im_bak, res);
|
|
||||||
|
|
||||||
cv::imwrite("vis_result.jpg", vis_img);
|
|
||||||
std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrtInfer(const std::string& det_model_dir,
|
|
||||||
const std::string& cls_model_dir,
|
|
||||||
const std::string& rec_model_dir,
|
|
||||||
const std::string& rec_label_file,
|
|
||||||
const std::string& image_file) {
|
|
||||||
auto det_model_file = det_model_dir + sep + "inference.pdmodel";
|
|
||||||
auto det_params_file = det_model_dir + sep + "inference.pdiparams";
|
|
||||||
|
|
||||||
auto cls_model_file = cls_model_dir + sep + "inference.pdmodel";
|
|
||||||
auto cls_params_file = cls_model_dir + sep + "inference.pdiparams";
|
|
||||||
|
|
||||||
auto rec_model_file = rec_model_dir + sep + "inference.pdmodel";
|
|
||||||
auto rec_params_file = rec_model_dir + sep + "inference.pdiparams";
|
|
||||||
auto rec_label = rec_label_file;
|
|
||||||
|
|
||||||
fastdeploy::vision::ocr::DBDetector det_model;
|
|
||||||
fastdeploy::vision::ocr::Classifier cls_model;
|
|
||||||
fastdeploy::vision::ocr::Recognizer rec_model;
|
|
||||||
|
|
||||||
//准备模型
|
|
||||||
if (!det_model_dir.empty()) {
|
|
||||||
auto det_option = fastdeploy::RuntimeOption();
|
|
||||||
det_option.UseGpu();
|
|
||||||
det_option.UseTrtBackend();
|
|
||||||
det_option.SetTrtInputShape("x", {1, 3, 50, 50}, {1, 3, 640, 640},
|
|
||||||
{1, 3, 960, 960});
|
|
||||||
|
|
||||||
det_model = fastdeploy::vision::ocr::DBDetector(
|
|
||||||
det_model_file, det_params_file, det_option);
|
|
||||||
|
|
||||||
if (!det_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize det_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cls_model_dir.empty()) {
|
|
||||||
auto cls_option = fastdeploy::RuntimeOption();
|
|
||||||
cls_option.UseGpu();
|
|
||||||
cls_option.UseTrtBackend();
|
|
||||||
cls_option.SetTrtInputShape("x", {1, 3, 48, 192});
|
|
||||||
|
|
||||||
cls_model = fastdeploy::vision::ocr::Classifier(
|
|
||||||
cls_model_file, cls_params_file, cls_option);
|
|
||||||
|
|
||||||
if (!cls_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize cls_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rec_model_dir.empty()) {
|
|
||||||
auto rec_option = fastdeploy::RuntimeOption();
|
|
||||||
rec_option.UseGpu();
|
|
||||||
rec_option.UseTrtBackend();
|
|
||||||
rec_option.SetTrtInputShape("x", {1, 3, 48, 10}, {1, 3, 48, 320},
|
|
||||||
{1, 3, 48, 2000});
|
|
||||||
|
|
||||||
rec_model = fastdeploy::vision::ocr::Recognizer(
|
|
||||||
rec_model_file, rec_params_file, rec_label, rec_option);
|
|
||||||
|
|
||||||
if (!rec_model.Initialized()) {
|
|
||||||
std::cerr << "Failed to initialize rec_model." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ocrv3_app = fastdeploy::application::ocrsystem::PPOCRSystemv3(
|
|
||||||
&det_model, &cls_model, &rec_model);
|
|
||||||
|
|
||||||
auto im = cv::imread(image_file);
|
|
||||||
auto im_bak = im.clone();
|
|
||||||
|
|
||||||
fastdeploy::vision::OCRResult res;
|
|
||||||
//开始预测
|
|
||||||
if (!ocrv3_app.Predict(&im, &res)) {
|
|
||||||
std::cerr << "Failed to predict." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//输出预测信息
|
|
||||||
std::cout << res.Str() << std::endl;
|
|
||||||
|
|
||||||
//可视化
|
|
||||||
auto vis_img = fastdeploy::vision::Visualize::VisOcr(im_bak, res);
|
|
||||||
|
|
||||||
cv::imwrite("vis_result.jpg", vis_img);
|
|
||||||
std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl;
|
std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,12 +72,23 @@ int main(int argc, char* argv[]) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::atoi(argv[6]) == 0) {
|
fastdeploy::RuntimeOption option;
|
||||||
CpuInfer(argv[1], argv[2], argv[3], argv[4], argv[5]);
|
int flag = std::atoi(argv[6]);
|
||||||
} else if (std::atoi(argv[6]) == 1) {
|
|
||||||
GpuInfer(argv[1], argv[2], argv[3], argv[4], argv[5]);
|
if (flag == 0) {
|
||||||
} else if (std::atoi(argv[6]) == 2) {
|
option.UseCpu();
|
||||||
TrtInfer(argv[1], argv[2], argv[3], argv[4], argv[5]);
|
} else if (flag == 1) {
|
||||||
|
option.UseGpu();
|
||||||
|
} else if (flag == 2) {
|
||||||
|
option.UseGpu();
|
||||||
|
option.UseTrtBackend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string det_model_dir = argv[1];
|
||||||
|
std::string cls_model_dir = argv[2];
|
||||||
|
std::string rec_model_dir = argv[3];
|
||||||
|
std::string rec_label_file = argv[4];
|
||||||
|
std::string test_image = argv[5];
|
||||||
|
InitAndInfer(det_model_dir, cls_model_dir, rec_model_dir, rec_label_file, test_image, option);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@@ -19,10 +19,9 @@ tar -xvf ch_ppocr_mobile_v2.0_cls_infer.tar.gz
|
|||||||
wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_infer.tar
|
wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_infer.tar
|
||||||
tar xvf ch_PP-OCRv3_rec_infer.tar
|
tar xvf ch_PP-OCRv3_rec_infer.tar
|
||||||
|
|
||||||
wget https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/release/2.6/doc/imgs/12.jpg
|
wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/doc/imgs/12.jpg
|
||||||
|
|
||||||
wget https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/release/2.6/ppocr/utils/ppocr_keys_v1.txt
|
|
||||||
|
|
||||||
|
wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/ppocr/utils/ppocr_keys_v1.txt
|
||||||
|
|
||||||
#下载部署示例代码
|
#下载部署示例代码
|
||||||
git clone https://github.com/PaddlePaddle/FastDeploy.git
|
git clone https://github.com/PaddlePaddle/FastDeploy.git
|
||||||
@@ -33,9 +32,7 @@ python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2
|
|||||||
# GPU推理
|
# GPU推理
|
||||||
python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu
|
python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu
|
||||||
# GPU上使用TensorRT推理
|
# GPU上使用TensorRT推理
|
||||||
python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --det_use_trt True --cls_use_trt True --rec_use_trt True
|
python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend trt
|
||||||
# OCR还支持det/cls/rec三个模型的组合使用,例如当我们不想使用cls模型的时候,只需要给--cls_model传入一个空的字符串, 例子如下:
|
|
||||||
python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model "" --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu
|
|
||||||
```
|
```
|
||||||
|
|
||||||
运行完成可视化结果如下图所示
|
运行完成可视化结果如下图所示
|
||||||
|
@@ -1,3 +1,17 @@
|
|||||||
|
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
import fastdeploy as fd
|
import fastdeploy as fd
|
||||||
import cv2
|
import cv2
|
||||||
import os
|
import os
|
||||||
@@ -21,7 +35,6 @@ def parse_arguments():
|
|||||||
"--rec_label_file",
|
"--rec_label_file",
|
||||||
required=True,
|
required=True,
|
||||||
help="Path of Recognization model of PPOCR.")
|
help="Path of Recognization model of PPOCR.")
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--image", type=str, required=True, help="Path of test image file.")
|
"--image", type=str, required=True, help="Path of test image file.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
@@ -30,112 +43,82 @@ def parse_arguments():
|
|||||||
default='cpu',
|
default='cpu',
|
||||||
help="Type of inference device, support 'cpu' or 'gpu'.")
|
help="Type of inference device, support 'cpu' or 'gpu'.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--det_use_trt",
|
"--backend",
|
||||||
type=ast.literal_eval,
|
type=str,
|
||||||
default=False,
|
default="default",
|
||||||
help="Wether to use tensorrt.")
|
help="Type of inference backend, support ort/trt/paddle/openvino, default 'openvino' for cpu, 'tensorrt' for gpu"
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--cls_use_trt",
|
"--device_id",
|
||||||
type=ast.literal_eval,
|
type=int,
|
||||||
default=False,
|
default=0,
|
||||||
help="Wether to use tensorrt.")
|
help="Define which GPU card used to run model.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--rec_use_trt",
|
"--cpu_thread_num",
|
||||||
type=ast.literal_eval,
|
type=int,
|
||||||
default=False,
|
default=9,
|
||||||
help="Wether to use tensorrt.")
|
help="Number of threads while inference on CPU.")
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
def build_det_option(args):
|
def build_option(args):
|
||||||
option = fd.RuntimeOption()
|
option = fd.RuntimeOption()
|
||||||
|
|
||||||
if args.device.lower() == "gpu":
|
if args.device.lower() == "gpu":
|
||||||
option.use_gpu()
|
option.use_gpu(0)
|
||||||
|
|
||||||
if args.det_use_trt:
|
option.set_cpu_thread_num(args.cpu_thread_num)
|
||||||
|
|
||||||
|
if args.backend.lower() == "trt":
|
||||||
|
assert args.device.lower(
|
||||||
|
) == "gpu", "TensorRT backend require inference on device GPU."
|
||||||
option.use_trt_backend()
|
option.use_trt_backend()
|
||||||
#det_max_side_len 默认为960,当用户更改DET模型的max_side_len参数时,请将此参数同时更改
|
elif args.backend.lower() == "ort":
|
||||||
det_max_side_len = 960
|
option.use_ort_backend()
|
||||||
option.set_trt_input_shape("x", [1, 3, 50, 50], [1, 3, 640, 640],
|
elif args.backend.lower() == "paddle":
|
||||||
[1, 3, det_max_side_len, det_max_side_len])
|
option.use_paddle_backend()
|
||||||
|
elif args.backend.lower() == "openvino":
|
||||||
return option
|
assert args.device.lower(
|
||||||
|
) == "cpu", "OpenVINO backend require inference on device CPU."
|
||||||
|
option.use_openvino_backend()
|
||||||
def build_cls_option(args):
|
|
||||||
option = fd.RuntimeOption()
|
|
||||||
|
|
||||||
if args.device.lower() == "gpu":
|
|
||||||
option.use_gpu()
|
|
||||||
|
|
||||||
if args.cls_use_trt:
|
|
||||||
option.use_trt_backend()
|
|
||||||
option.set_trt_input_shape("x", [1, 3, 32, 100])
|
|
||||||
|
|
||||||
return option
|
|
||||||
|
|
||||||
|
|
||||||
def build_rec_option(args):
|
|
||||||
option = fd.RuntimeOption()
|
|
||||||
|
|
||||||
if args.device.lower() == "gpu":
|
|
||||||
option.use_gpu()
|
|
||||||
|
|
||||||
if args.rec_use_trt:
|
|
||||||
option.use_trt_backend()
|
|
||||||
option.set_trt_input_shape("x", [1, 3, 48, 10], [1, 3, 48, 320],
|
|
||||||
[1, 3, 48, 2000])
|
|
||||||
return option
|
return option
|
||||||
|
|
||||||
|
|
||||||
args = parse_arguments()
|
args = parse_arguments()
|
||||||
|
|
||||||
#Det模型
|
# Detection模型, 检测文字框
|
||||||
det_model_file = os.path.join(args.det_model, "inference.pdmodel")
|
det_model_file = os.path.join(args.det_model, "inference.pdmodel")
|
||||||
det_params_file = os.path.join(args.det_model, "inference.pdiparams")
|
det_params_file = os.path.join(args.det_model, "inference.pdiparams")
|
||||||
#Cls模型
|
# Classification模型,方向分类,可选
|
||||||
cls_model_file = os.path.join(args.cls_model, "inference.pdmodel")
|
cls_model_file = os.path.join(args.cls_model, "inference.pdmodel")
|
||||||
cls_params_file = os.path.join(args.cls_model, "inference.pdiparams")
|
cls_params_file = os.path.join(args.cls_model, "inference.pdiparams")
|
||||||
#Rec模型
|
# Recognition模型,文字识别模型
|
||||||
rec_model_file = os.path.join(args.rec_model, "inference.pdmodel")
|
rec_model_file = os.path.join(args.rec_model, "inference.pdmodel")
|
||||||
rec_params_file = os.path.join(args.rec_model, "inference.pdiparams")
|
rec_params_file = os.path.join(args.rec_model, "inference.pdiparams")
|
||||||
rec_label_file = args.rec_label_file
|
rec_label_file = args.rec_label_file
|
||||||
|
|
||||||
#默认
|
# 对于三个模型,均采用同样的部署配置
|
||||||
det_model = fd.vision.ocr.DBDetector()
|
# 用户也可根据自行需求分别配置
|
||||||
cls_model = fd.vision.ocr.Classifier()
|
runtime_option = build_option(args)
|
||||||
rec_model = fd.vision.ocr.Recognizer()
|
|
||||||
|
|
||||||
#模型初始化
|
det_model = fd.vision.ocr.DBDetector(
|
||||||
if (len(args.det_model) != 0):
|
det_model_file, det_params_file, runtime_option=runtime_option)
|
||||||
det_runtime_option = build_det_option(args)
|
cls_model = fd.vision.ocr.Classifier(
|
||||||
det_model = fd.vision.ocr.DBDetector(
|
cls_model_file, cls_params_file, runtime_option=runtime_option)
|
||||||
det_model_file, det_params_file, runtime_option=det_runtime_option)
|
rec_model = fd.vision.ocr.Recognizer(
|
||||||
|
rec_model_file,
|
||||||
|
rec_params_file,
|
||||||
|
rec_label_file,
|
||||||
|
runtime_option=runtime_option)
|
||||||
|
|
||||||
if (len(args.cls_model) != 0):
|
# 创建OCR系统,串联3个模型,其中cls_model可选,如无需求,可设置为None
|
||||||
cls_runtime_option = build_cls_option(args)
|
ocr_system = fd.vision.ocr.PPOCRSystemv3(
|
||||||
cls_model = fd.vision.ocr.Classifier(
|
det_model=det_model, cls_model=cls_model, rec_model=rec_model)
|
||||||
cls_model_file, cls_params_file, runtime_option=cls_runtime_option)
|
|
||||||
|
|
||||||
if (len(args.rec_model) != 0):
|
|
||||||
rec_runtime_option = build_rec_option(args)
|
|
||||||
rec_model = fd.vision.ocr.Recognizer(
|
|
||||||
rec_model_file,
|
|
||||||
rec_params_file,
|
|
||||||
rec_label_file,
|
|
||||||
runtime_option=rec_runtime_option)
|
|
||||||
|
|
||||||
ppocrsysv3 = fd.vision.ocr.PPOCRSystemv3(
|
|
||||||
ocr_det=det_model._model,
|
|
||||||
ocr_cls=cls_model._model,
|
|
||||||
ocr_rec=rec_model._model)
|
|
||||||
|
|
||||||
# 预测图片准备
|
# 预测图片准备
|
||||||
im = cv2.imread(args.image)
|
im = cv2.imread(args.image)
|
||||||
|
|
||||||
#预测并打印结果
|
#预测并打印结果
|
||||||
result = ppocrsysv3.predict(im)
|
result = ocr_system.predict(im)
|
||||||
|
|
||||||
print(result)
|
print(result)
|
||||||
|
|
||||||
|
7
external/openvino.cmake
vendored
7
external/openvino.cmake
vendored
@@ -124,12 +124,7 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
execute_process(COMMAND sh -c "ls *.so*" WORKING_DIRECTORY ${OPENVINO_INSTALL_DIR}/lib
|
add_custom_target(patchelf_openvino ALL COMMAND bash -c "sh ${PROJECT_SOURCE_DIR}/build_scripts/patch_lib.sh ${OPENVINO_INSTALL_DIR}/lib" DEPENDS ${LIBRARY_NAME})
|
||||||
COMMAND sh -c "xargs patchelf --set-rpath '$ORIGIN'" WORKING_DIRECTORY ${OPENVINO_INSTALL_DIR}/lib
|
|
||||||
RESULT_VARIABLE result
|
|
||||||
OUTPUT_VARIABLE curr_out
|
|
||||||
ERROR_VARIABLE curr_out)
|
|
||||||
message(STATUS "result:${result} out:${curr_out}")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(external_openvino STATIC IMPORTED GLOBAL)
|
add_library(external_openvino STATIC IMPORTED GLOBAL)
|
||||||
|
@@ -64,7 +64,7 @@ class RuntimeOption:
|
|||||||
def use_cpu(self):
|
def use_cpu(self):
|
||||||
return self._option.use_cpu()
|
return self._option.use_cpu()
|
||||||
|
|
||||||
def set_cpu_thread_num(self, thread_num=8):
|
def set_cpu_thread_num(self, thread_num=-1):
|
||||||
return self._option.set_cpu_thread_num(thread_num)
|
return self._option.set_cpu_thread_num(thread_num)
|
||||||
|
|
||||||
def use_paddle_backend(self):
|
def use_paddle_backend(self):
|
||||||
|
@@ -217,18 +217,24 @@ class Recognizer(FastDeployModel):
|
|||||||
|
|
||||||
|
|
||||||
class PPOCRSystemv3(FastDeployModel):
|
class PPOCRSystemv3(FastDeployModel):
|
||||||
def __init__(self, ocr_det=None, ocr_cls=None, ocr_rec=None):
|
def __init__(self, det_model=None, cls_model=None, rec_model=None):
|
||||||
|
assert det_model is not None and rec_model is not None, "The det_model and rec_model cannot be None."
|
||||||
self._model = C.vision.ocr.PPOCRSystemv3(ocr_det, ocr_cls, ocr_rec)
|
if cls_model is None:
|
||||||
|
self.system = C.vision.ocr.PPOCRSystemv3(det_model._model, rec_model._model)
|
||||||
|
else:
|
||||||
|
self.system = C.vision.ocr.PPOCRSystemv3(det_model._model, cls_model._model, rec_model._model)
|
||||||
|
|
||||||
def predict(self, input_image):
|
def predict(self, input_image):
|
||||||
return self._model.predict(input_image)
|
return self.system.predict(input_image)
|
||||||
|
|
||||||
|
|
||||||
class PPOCRSystemv2(FastDeployModel):
|
class PPOCRSystemv2(FastDeployModel):
|
||||||
def __init__(self, ocr_det=None, ocr_cls=None, ocr_rec=None):
|
def __init__(self, det_model=None, cls_model=None, rec_model=None):
|
||||||
|
assert det_model is not None and rec_model is not None, "The det_model and rec_model cannot be None."
|
||||||
self._model = C.vision.ocr.PPOCRSystemv2(ocr_det, ocr_cls, ocr_rec)
|
if cls_model is None:
|
||||||
|
self.system = C.vision.ocr.PPOCRSystemv2(det_model._model, rec_model._model)
|
||||||
|
else:
|
||||||
|
self.system = C.vision.ocr.PPOCRSystemv2(det_model._model, cls_model._model, rec_model._model)
|
||||||
|
|
||||||
def predict(self, input_image):
|
def predict(self, input_image):
|
||||||
return self._model.predict(input_image)
|
return self.system.predict(input_image)
|
||||||
|
Reference in New Issue
Block a user