main.cpp 11.2 KB
Newer Older
MissPenguin's avatar
MissPenguin committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 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.

#include "omp.h"
#include "opencv2/core.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include <chrono>
#include <iomanip>
#include <iostream>
#include <ostream>
WenmuZhou's avatar
WenmuZhou committed
23
#include <sys/stat.h>
MissPenguin's avatar
MissPenguin committed
24
25
26
27
28
29
#include <vector>

#include <cstring>
#include <fstream>
#include <numeric>

WenmuZhou's avatar
WenmuZhou committed
30
#include <include/args.h>
MissPenguin's avatar
MissPenguin committed
31
#include <include/ocr_cls.h>
WenmuZhou's avatar
WenmuZhou committed
32
#include <include/ocr_det.h>
MissPenguin's avatar
MissPenguin committed
33
#include <include/ocr_rec.h>
MissPenguin's avatar
MissPenguin committed
34
#include <include/utility.h>
MissPenguin's avatar
MissPenguin committed
35
36
#include <sys/stat.h>

MissPenguin's avatar
MissPenguin committed
37
#include "auto_log/autolog.h"
MissPenguin's avatar
MissPenguin committed
38
39
40
41
42

using namespace std;
using namespace cv;
using namespace PaddleOCR;

WenmuZhou's avatar
WenmuZhou committed
43
static bool PathExists(const std::string &path) {
MissPenguin's avatar
MissPenguin committed
44
45
46
47
48
49
#ifdef _WIN32
  struct _stat buffer;
  return (_stat(path.c_str(), &buffer) == 0);
#else
  struct stat buffer;
  return (stat(path.c_str(), &buffer) == 0);
WenmuZhou's avatar
WenmuZhou committed
50
#endif // !_WIN32
MissPenguin's avatar
MissPenguin committed
51
52
}

MissPenguin's avatar
MissPenguin committed
53
int main_det(std::vector<cv::String> cv_all_img_names) {
WenmuZhou's avatar
WenmuZhou committed
54
55
56
57
58
  std::vector<double> time_info = {0, 0, 0};
  DBDetector det(FLAGS_det_model_dir, FLAGS_use_gpu, FLAGS_gpu_id,
                 FLAGS_gpu_mem, FLAGS_cpu_threads, FLAGS_enable_mkldnn,
                 FLAGS_max_side_len, FLAGS_det_db_thresh,
                 FLAGS_det_db_box_thresh, FLAGS_det_db_unclip_ratio,
59
                 FLAGS_det_db_score_mode, FLAGS_use_dilation,
WenmuZhou's avatar
WenmuZhou committed
60
                 FLAGS_use_tensorrt, FLAGS_precision);
WenmuZhou's avatar
WenmuZhou committed
61

WenmuZhou's avatar
WenmuZhou committed
62
63
64
65
  if (!PathExists(FLAGS_output)) {
    mkdir(FLAGS_output.c_str(), 0777);
  }

WenmuZhou's avatar
WenmuZhou committed
66
  for (int i = 0; i < cv_all_img_names.size(); ++i) {
WenmuZhou's avatar
WenmuZhou committed
67
68
69
    if (!FLAGS_benchmark) {
      cout << "The predict img: " << cv_all_img_names[i] << endl;
    }
WenmuZhou's avatar
WenmuZhou committed
70
71
72
73
74
75
76
77
78
79
80

    cv::Mat srcimg = cv::imread(cv_all_img_names[i], cv::IMREAD_COLOR);
    if (!srcimg.data) {
      std::cerr << "[ERROR] image read failed! image path: "
                << cv_all_img_names[i] << endl;
      exit(1);
    }
    std::vector<std::vector<std::vector<int>>> boxes;
    std::vector<double> det_times;

    det.Run(srcimg, boxes, &det_times);
WenmuZhou's avatar
WenmuZhou committed
81
    // visualization
WenmuZhou's avatar
WenmuZhou committed
82
83
84
85
    if (FLAGS_visualize) {
      std::string file_name = Utility::basename(cv_all_img_names[i]);
      Utility::VisualizeBboxes(srcimg, boxes, FLAGS_output + "/" + file_name);
    }
WenmuZhou's avatar
WenmuZhou committed
86
87
88
89
    time_info[0] += det_times[0];
    time_info[1] += det_times[1];
    time_info[2] += det_times[2];

MissPenguin's avatar
MissPenguin committed
90
    if (FLAGS_benchmark) {
91
      cout << cv_all_img_names[i] << "\t[";
WenmuZhou's avatar
WenmuZhou committed
92
      for (int n = 0; n < boxes.size(); n++) {
93
        cout << '[';
WenmuZhou's avatar
WenmuZhou committed
94
        for (int m = 0; m < boxes[n].size(); m++) {
95
96
97
98
99
100
101
102
          cout << '[' << boxes[n][m][0] << ',' << boxes[n][m][1] << "]";
          if (m != boxes[n].size() - 1) {
            cout << ',';
          }
        }
        cout << ']';
        if (n != boxes.size() - 1) {
          cout << ',';
WenmuZhou's avatar
WenmuZhou committed
103
104
        }
      }
105
      cout << ']' << endl;
MissPenguin's avatar
MissPenguin committed
106
    }
WenmuZhou's avatar
WenmuZhou committed
107
  }
MissPenguin's avatar
MissPenguin committed
108

WenmuZhou's avatar
WenmuZhou committed
109
110
111
112
113
114
115
116
  if (FLAGS_benchmark) {
    AutoLogger autolog("ocr_det", FLAGS_use_gpu, FLAGS_use_tensorrt,
                       FLAGS_enable_mkldnn, FLAGS_cpu_threads, 1, "dynamic",
                       FLAGS_precision, time_info, cv_all_img_names.size());
    autolog.report();
  }
  return 0;
}
MissPenguin's avatar
MissPenguin committed
117

