PaddleOCR service deployment - and calling via Java

The previous article talked about the simple use of PaddleOCR, but the ultimate goal must be to deploy it as a service for us to call. Here is an introduction to its service deployment method

Choose a deployment method

The official recommendations are as follows:
Python reasoning
C++ reasoning
Serving service deployment (Python/C++)
Paddle-Lite end-to-end deployment (ARM CPU/OpenCL ARM GPU)
Paddle.js deployment

The advantages and disadvantages of each method are as follows

Since I am doing Java development and don't know Python, I use Serving service deployment
PaddleOCR provides 2 service deployment methods:

based on PaddleHub Serving deployment;
based on PaddleServing deployment of

I chose to deploy through PaddleHub Serving

Install Hub Serving

prepare the environment

pip install paddlehub -i

Check it out after installation

Download the inference model

Create a new 'inference' folder under PaddleOCR, prepare the inference model and put it in the 'inference' folder, the default is the ultra-lightweight model of v1.1

The default model path is:
Detection model: ./inference/ch_ppocr_mobile_v1.1_det_infer/
Recognition model: ./inference/ch_ppocr_mobile_v1.1_rec_infer/
Orientation classifier: ./inference/ch_ppocr_mobile_v1.1_cls_infer/
The model path can be viewed and modified in More models can be downloaded from the model library provided by PaddleOCR, or replaced with models that have been trained and converted by themselves.

Install the service module

#In the Linux environment, the installation example is as follows:
# Install the detection service module:  
hub install deploy/hubserving/ocr_det/

# Or, install the recognition service module:  
hub install deploy/hubserving/ocr_rec/

# Or, install the Detect+Identify tandem service module:  
hub install deploy/hubserving/ocr_system/
#In the Windows environment (the folder separator is \), the installation example is as follows:
# Install the detection service module:  
hub install deploy\hubserving\ocr_det\

# Or, install the recognition service module:  
hub install deploy\hubserving\ocr_rec\

# Or, install the Detect+Identify tandem service module:
hub install deploy\hubserving\ocr_system\

It is best to install all these modules here, otherwise an error will be reported when starting

start service

There are two ways to start, one is to start globally, and the other is to start by specifying the path

#global start
hub serving start -m ocr_system

I use the specified path to start here, and I need to switch to the hubserving directory through the command

hub serving start -c deploy\hubserving\ocr_system\config.json

For other parameters of startup, refer to the official documentation

**Note:** If the startup error xxx path cannot be found, go to the files of ocr_system, ocr_det, and ocr_rec under PaddleOCR\deploy\hubserving, and replace all model_dir
Replace it with an absolute path that conforms to the win format;

This completes the deployment of a service API, using the default port number 8868.
Access example:
python tools/ --server_url= --image_dir=img/22.jpg
Output result:

Java call

We can call the service through Java code, the code is as follows:

 * @author: fueen
 * @createTime: 2022/11/28 10:01
public class PaddleOCRController {

    public String fileUpload(@RequestParam("file") MultipartFile file, HttpServletRequest req, Model model){
        try {
            //Receive uploaded files
            //Receiving uploaded files
            String fileName = System.currentTimeMillis()+file.getOriginalFilename();
            String destFileName=req.getServletContext().getRealPath("")+"uploaded"+ File.separator+fileName;
            File destFile = new File(destFileName);
            //Pass the address of the uploaded file to the front-end template engine
            //The address of the uploaded file is passed in to the front-end template engine
            //Start preparing to request API
            //Start preparing the request API
            //Create request header
            //Create request header
            HttpHeaders headers = new HttpHeaders();
            //Set request header format
            //Set the request header format
            //Build request parameters
            //Build request parameters
            MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
            //Read static resource files
            //Read the static resource file
            InputStream imagePath = new FileInputStream(destFile);
            //Add the request parameter images, and pass in the Base64-encoded image
            //Add the request parameter Images and pass in the Base64 encoded image
            map.add("images", ImageToBase64(imagePath));
            //build request
            //Build request
            HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
            RestTemplate restTemplate = new RestTemplate();
            //send request
            //Send the request
            Map json = restTemplate.postForEntity("", request, Map.class).getBody();
            //Parse Json return value
            //Parse the Json return value
            List<List<Map>> json1 = (List<List<Map>>) json.get("results");
            //Get the file directory to prepare for drawing later
            //Get the file directory to prepare for later drawing
            String tarImgPath = destFile.toString();
            File srcImgFile = new File(tarImgPath);
            //file stream to image
            //The file flows into images
            Image srcImg =;
            if (null == srcImg){
                return "nothing,Finish!";
            //Get the width of the image
            //Gets the width of the image
            int srcImgWidth = srcImg.getWidth(null);
            //Get the height of the picture
            //Get the height of the image
            int srcImgHeight = srcImg.getHeight(null);
            //Start the main process of drawing, create a drawing board, set the brush color, etc.
            //Start drawing main flow, create artboard, set brush color, etc
            BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bufImg.createGraphics();
            g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
            //Loop through all content
            //Loop through everything
            for (int i = 0; i < json1.get(0).size(); i++) {
                System.out.println("The current text is:" + json1.get(0).get(i).get("text"));
                System.out.println("The possible probabilities are:" + json1.get(0).get(i).get("confidence"));
                List<List<Integer>> json2 = (List<List<Integer>>) json1.get(0).get(i).get("text_region");
                System.out.println("text coordinates" + json2);
                int x = json2.get(0).get(0);
                int y = json2.get(0).get(1);
                int w = json2.get(1).get(0)-json2.get(0).get(0);
                int h = json2.get(2).get(1)-json2.get(0).get(1);
                g.drawRect(x,y,w,h);  //Draw the watermark Draw the watermark
            //Submit content to the front-end template engine
            //Submit the content to the front-end template engine
            // output image
            //The output image
            FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
            ImageIO.write(bufImg, "png", outImgStream);
            System.out.println("finished drawing");
        } catch (FileNotFoundException e) {
            return "upload failed," + e.getMessage();
        } catch (IOException e) {
            return "upload failed," + e.getMessage();
        return "OK";
    private String ImageToBase64(InputStream imgPath) {
        byte[] data = null;
        // read image byte array
        //Read the image byte array
        try {
            InputStream in = imgPath;
            data = new byte[in.available()];
        } catch (IOException e) {
        // Base64 encode byte array
        //Base64 encoding of byte array
        BASE64Encoder encoder = new BASE64Encoder();
        // Returns a Base64-encoded byte array string
        //Returns a Base64 encoded byte array string
        //System.out.println("Image conversion Base64:" + encoder.encode(Objects.requireNonNull(data)));
        return encoder.encode(Objects.requireNonNull(data));


Then run, call the interface through postman to test

console output

Finish! Later, you can make different processing modifications according to your own business needs.

Tags: Java image processing Deep Learning

Posted by discostudio on Sat, 03 Dec 2022 09:11:55 +1030