由于工作需求,需要免费的一款移动端文字识别工具,网上第三方都需要付费方可使用,实在是难搞,于是通过Paddle OCR搭建了一款识别demo
准确率挺高,支持中英文。看效果如图:
下载地址:https://download.csdn/download/m0_37809901/85214446
文字识别是通过C++实现的
using namespace paddle::lite_api;
using namespace cv;
struct Object {
int batch_id;
cv::Rect rec;
int class_id;
float prob;
};
std::mutex mtx;
std::shared_ptr<PaddlePredictor> net_ocr1;
std::shared_ptr<PaddlePredictor> net_ocr2;
Timer tic;
long long count = 0;
- (NSArray *) ocr_infer:(cv::Mat) originImage{
int max_side_len = 960;
float ratio_h{};
float ratio_w{};
cv::Mat image;
cv::cvtColor(originImage, image, cv::COLOR_RGB2BGR);
cv::Mat img;
image.copyTo(img);
img = resize_img_type0(img, max_side_len, &ratio_h, &ratio_w);
cv::Mat img_fp;
img.convertTo(img_fp, CV_32FC3, 1.0 / 255.f);
std::unique_ptr<Tensor> input_tensor(net_ocr1->GetInput(0));
input_tensor->Resize({1, 3, img_fp.rows, img_fp.cols});
auto *data0 = input_tensor->mutable_data<float>();
const float *dimg = reinterpret_cast<const float *>(img_fp.data);
neon_mean_scale(dimg, data0, img_fp.rows * img_fp.cols, self.mean, self.scale);
tic.clear();
tic.start();
net_ocr1->Run();
std::unique_ptr<const Tensor> output_tensor(std::move(net_ocr1->GetOutput(0)));
auto *outptr = output_tensor->data<float>();
auto shape_out = output_tensor->shape();
int64_t out_numl = 1;
double sum = 0;
for (auto i : shape_out) {
out_numl *= i;
}
int s2 = int(shape_out[2]);
int s3 = int(shape_out[3]);
cv::Mat pred_map = cv::Mat::zeros(s2, s3, CV_32F);
memcpy(pred_map.data, outptr, s2 * s3 * sizeof(float));
cv::Mat cbuf_map;
pred_map.convertTo(cbuf_map, CV_8UC1, 255.0f);
const double threshold = 0.1 * 255;
const double maxvalue = 255;
cv::Mat bit_map;
cv::threshold(cbuf_map, bit_map, threshold, maxvalue, cv::THRESH_BINARY);
auto boxes = boxes_from_bitmap(pred_map, bit_map);
std::vector<std::vector<std::vector<int>>> filter_boxes = filter_tag_det_res(boxes, ratio_h, ratio_w, image);
cv::Point rook_points[filter_boxes.size()][4];
for (int n = 0; n < filter_boxes.size(); n++) {
for (int m = 0; m < filter_boxes[0].size(); m++) {
rook_points[n][m] = cv::Point(int(filter_boxes[n][m][0]), int(filter_boxes[n][m][1]));
}
}
NSMutableArray *result = [[NSMutableArray alloc] init];
for (int i = 0; i < filter_boxes.size(); i++) {
cv::Mat crop_img;
crop_img = get_rotate_crop_image(image, filter_boxes[i]);
OcrData *r = [self paddleOcrRec:crop_img ];
NSMutableArray *points = [NSMutableArray new];
for (int jj = 0; jj < 4; ++jj) {
NSValue *v = [NSValue valueWithCGPoint:CGPointMake(
rook_points[i][jj].x / CGFloat(originImage.cols),
rook_points[i][jj].y / CGFloat(originImage.rows))];
[points addObject:v];
}
r.polygonPoints = points;
[result addObject:r];
}
NSArray* rec_out =[[result reverseObjectEnumerator] allObjects];
tic.end();
std::cout<<"infer time: "<<tic.get_sum_ms()<<"ms"<<std::endl;
return rec_out;
}
更多推荐
Paddle OCR 移动端识别
发布评论