mirror of
https://github.com/RapidAI/RapidOCR.git
synced 2026-11-10 21:10:55 +08:00
Add rapidocr_api module
This commit is contained in:
1 parent
0c3a528904
commit
05d7e8874e
9 files changed
+505
-123
No files matched your search
@@ -0,0 +1,53 @@
|
||||
name: Push rapidocr_api to pypi
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
paths:
|
||||
- 'api/rapidocr_api/**'
|
||||
- 'docs/doc_whl_rapidocr_api.md'
|
||||
- 'api/setup.py'
|
||||
- '.github/workflows/gen_whl_to_pypi_rapidocr_api.yml'
|
||||
|
||||
jobs:
|
||||
GenerateWHL_PushPyPi:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python 3.7
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.7'
|
||||
architecture: 'x64'
|
||||
|
||||
- name: Set SSH Environment
|
||||
env:
|
||||
DEPLOY_KEYS: ${{ secrets.GEN_PYTHON_SDK }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh/
|
||||
echo "$DEPLOY_KEYS" > ~/.ssh/id_rsa
|
||||
chmod 600 ~/.ssh/id_rsa
|
||||
chmod 700 ~/.ssh && chmod 600 ~/.ssh/*
|
||||
|
||||
- name: Run setup.py
|
||||
run: |
|
||||
cd api
|
||||
pip install -r requirements.txt
|
||||
|
||||
python -m pip install --upgrade pip
|
||||
python setup.py bdist_wheel ${{ github.event.head_commit.message }}
|
||||
|
||||
# - name: Publish distribution 📦 to Test PyPI
|
||||
# uses: pypa/gh-action-pypi-publish@v1.5.0
|
||||
# with:
|
||||
# password: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
||||
# repository_url: https://test.pypi.org/legacy/
|
||||
# packages_dir: ocrweb/dist/
|
||||
|
||||
- name: Publish distribution 📦 to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@v1.5.0
|
||||
with:
|
||||
password: ${{ secrets.RAPIDOCR_API_PYPI }}
|
||||
packages_dir: api/dist/
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
## RapidOCR API
|
||||
|
||||
<p>
|
||||
<a href=""><img src="https://img.shields.io/badge/Python->=3.7,<=3.10-aff.svg"></a>
|
||||
<a href=""><img src="https://img.shields.io/badge/OS-Linux%2C%20Win%2C%20Mac-pink.svg"></a>
|
||||
<a href="https://pypi.org/project/rapidocr-api/"><img alt="PyPI" src="https://img.shields.io/pypi/v/rapidocr-api"></a>
|
||||
<a href="https://pepy.tech/project/rapidocr_api"><img src="https://static.pepy.tech/personalized-badge/rapidocr_api?period=total&units=abbreviation&left_color=grey&right_color=blue&left_text=Downloads"></a>
|
||||
</p>
|
||||
|
||||
- 采用FastAPI+uvicorn实现。
|
||||
|
||||
### 使用步骤
|
||||
1. 安装`rapidocr_api`
|
||||
```bash
|
||||
$ pip install rapidocr_api
|
||||
```
|
||||
2. 运行
|
||||
- 用法:
|
||||
```bash
|
||||
$ rapidocr_api -h
|
||||
usage: rapidocr_api [-h] [-ip IP] [-p PORT]
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-ip IP, --ip IP IP Address
|
||||
-p PORT, --port PORT IP port
|
||||
```
|
||||
- 示例:
|
||||
```bash
|
||||
$ rapidocr_api -ip 0.0.0.0 -p 9003
|
||||
```
|
||||
3. 使用(本质就是发送一个POST请求,其他语言同理)
|
||||
- 以文件的方式发送请求
|
||||
```python
|
||||
import requests
|
||||
|
||||
url = 'http://localhost:9003/ocr'
|
||||
img_path = '../python/tests/test_files/ch_en_num.jpg'
|
||||
|
||||
with open(img_path, 'rb') as f:
|
||||
file_dict = {'image_file': (img_path, f, 'image/png')}
|
||||
response = requests.post(url, files=file_dict, timeout=60)
|
||||
|
||||
print(response.json())
|
||||
```
|
||||
- 以`base64`方式发送post请求
|
||||
```python
|
||||
import base64
|
||||
import requests
|
||||
|
||||
url = 'http://localhost:9003/ocr'
|
||||
img_path = '../python/tests/test_files/ch_en_num.jpg'
|
||||
|
||||
with open(img_path, 'rb') as fa:
|
||||
img_str = base64.b64encode(fa.read())
|
||||
|
||||
payload = {'image_data': img_str}
|
||||
resp = requests.post(url, data=payload)
|
||||
|
||||
print(resp.json())
|
||||
```
|
||||
4. API输出
|
||||
- 示例结果:
|
||||
<details>
|
||||
<summary>详情</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"0": {
|
||||
"rec_txt": "香港深圳抽血,",
|
||||
"dt_boxes": [
|
||||
[265, 18],
|
||||
[472, 231],
|
||||
[431, 271],
|
||||
[223, 59]
|
||||
],
|
||||
"score": "0.8175641223788261"
|
||||
},
|
||||
"1": {
|
||||
"rec_txt": "专业查性别",
|
||||
"dt_boxes": [
|
||||
[388, 15],
|
||||
[636, 257],
|
||||
[587, 307],
|
||||
[339, 65]
|
||||
],
|
||||
"score": "0.8293875356515249"
|
||||
},
|
||||
"2": {
|
||||
"rec_txt": "专业鉴定B超单",
|
||||
"dt_boxes": [
|
||||
[215, 84],
|
||||
[509, 413],
|
||||
[453, 463],
|
||||
[159, 134]
|
||||
],
|
||||
"score": "0.8626169338822365"
|
||||
},
|
||||
"3": {
|
||||
"rec_txt": "b超仪器查性别",
|
||||
"dt_boxes": [
|
||||
[128, 135],
|
||||
[430, 478],
|
||||
[366, 534],
|
||||
[64, 192]
|
||||
],
|
||||
"score": "0.8449362441897392"
|
||||
},
|
||||
"4": {
|
||||
"rec_txt": "加微信eee",
|
||||
"dt_boxes": [
|
||||
[58, 189],
|
||||
[268, 450],
|
||||
[209, 498],
|
||||
[0, 236]
|
||||
],
|
||||
"score": "0.8176911813872201"
|
||||
},
|
||||
"5": {
|
||||
"rec_txt": "可邮寄",
|
||||
"dt_boxes": [
|
||||
[493, 261],
|
||||
[617, 384],
|
||||
[577, 423],
|
||||
[454, 300]
|
||||
],
|
||||
"score": "0.7494261413812637"
|
||||
}
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
- 输出结果说明:
|
||||
- 如果图像中存在文字,则会输出json格式,具体格式介绍如下:
|
||||
```python
|
||||
{
|
||||
"0": {
|
||||
"rec_txt": "香港深圳抽血,", # 识别的文本
|
||||
"dt_boxes": [ # 依次为左上角 → 右上角 → 右下角 → 左下角
|
||||
[265, 18],
|
||||
[472, 231],
|
||||
[431, 271],
|
||||
[223, 59]
|
||||
],
|
||||
"score": "0.8175641223788261" # 置信度
|
||||
}
|
||||
}
|
||||
```
|
||||
- 如果没有检测到文字,则会输出空json(`{}`)。
|
||||
5. **!!说明:OCR的输出结果为最原始结果,大家可按需进一步扩展。**
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# @Author: SWHL
|
||||
# @Contact: liekkaskono@163.com
|
||||
|
||||
import requests
|
||||
|
||||
url = 'http://localhost:9003/ocr'
|
||||
img_path = '../python/tests/test_files/ch_en_num.jpg'
|
||||
|
||||
with open(img_path, 'rb') as f:
|
||||
file_dict = {'image_file': (img_path, f, 'image/png')}
|
||||
response = requests.post(url, files=file_dict, timeout=60)
|
||||
|
||||
print(response.json())
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# @Author: SWHL
|
||||
# @Contact: liekkaskono@163.com
|
||||
@@ -0,0 +1,81 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# @Author: SWHL
|
||||
# @Contact: liekkaskono@163.com
|
||||
import argparse
|
||||
import base64
|
||||
import io
|
||||
import json
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
import uvicorn
|
||||
from fastapi import FastAPI, Form, UploadFile
|
||||
from PIL import Image
|
||||
from rapidocr_onnxruntime import RapidOCR
|
||||
|
||||
|
||||
sys.path.append(str(Path(__file__).resolve().parent.parent))
|
||||
|
||||
|
||||
class OCRAPIUtils():
|
||||
def __init__(self) -> None:
|
||||
self.ocr = RapidOCR()
|
||||
|
||||
def __call__(self, img):
|
||||
img = np.array(img)
|
||||
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
|
||||
|
||||
ocr_res, _ = self.ocr(img)
|
||||
if not ocr_res:
|
||||
return json.dumps({})
|
||||
|
||||
out_dict = {str(i): {'rec_txt': rec,
|
||||
'dt_boxes': dt_box,
|
||||
'score': score}
|
||||
for i, (dt_box, rec, score) in enumerate(ocr_res)}
|
||||
return json.dumps(out_dict, indent=2, ensure_ascii=False)
|
||||
|
||||
|
||||
app = FastAPI()
|
||||
processor = OCRAPIUtils()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def root():
|
||||
return {'message': 'Welcome to RapidOCR Server!'}
|
||||
|
||||
|
||||
@app.post('/ocr')
|
||||
async def ocr(image_file: UploadFile = None, image_data: str = Form(None)):
|
||||
if image_file:
|
||||
img = Image.open(image_file.file)
|
||||
elif image_data:
|
||||
img_bytes = str.encode(image_data)
|
||||
img_b64decode = base64.b64decode(img_bytes)
|
||||
img = Image.open(io.BytesIO(img_b64decode))
|
||||
else:
|
||||
raise ValueError(
|
||||
'When sending a post request, data or files must have a value.')
|
||||
|
||||
ocr_res = processor(img)
|
||||
return ocr_res
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser('rapidocr_api')
|
||||
parser.add_argument('-ip', '--ip', type=str, default='0.0.0.0',
|
||||
help='IP Address')
|
||||
parser.add_argument('-p', '--port', type=int, default=9003,
|
||||
help='IP port')
|
||||
args = parser.parse_args()
|
||||
|
||||
cur_file_path = Path(__file__).resolve()
|
||||
app_path = f'{cur_file_path.parent.name}.{cur_file_path.stem}:app'
|
||||
print(app_path)
|
||||
uvicorn.run(app_path, host=args.ip, port=args.port, reload=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,6 @@
|
||||
requests
|
||||
rapidocr_onnxruntime
|
||||
get_pypi_latest_version
|
||||
wheel
|
||||
fastapi
|
||||
uvicorn[standard]
|
||||
@@ -0,0 +1,67 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# @Author: SWHL
|
||||
# @Contact: liekkaskono@163.com
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import setuptools
|
||||
from get_pypi_latest_version import GetPyPiLatestVersion
|
||||
|
||||
|
||||
def get_readme():
|
||||
root_dir = Path(__file__).resolve().parent.parent
|
||||
readme_path = str(root_dir / 'docs' / 'doc_whl_rapidocr_api.md')
|
||||
with open(readme_path, 'r', encoding='utf-8') as f:
|
||||
readme = f.read()
|
||||
return readme
|
||||
|
||||
|
||||
MODULE_NAME = 'rapidocr_api'
|
||||
|
||||
obtainer = GetPyPiLatestVersion()
|
||||
try:
|
||||
latest_version = obtainer(MODULE_NAME)
|
||||
except ValueError:
|
||||
latest_version = '0.0.1'
|
||||
VERSION_NUM = obtainer.version_add_one(latest_version)
|
||||
|
||||
if len(sys.argv) > 2:
|
||||
match_str = ' '.join(sys.argv[2:])
|
||||
matched_versions = obtainer.extract_version(match_str)
|
||||
if matched_versions:
|
||||
VERSION_NUM = matched_versions
|
||||
sys.argv = sys.argv[:2]
|
||||
|
||||
setuptools.setup(
|
||||
name=MODULE_NAME,
|
||||
version=VERSION_NUM,
|
||||
platforms='Any',
|
||||
description='A cross platform OCR API Library based on OnnxRuntime.',
|
||||
long_description=get_readme(),
|
||||
long_description_content_type='text/markdown',
|
||||
author='SWHL',
|
||||
author_email='liekkaskono@163.com',
|
||||
url='https://github.com/RapidAI/RapidOCR',
|
||||
download_url='https://github.com/RapidAI/RapidOCR.git',
|
||||
license='Apache-2.0',
|
||||
include_package_data=True,
|
||||
install_requires=['requests', 'rapidocr_onnxruntime',
|
||||
'fastapi', 'uvicorn[standard]'],
|
||||
packages=[MODULE_NAME],
|
||||
package_data={'': ['*.ico', '*.css', '*.js', '*.html']},
|
||||
keywords=[
|
||||
'ocr,text_detection,text_recognition,db,onnxruntime,paddleocr,openvino,rapidocr'
|
||||
],
|
||||
classifiers=[
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
'Programming Language :: Python :: 3.10',
|
||||
],
|
||||
python_requires='>=3.7,<=3.10',
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
f'{MODULE_NAME}={MODULE_NAME}.api:main',
|
||||
],
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,130 @@
|
||||
## rapidocr-api
|
||||
<p>
|
||||
<a href=""><img src="https://img.shields.io/badge/Python->=3.7,<=3.10-aff.svg"></a>
|
||||
<a href=""><img src="https://img.shields.io/badge/OS-Linux%2C%20Win%2C%20Mac-pink.svg"></a>
|
||||
<a href="https://pypi.org/project/rapidocr-api/"><img alt="PyPI" src="https://img.shields.io/pypi/v/rapidocr-api"></a>
|
||||
<a href="https://pepy.tech/project/rapidocr_api"><img src="https://static.pepy.tech/personalized-badge/rapidocr_api?period=total&units=abbreviation&left_color=grey&right_color=blue&left_text=Downloads"></a>
|
||||
</p>
|
||||
|
||||
### Use
|
||||
1. Install`rapidocr_web[api]`
|
||||
```bash
|
||||
$ pip install rapidocr_web[api]
|
||||
```
|
||||
2. Run
|
||||
- Usage:
|
||||
```bash
|
||||
$ rapidocr_api -h
|
||||
usage: rapidocr_api [-h] [-ip IP] [-p PORT]
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-ip IP, --ip IP IP Address
|
||||
-p PORT, --port PORT IP port
|
||||
```
|
||||
- Example:
|
||||
```bash
|
||||
$ rapidocr_api -ip 0.0.0.0 -p 9003
|
||||
```
|
||||
3. Use
|
||||
- Send image data by file format.
|
||||
```python
|
||||
import requests
|
||||
|
||||
url = 'http://localhost:9003/ocr'
|
||||
img_path = '../python/tests/test_files/ch_en_num.jpg'
|
||||
|
||||
with open(img_path, 'rb') as f:
|
||||
file_dict = {'image_file': (img_path, f, 'image/png')}
|
||||
response = requests.post(url, files=file_dict, timeout=60)
|
||||
|
||||
print(response.json())
|
||||
```
|
||||
- Send image data by base64 format.
|
||||
```python
|
||||
import base64
|
||||
import requests
|
||||
|
||||
url = 'http://localhost:9003/ocr'
|
||||
img_path = '../python/tests/test_files/ch_en_num.jpg'
|
||||
|
||||
with open(img_path, 'rb') as fa:
|
||||
img_str = base64.b64encode(fa.read())
|
||||
|
||||
payload = {'image_data': img_str}
|
||||
resp = requests.post(url, data=payload)
|
||||
|
||||
print(resp.json())
|
||||
```
|
||||
4. Output
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"0": {
|
||||
"rec_txt": "香港深圳抽血,",
|
||||
"dt_boxes": [
|
||||
[265, 18],
|
||||
[472, 231],
|
||||
[431, 271],
|
||||
[223, 59]
|
||||
],
|
||||
"score": "0.8175641223788261"
|
||||
},
|
||||
"1": {
|
||||
"rec_txt": "专业查性别",
|
||||
"dt_boxes": [
|
||||
[388, 15],
|
||||
[636, 257],
|
||||
[587, 307],
|
||||
[339, 65]
|
||||
],
|
||||
"score": "0.8293875356515249"
|
||||
},
|
||||
"2": {
|
||||
"rec_txt": "专业鉴定B超单",
|
||||
"dt_boxes": [
|
||||
[215, 84],
|
||||
[509, 413],
|
||||
[453, 463],
|
||||
[159, 134]
|
||||
],
|
||||
"score": "0.8626169338822365"
|
||||
},
|
||||
"3": {
|
||||
"rec_txt": "b超仪器查性别",
|
||||
"dt_boxes": [
|
||||
[128, 135],
|
||||
[430, 478],
|
||||
[366, 534],
|
||||
[64, 192]
|
||||
],
|
||||
"score": "0.8449362441897392"
|
||||
},
|
||||
"4": {
|
||||
"rec_txt": "加微信eee",
|
||||
"dt_boxes": [
|
||||
[58, 189],
|
||||
[268, 450],
|
||||
[209, 498],
|
||||
[0, 236]
|
||||
],
|
||||
"score": "0.8176911813872201"
|
||||
},
|
||||
"5": {
|
||||
"rec_txt": "可邮寄",
|
||||
"dt_boxes": [
|
||||
[493, 261],
|
||||
[617, 384],
|
||||
[577, 423],
|
||||
[454, 300]
|
||||
],
|
||||
"score": "0.7494261413812637"
|
||||
}
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
### See details for [RapidOCR](https://github.com/RapidAI/RapidOCR/tree/main/ocrweb).
|
||||
@@ -6,8 +6,7 @@
|
||||
<a href="https://pepy.tech/project/rapidocr_web"><img src="https://static.pepy.tech/personalized-badge/rapidocr_web?period=total&units=abbreviation&left_color=grey&right_color=blue&left_text=Downloads"></a>
|
||||
</p>
|
||||
|
||||
### Web use
|
||||
|
||||
### use
|
||||
1. Install package by pypi.
|
||||
```bash
|
||||
$ pip install rapidocr-web
|
||||
@@ -29,125 +28,4 @@
|
||||
```
|
||||
3. Open `http://localhost:9003/` to view, enjoy it.
|
||||
|
||||
### API Use
|
||||
1. Install`rapidocr_web[api]`
|
||||
```bash
|
||||
$ pip install rapidocr_web[api]
|
||||
```
|
||||
2. Run
|
||||
- Usage:
|
||||
```bash
|
||||
$ rapidocr_api -h
|
||||
usage: rapidocr_api [-h] [-ip IP] [-p PORT]
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-ip IP, --ip IP IP Address
|
||||
-p PORT, --port PORT IP port
|
||||
```
|
||||
- Example:
|
||||
```bash
|
||||
$ rapidocr_api -ip 0.0.0.0 -p 9003
|
||||
```
|
||||
3. Use
|
||||
- Send image data by file format.
|
||||
```python
|
||||
import requests
|
||||
|
||||
url = 'http://localhost:9003/ocr'
|
||||
img_path = '../python/tests/test_files/ch_en_num.jpg'
|
||||
|
||||
with open(img_path, 'rb') as f:
|
||||
file_dict = {'image_file': (img_path, f, 'image/png')}
|
||||
response = requests.post(url, files=file_dict, timeout=60)
|
||||
|
||||
print(response.json())
|
||||
```
|
||||
- Send image data by base64 format.
|
||||
```python
|
||||
import base64
|
||||
import requests
|
||||
|
||||
url = 'http://localhost:9003/ocr'
|
||||
img_path = '../python/tests/test_files/ch_en_num.jpg'
|
||||
|
||||
with open(img_path, 'rb') as fa:
|
||||
img_str = base64.b64encode(fa.read())
|
||||
|
||||
payload = {'image_data': img_str}
|
||||
resp = requests.post(url, data=payload)
|
||||
|
||||
print(resp.json())
|
||||
```
|
||||
4. Output
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"0": {
|
||||
"rec_txt": "香港深圳抽血,",
|
||||
"dt_boxes": [
|
||||
[265, 18],
|
||||
[472, 231],
|
||||
[431, 271],
|
||||
[223, 59]
|
||||
],
|
||||
"score": "0.8175641223788261"
|
||||
},
|
||||
"1": {
|
||||
"rec_txt": "专业查性别",
|
||||
"dt_boxes": [
|
||||
[388, 15],
|
||||
[636, 257],
|
||||
[587, 307],
|
||||
[339, 65]
|
||||
],
|
||||
"score": "0.8293875356515249"
|
||||
},
|
||||
"2": {
|
||||
"rec_txt": "专业鉴定B超单",
|
||||
"dt_boxes": [
|
||||
[215, 84],
|
||||
[509, 413],
|
||||
[453, 463],
|
||||
[159, 134]
|
||||
],
|
||||
"score": "0.8626169338822365"
|
||||
},
|
||||
"3": {
|
||||
"rec_txt": "b超仪器查性别",
|
||||
"dt_boxes": [
|
||||
[128, 135],
|
||||
[430, 478],
|
||||
[366, 534],
|
||||
[64, 192]
|
||||
],
|
||||
"score": "0.8449362441897392"
|
||||
},
|
||||
"4": {
|
||||
"rec_txt": "加微信eee",
|
||||
"dt_boxes": [
|
||||
[58, 189],
|
||||
[268, 450],
|
||||
[209, 498],
|
||||
[0, 236]
|
||||
],
|
||||
"score": "0.8176911813872201"
|
||||
},
|
||||
"5": {
|
||||
"rec_txt": "可邮寄",
|
||||
"dt_boxes": [
|
||||
[493, 261],
|
||||
[617, 384],
|
||||
[577, 423],
|
||||
[454, 300]
|
||||
],
|
||||
"score": "0.7494261413812637"
|
||||
}
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
### See details for [RapidOCR](https://github.com/RapidAI/RapidOCR/tree/main/ocrweb).
|
||||
Reference in new issue
Block a user