MissPenguin's avatar
MissPenguin committed
118
int main_rec(std::vector<cv::String> cv_all_img_names) {
WenmuZhou's avatar
WenmuZhou committed
119
  std::vector<double> time_info = {0, 0, 0};
MissPenguin's avatar
MissPenguin committed
120

WenmuZhou's avatar
WenmuZhou committed
121
122
  std::string rec_char_dict_path = FLAGS_rec_char_dict_path;
  cout << "label file: " << rec_char_dict_path << endl;
MissPenguin's avatar
MissPenguin committed
123

WenmuZhou's avatar
WenmuZhou committed
124
125
  CRNNRecognizer rec(FLAGS_rec_model_dir, FLAGS_use_gpu, FLAGS_gpu_id,
                     FLAGS_gpu_mem, FLAGS_cpu_threads, FLAGS_enable_mkldnn,
WenmuZhou's avatar
WenmuZhou committed
126
                     rec_char_dict_path, FLAGS_use_tensorrt, FLAGS_precision,
WenmuZhou's avatar
WenmuZhou committed
127
128
129
130
131
132
133
134
135
                     FLAGS_rec_batch_num);

  std::vector<cv::Mat> img_list;
  for (int i = 0; i < cv_all_img_names.size(); ++i) {
    cv::Mat srcimg = cv::imread(cv_all_img_names[i], cv::IMREAD_COLOR);
    if (!srcimg.data) {
      std::cerr << "[ERROR] image read failed! image path: "
                << cv_all_img_names[i] << endl;
      exit(1);
MissPenguin's avatar
MissPenguin committed
136
    }
WenmuZhou's avatar
WenmuZhou committed
137
138
    img_list.push_back(srcimg);
  }
WenmuZhou's avatar
WenmuZhou committed
139
140
  std::vector<std::string> rec_texts(img_list.size(), "");
  std::vector<float> rec_text_scores(img_list.size(), 0);
WenmuZhou's avatar
WenmuZhou committed
141
  std::vector<double> rec_times;
WenmuZhou's avatar
WenmuZhou committed
142
143
144
145
146
147
  rec.Run(img_list, rec_texts, rec_text_scores, &rec_times);
  // output rec results
  for (int i = 0; i < rec_texts.size(); i++) {
    cout << "The predict img: " << cv_all_img_names[i] << "\t" << rec_texts[i]
         << "\t" << rec_text_scores[i] << endl;
  }
WenmuZhou's avatar
WenmuZhou committed
148
149
150
  time_info[0] += rec_times[0];
  time_info[1] += rec_times[1];
  time_info[2] += rec_times[2];
MissPenguin's avatar
MissPenguin committed
151

WenmuZhou's avatar
WenmuZhou committed
152
153
154
155
156
157
158
159
160
  if (FLAGS_benchmark) {
    AutoLogger autolog("ocr_rec", FLAGS_use_gpu, FLAGS_use_tensorrt,
                       FLAGS_enable_mkldnn, FLAGS_cpu_threads,
                       FLAGS_rec_batch_num, "dynamic", FLAGS_precision,
                       time_info, cv_all_img_names.size());
    autolog.report();
  }
  return 0;
}
MissPenguin's avatar
MissPenguin committed
161

