diff --git a/deploy/lite/crnn_process.cc b/deploy/lite/crnn_process.cc index e6642b37049c19dc3c463aa2a0f77dab4b4a8b9f..ca2a9df24752d9596c89610341b214173736a1d0 100644 --- a/deploy/lite/crnn_process.cc +++ b/deploy/lite/crnn_process.cc @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "crnn_process.h" //NOLINT +#include "crnn_process.h" //NOLINT #include #include #include const std::vector rec_image_shape{3, 32, 320}; -cv::Mat CrnnResizeNormImg(cv::Mat img, float wh_ratio) { +cv::Mat CrnnResizeNormImg(cv::Mat img, float wh_ratio, bool is_norm) { int imgC, imgH, imgW; imgC = rec_image_shape[0]; imgW = rec_image_shape[2]; @@ -34,54 +34,31 @@ cv::Mat CrnnResizeNormImg(cv::Mat img, float wh_ratio) { else resize_w = int(ceilf(imgH * ratio)); cv::Mat resize_img; - cv::resize( - img, resize_img, cv::Size(resize_w, imgH), 0.f, 0.f, cv::INTER_CUBIC); - - resize_img.convertTo(resize_img, CV_32FC3, 1 / 255.f); - - for (int h = 0; h < resize_img.rows; h++) { - for (int w = 0; w < resize_img.cols; w++) { - resize_img.at(h, w)[0] = - (resize_img.at(h, w)[0] - 0.5) * 2; - resize_img.at(h, w)[1] = - (resize_img.at(h, w)[1] - 0.5) * 2; - resize_img.at(h, w)[2] = - (resize_img.at(h, w)[2] - 0.5) * 2; - } - } - - cv::Mat dist; - cv::copyMakeBorder(resize_img, - dist, - 0, - 0, - 0, - int(imgW - resize_w), - cv::BORDER_CONSTANT, - {0, 0, 0}); - - return dist; -} - -cv::Mat CrnnResizeImg(cv::Mat img, float wh_ratio) { - int imgC, imgH, imgW; - imgC = rec_image_shape[0]; - imgW = rec_image_shape[2]; - imgH = rec_image_shape[1]; + cv::resize(img, resize_img, cv::Size(resize_w, imgH), 0.f, 0.f, + cv::INTER_LINEAR); - imgW = int(32 * wh_ratio); + if (!is_norm) { + return resize_img; + } else { + resize_img.convertTo(resize_img, CV_32FC3, 1 / 255.f); + + for (int h = 0; h < resize_img.rows; h++) { + for (int w = 0; w < resize_img.cols; w++) { + resize_img.at(h, w)[0] = + (resize_img.at(h, w)[0] - 0.5) * 2; + resize_img.at(h, w)[1] = + (resize_img.at(h, w)[1] - 0.5) * 2; + resize_img.at(h, w)[2] = + (resize_img.at(h, w)[2] - 0.5) * 2; + } + } - float ratio = float(img.cols) / float(img.rows); - int resize_w, resize_h; - if (ceilf(imgH * ratio) > imgW) - resize_w = imgW; - else - resize_w = int(ceilf(imgH * ratio)); - cv::Mat resize_img; - cv::resize( - img, resize_img, cv::Size(resize_w, imgH), 0.f, 0.f, cv::INTER_LINEAR); + cv::Mat dist; + cv::copyMakeBorder(resize_img, dist, 0, 0, 0, int(imgW - resize_w), + cv::BORDER_CONSTANT, {0, 0, 0}); - return resize_img; + return dist; + } } std::vector ReadDict(std::string path) { @@ -140,9 +117,7 @@ cv::Mat GetRotateCropImage(cv::Mat srcimage, cv::Mat M = cv::getPerspectiveTransform(pointsf, pts_std); cv::Mat dst_img; - cv::warpPerspective(img_crop, - dst_img, - M, + cv::warpPerspective(img_crop, dst_img, M, cv::Size(img_crop_width, img_crop_height), cv::BORDER_REPLICATE); diff --git a/deploy/lite/crnn_process.h b/deploy/lite/crnn_process.h index b63f58ba80d04451ce921cb924d1a015a0647242..a27e3046dde9de37b5e7cecad55a48fbe02fadcc 100644 --- a/deploy/lite/crnn_process.h +++ b/deploy/lite/crnn_process.h @@ -21,14 +21,12 @@ #include #include -#include "math.h" //NOLINT +#include "math.h" //NOLINT #include "opencv2/core.hpp" #include "opencv2/imgcodecs.hpp" #include "opencv2/imgproc.hpp" -cv::Mat CrnnResizeNormImg(cv::Mat img, float wh_ratio); - -cv::Mat CrnnResizeImg(cv::Mat img, float wh_ratio); +cv::Mat CrnnResizeNormImg(cv::Mat img, float wh_ratio, bool is_norm); std::vector ReadDict(std::string path); diff --git a/deploy/lite/db_post_process.cc b/deploy/lite/db_post_process.cc index 78d1194167abb58263a611996f24900344a471b3..a6cffe7b8ebfc2489c01b8970da30b8d54300f22 100644 --- a/deploy/lite/db_post_process.cc +++ b/deploy/lite/db_post_process.cc @@ -276,4 +276,4 @@ FilterTagDetRes(std::vector>> boxes, float ratio_h, root_points.push_back(boxes[n]); } return root_points; -} \ No newline at end of file +} diff --git a/deploy/lite/ocr_db_crnn.cc b/deploy/lite/ocr_db_crnn.cc index e59cdcd4f4a415fd144bfe03f88a4a85c5c09ae3..76fa97034e1ee53a7f7c66791875f066c63898fa 100644 --- a/deploy/lite/ocr_db_crnn.cc +++ b/deploy/lite/ocr_db_crnn.cc @@ -107,8 +107,9 @@ cv::Mat DetResizeImg(const cv::Mat img, int max_size_len, void RunRecModel(std::vector>> boxes, cv::Mat img, std::shared_ptr predictor_crnn, - std::string dict_path, std::vector &rec_text, - std::vector &rec_text_score) { + std::vector &rec_text, + std::vector &rec_text_score, + std::vector charactor_dict) { std::vector mean = {0.5f, 0.5f, 0.5f}; std::vector scale = {1 / 0.5f, 1 / 0.5f, 1 / 0.5f}; @@ -117,14 +118,12 @@ void RunRecModel(std::vector>> boxes, cv::Mat img, cv::Mat crop_img; cv::Mat resize_img; - auto charactor_dict = ReadDict(dict_path); - int index = 0; for (int i = boxes.size() - 1; i >= 0; i--) { crop_img = GetRotateCropImage(srcimg, boxes[i]); float wh_ratio = float(crop_img.cols) / float(crop_img.rows); - resize_img = CrnnResizeImg(crop_img, wh_ratio); + resize_img = CrnnResizeNormImg(crop_img, wh_ratio, false); resize_img.convertTo(resize_img, CV_32FC3, 1 / 255.f); const float *dimg = reinterpret_cast(resize_img.data); @@ -227,13 +226,12 @@ RunDetModel(std::shared_ptr predictor, cv::Mat img, auto shape_out = output_tensor->shape(); // Save output - float pred[shape_out[2]][shape_out[3]]; - unsigned char cbuf[shape_out[2]][shape_out[3]]; + float pred[shape_out[2] * shape_out[3]]; + unsigned char cbuf[shape_out[2] * shape_out[3]]; for (int i = 0; i < int(shape_out[2] * shape_out[3]); i++) { - pred[int(i / int(shape_out[3]))][int(i % shape_out[3])] = float(outptr[i]); - cbuf[int(i / int(shape_out[3]))][int(i % shape_out[3])] = - (unsigned char)((outptr[i]) * 255); + pred[i] = float(outptr[i]); + cbuf[i] = (unsigned char)((outptr[i]) * 255); } cv::Mat cbuf_map(shape_out[2], shape_out[3], CV_8UC1, (unsigned char *)cbuf); @@ -333,13 +331,15 @@ int main(int argc, char **argv) { auto det_predictor = loadModel(det_model_file); auto rec_predictor = loadModel(rec_model_file); + auto charactor_dict = ReadDict(dict_path); + cv::Mat srcimg = cv::imread(img_path, cv::IMREAD_COLOR); auto boxes = RunDetModel(det_predictor, srcimg, Config); std::vector rec_text; std::vector rec_text_score; - RunRecModel(boxes, srcimg, rec_predictor, dict_path, rec_text, - rec_text_score); + RunRecModel(boxes, srcimg, rec_predictor, rec_text, rec_text_score, + charactor_dict); auto end = std::chrono::system_clock::now(); auto duration = diff --git a/deploy/lite/readme.md b/deploy/lite/readme.md index 604ce0a91eb309c12ea0687fae82b5c17a237090..40260103fadd1af8f037f7c8abd0b3b9ab1764da 100644 --- a/deploy/lite/readme.md +++ b/deploy/lite/readme.md @@ -1,6 +1,6 @@ -# PaddleOCR 模型部署 +# PaddleOCR 端侧模型部署 -PaddleOCR是集训练、预测、端侧部署于一体的实用OCR工具库。本教程将介绍在安卓移动端部署PaddleOCR超轻量中文检测、识别模型的主要流程。 +本教程将介绍在移动端部署PaddleOCR超轻量中文检测、识别模型的详细步骤。 ## 1. 准备环境 @@ -159,6 +159,7 @@ demo/cxx/ocr/ | |--11.jpg 待测试图像 | |--ppocr_keys_v1.txt 字典文件 | |--libpaddle_light_api_shared.so C++预测库文件 +| |--config.txt DB-CRNN超参数配置 |-- config.txt DB-CRNN超参数配置 |-- crnn_process.cc 识别模型CRNN的预处理和后处理文件 |-- crnn_process.h