paddleocr 在docker環境下部署

壶小旭發表於2024-03-15

paddleocr 在docker環境下部署

  1. 第一步 檢視cuda的版本nvcc -V,我的是11.2;nvidia-smi 對應的cuda version是11.6,所以採用了registry.baidubce.com/paddlepaddle/paddle:latest-dev-cuda11.6-cudnn8.4-trt8.4-gcc82作為基礎映象


  2. Docker映象源選擇,DockerHub地址

  3. Dockerfile配置

    FROM registry.baidubce.com/paddlepaddle/paddle:latest-dev-cuda11.6-cudnn8.4-trt8.4-gcc82
    
    # 設定工作目錄
    WORKDIR /paddle
    ENV TZ=Asia/Shanghai \
        DEBIAN_FRONTEND=noninteractive
    #將原生代碼同步到映象的/paddle目錄下
    copy . /paddle
    #安裝python依賴環境
    RUN python -m pip install paddlepaddle-gpu==0.0.0.post112 -f https://www.paddlepaddle.org.cn/whl/linux/gpu/develop.html
    RUN pip install fastapi -i https://pypi.tuna.tsinghua.edu.cn/simple
    RUN pip install uvicorn -i https://pypi.tuna.tsinghua.edu.cn/simple
    RUN pip install python-multipart -i https://pypi.tuna.tsinghua.edu.cn/simple
    RUN pip install paddleocr -i https://pypi.tuna.tsinghua.edu.cn/simple
    
    CMD ["python", "/paddle/main_ocr.py"]
    
  4. 核心程式碼

    ## ocr_paddle.py
    from paddleocr import PaddleOCR, draw_ocr
    
    # Paddleocr目前支援的多語言語種可以透過修改lang引數進行切換
    # 例如`ch`, `en`, `fr`, `german`, `korean`, `japan`
    def ocr(file_name):
        ocr = PaddleOCR(use_angle_cls=True, lang="ch")  # need to run only once to download and load model into memory
        img_path = './uploads/'+file_name
        result = ocr.ocr(img_path, cls=True)
    
        final_txt=[]
        for idx in range(len(result)):
            res = result[idx]
            for line in res:
                final_txt.append(line[1][0])
        print("\n".join(final_txt))
        return "\n".join(final_txt)
    
    
    #main_ocr.py
    from fastapi import FastAPI, UploadFile, File
    import codecs
    import sys
    from fastapi.middleware.cors import CORSMiddleware
    from fastapi.responses import JSONResponse
    from ocr_paddle import ocr
    
    from PIL import Image
    import io
    
    app = FastAPI()
    app.add_middleware(
            CORSMiddleware,
            # 允許跨域的源列表,例如 ["http://www.example.org"] 等等,["*"] 表示允許任何源
            allow_origins=["*"],
            # 跨域請求是否支援 cookie,預設是 False,如果為 True,allow_origins 必須為具體的源,不可以是 ["*"]
            allow_credentials=False,
            # 允許跨域請求的 HTTP 方法列表,預設是 ["GET"]
            allow_methods=["*"],
            # 允許跨域請求的 HTTP 請求頭列表,預設是 [],可以使用 ["*"] 表示允許所有的請求頭
            # 當然 Accept、Accept-Language、Content-Language 以及 Content-Type 總之被允許的
            allow_headers=["*"],
            # 可以被瀏覽器訪問的響應頭, 預設是 [],一般很少指定
            # expose_headers=["*"]
            # 設定瀏覽器快取 CORS 響應的最長時間,單位是秒。預設為 600,一般也很少指定
            # max_age=1000
    )
    
    @app.post("/image2text/")
    async def image2text(file: UploadFile):
        # print(file.filename)
        try:
            # 檢查檔案是否上傳成功
            if file.content_type.startswith('image'):
                # 指定本地檔案儲存路徑
                with open(f"./uploads/{file.filename}", "wb") as f:
                    f.write(file.file.read())
                res=ocr(file.filename)
                
                return JSONResponse(content={"message": res}, status_code=200)
            else:
                return JSONResponse(content={"message": "Invalid file format. Only images are allowed."}, status_code=400)
        except Exception as e:
            return JSONResponse(content={"message": str(e)}, status_code=500)
    @app.post("/image2text2/")
    async def image2text2(image_bytes):
        print(image_bytes)
        status=0
        res=""
        try:
            image_stream = io.BytesIO(image_bytes)
            # print(file.filename)
            # 指定影像檔案的本地儲存路徑
            save_path = "./uploads/image.png"
            image = Image.open(image_stream)
    
            # 儲存影像到本地檔案
            image.save(save_path)
            status=200
            res=ocr("image.png")
        except Exception as e:
            status=500
        finally:
            # 關閉影像物件和二進位制流
            image.close()
            image_stream.close()
        return JSONResponse(content={"message": res}, status_code=status)
      
    # 在最下面加上 這一句 代替命令列啟動
    if __name__ == "__main__":
        import uvicorn
        uvicorn.run(app='main_ocr:app', host="0.0.0.0", port=8888, reload=True)
    
  5. 製作映象,build

    docker build -t ppocr:1.0 .
    
  6. 執行

     nvidia-docker run --name ppocr --shm-size=64G --network=host -it ppocr:1.0
    

相關文章