MissPenguin's avatar
MissPenguin committed
162
int main_system(std::vector<cv::String> cv_all_img_names) {
WenmuZhou's avatar
WenmuZhou committed
163
164
  std::vector<double> time_info_det = {0, 0, 0};
  std::vector<double> time_info_rec = {0, 0, 0};
MissPenguin's avatar
MissPenguin committed
165

WenmuZhou's avatar
WenmuZhou committed
166
167
168
169
  if (!PathExists(FLAGS_output)) {
    mkdir(FLAGS_output.c_str(), 0777);
  }

WenmuZhou's avatar
WenmuZhou committed
170
171
172
173
  DBDetector det(FLAGS_det_model_dir, FLAGS_use_gpu, FLAGS_gpu_id,
                 FLAGS_gpu_mem, FLAGS_cpu_threads, FLAGS_enable_mkldnn,
                 FLAGS_max_side_len, FLAGS_det_db_thresh,
                 FLAGS_det_db_box_thresh, FLAGS_det_db_unclip_ratio,
174
                 FLAGS_det_db_score_mode, FLAGS_use_dilation,
WenmuZhou's avatar
WenmuZhou committed
175
                 FLAGS_use_tensorrt, FLAGS_precision);
WenmuZhou's avatar
WenmuZhou committed
176
177
178
179
180
181
182
183

  Classifier *cls = nullptr;
  if (FLAGS_use_angle_cls) {
    cls = new Classifier(FLAGS_cls_model_dir, FLAGS_use_gpu, FLAGS_gpu_id,
                         FLAGS_gpu_mem, FLAGS_cpu_threads, FLAGS_enable_mkldnn,
                         FLAGS_cls_thresh, FLAGS_use_tensorrt, FLAGS_precision);
  }

WenmuZhou's avatar
WenmuZhou committed
184
185
  std::string rec_char_dict_path = FLAGS_rec_char_dict_path;
  cout << "label file: " << rec_char_dict_path << endl;
WenmuZhou's avatar
WenmuZhou committed
186
187
188

  CRNNRecognizer rec(FLAGS_rec_model_dir, FLAGS_use_gpu, FLAGS_gpu_id,
                     FLAGS_gpu_mem, FLAGS_cpu_threads, FLAGS_enable_mkldnn,
WenmuZhou's avatar
WenmuZhou committed
189
                     rec_char_dict_path, FLAGS_use_tensorrt, FLAGS_precision,
WenmuZhou's avatar
WenmuZhou committed
190
191
192
                     FLAGS_rec_batch_num);

  for (int i = 0; i < cv_all_img_names.size(); ++i) {
WenmuZhou's avatar
WenmuZhou committed
193
    cout << "The predict img: " << cv_all_img_names[i] << endl;
MissPenguin's avatar
MissPenguin committed
194

WenmuZhou's avatar
WenmuZhou committed
195
196
197
198
199
    cv::Mat srcimg = cv::imread(cv_all_img_names[i], cv::IMREAD_COLOR);
    if (!srcimg.data) {
      std::cerr << "[ERROR] image read failed! image path: "
                << cv_all_img_names[i] << endl;
      exit(1);
MissPenguin's avatar
MissPenguin committed
200
    }
WenmuZhou's avatar
WenmuZhou committed
201
    // det
WenmuZhou's avatar
WenmuZhou committed
202
203
204
    std::vector<std::vector<std::vector<int>>> boxes;
    std::vector<double> det_times;
    std::vector<double> rec_times;
MissPenguin's avatar
MissPenguin committed
205

WenmuZhou's avatar
WenmuZhou committed
206
    det.Run(srcimg, boxes, &det_times);
WenmuZhou's avatar
WenmuZhou committed
207
208
209
210
    if (FLAGS_visualize) {
      std::string file_name = Utility::basename(cv_all_img_names[i]);
      Utility::VisualizeBboxes(srcimg, boxes, FLAGS_output + "/" + file_name);
    }
WenmuZhou's avatar
WenmuZhou committed
211
212
213
    time_info_det[0] += det_times[0];
    time_info_det[1] += det_times[1];
    time_info_det[2] += det_times[2];
MissPenguin's avatar
MissPenguin committed
214

WenmuZhou's avatar
WenmuZhou committed
215
    // rec
WenmuZhou's avatar
WenmuZhou committed
216
217
218
219
220
221
222
223
    std::vector<cv::Mat> img_list;
    for (int j = 0; j < boxes.size(); j++) {
      cv::Mat crop_img;
      crop_img = Utility::GetRotateCropImage(srcimg, boxes[j]);
      if (cls != nullptr) {
        crop_img = cls->Run(crop_img);
      }
      img_list.push_back(crop_img);
MissPenguin's avatar
MissPenguin committed
224
    }
WenmuZhou's avatar
WenmuZhou committed
225
226
227
228
229
230
231
232
    std::vector<std::string> rec_texts(img_list.size(), "");
    std::vector<float> rec_text_scores(img_list.size(), 0);
    rec.Run(img_list, rec_texts, rec_text_scores, &rec_times);
    // output rec results
    for (int i = 0; i < rec_texts.size(); i++) {
      std::cout << i << "\t" << rec_texts[i] << "\t" << rec_text_scores[i]
                << std::endl;
    }
WenmuZhou's avatar
WenmuZhou committed
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
    time_info_rec[0] += rec_times[0];
    time_info_rec[1] += rec_times[1];
    time_info_rec[2] += rec_times[2];
  }

  if (FLAGS_benchmark) {
    AutoLogger autolog_det("ocr_det", FLAGS_use_gpu, FLAGS_use_tensorrt,
                           FLAGS_enable_mkldnn, FLAGS_cpu_threads, 1, "dynamic",
                           FLAGS_precision, time_info_det,
                           cv_all_img_names.size());
    AutoLogger autolog_rec("ocr_rec", FLAGS_use_gpu, FLAGS_use_tensorrt,
                           FLAGS_enable_mkldnn, FLAGS_cpu_threads,
                           FLAGS_rec_batch_num, "dynamic", FLAGS_precision,
                           time_info_rec, cv_all_img_names.size());
    autolog_det.report();
    std::cout << endl;
    autolog_rec.report();
  }
  return 0;
}

void check_params(char *mode) {
  if (strcmp(mode, "det") == 0) {
    if (FLAGS_det_model_dir.empty() || FLAGS_image_dir.empty()) {
      std::cout << "Usage[det]: ./ppocr "
                   "--det_model_dir=/PATH/TO/DET_INFERENCE_MODEL/ "
                << "--image_dir=/PATH/TO/INPUT/IMAGE/" << std::endl;
      exit(1);
MissPenguin's avatar
MissPenguin committed
261
    }
WenmuZhou's avatar
WenmuZhou committed
262
263
264
265
266
267
268
  }
  if (strcmp(mode, "rec") == 0) {
    if (FLAGS_rec_model_dir.empty() || FLAGS_image_dir.empty()) {
      std::cout << "Usage[rec]: ./ppocr "
                   "--rec_model_dir=/PATH/TO/REC_INFERENCE_MODEL/ "
                << "--image_dir=/PATH/TO/INPUT/IMAGE/" << std::endl;
      exit(1);
MissPenguin's avatar
MissPenguin committed
269
    }
WenmuZhou's avatar
WenmuZhou committed
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
  }
  if (strcmp(mode, "system") == 0) {
    if ((FLAGS_det_model_dir.empty() || FLAGS_rec_model_dir.empty() ||
         FLAGS_image_dir.empty()) ||
        (FLAGS_use_angle_cls && FLAGS_cls_model_dir.empty())) {
      std::cout << "Usage[system without angle cls]: ./ppocr "
                   "--det_model_dir=/PATH/TO/DET_INFERENCE_MODEL/ "
                << "--rec_model_dir=/PATH/TO/REC_INFERENCE_MODEL/ "
                << "--image_dir=/PATH/TO/INPUT/IMAGE/" << std::endl;
      std::cout << "Usage[system with angle cls]: ./ppocr "
                   "--det_model_dir=/PATH/TO/DET_INFERENCE_MODEL/ "
                << "--use_angle_cls=true "
                << "--cls_model_dir=/PATH/TO/CLS_INFERENCE_MODEL/ "
                << "--rec_model_dir=/PATH/TO/REC_INFERENCE_MODEL/ "
                << "--image_dir=/PATH/TO/INPUT/IMAGE/" << std::endl;
      exit(1);
MissPenguin's avatar
MissPenguin committed
286
    }
WenmuZhou's avatar
WenmuZhou committed
287
288
289
290
291
292
  }
  if (FLAGS_precision != "fp32" && FLAGS_precision != "fp16" &&
      FLAGS_precision != "int8") {
    cout << "precison should be 'fp32'(default), 'fp16' or 'int8'. " << endl;
    exit(1);
  }
MissPenguin's avatar
MissPenguin committed
293
294
}

MissPenguin's avatar
MissPenguin committed
295
int main(int argc, char **argv) {
WenmuZhou's avatar
WenmuZhou committed
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
  if (argc <= 1 ||
      (strcmp(argv[1], "det") != 0 && strcmp(argv[1], "rec") != 0 &&
       strcmp(argv[1], "system") != 0)) {
    std::cout << "Please choose one mode of [det, rec, system] !" << std::endl;
    return -1;
  }
  std::cout << "mode: " << argv[1] << endl;

  // Parsing command-line
  google::ParseCommandLineFlags(&argc, &argv, true);
  check_params(argv[1]);

  if (!PathExists(FLAGS_image_dir)) {
    std::cerr << "[ERROR] image path not exist! image_dir: " << FLAGS_image_dir
              << endl;
    exit(1);
  }

  std::vector<cv::String> cv_all_img_names;
  cv::glob(FLAGS_image_dir, cv_all_img_names);
  std::cout << "total images num: " << cv_all_img_names.size() << endl;
MissPenguin's avatar
MissPenguin committed
317

WenmuZhou's avatar
WenmuZhou committed
318
319
320
321
322
323
324
325
326
  if (strcmp(argv[1], "det") == 0) {
    return main_det(cv_all_img_names);
  }
  if (strcmp(argv[1], "rec") == 0) {
    return main_rec(cv_all_img_names);
  }
  if (strcmp(argv[1], "system") == 0) {
    return main_system(cv_all_img_names);
  }
MissPenguin's avatar
MissPenguin committed
327
}