tleyden / open-ocr

Run your own OCR-as-a-Service using Tesseract and Docker
Apache License 2.0
1.33k stars 223 forks source link

Base64 string #88

Closed speedfl closed 7 years ago

speedfl commented 7 years ago

Hello.

First thanks a lot for your job. I was trying to figure out how to implement an ocr on my server and you gave me the key. I would like to know if you can handle base64 encoded image ? Thanks a lot and continue like this

tleyden commented 7 years ago

not out of the box, but I would definitely take a PR

will multipart/related not work, or are you just trying to avoid the pain of dealing with it? (which I totally get)

speedfl commented 7 years ago

I am trying to avoid it. To be honnest I was using vision api of google and they were taking base64 and it was reallt easy from the client to their api (everything in base64) I will try to make it work on my server this weekend. And if yes I will propose a PR

tleyden commented 7 years ago

I saw that google was using base64 and then wished I'd taken that approach too

I think the ocr endpoint should be able to take either:

var body = {
  'img_url': 'http://bit.ly/ocrimage',
  'engine': 'tesseract',
  ...
};

or

var body = {
  'img_base64': '87DFSFD...',
  'engine': 'tesseract',
   ...
};

and then this code:

        tmpFileName, err := func() (string, error) {
        if ocrRequest.ImgUrl != "" {
            return t.tmpFileFromImageUrl(ocrRequest.ImgUrl)
        } else {
            return t.tmpFileFromImageBytes(ocrRequest.ImgBytes)
        }

    }()

would change to:

               tmpFileName, err := func() (string, error) {
        if ocrRequest.ImgUrl != "" {
            return t.tmpFileFromImageUrl(ocrRequest.ImgUrl)
        } else if ocrRequest.ImageBase64 != "" {
            return t.tmpFileFromImageBase64(ocrRequest.ImgBase64)
                }  else {
            return t.tmpFileFromImageBytes(ocrRequest.ImgBytes)
        }

    }()
speedfl commented 7 years ago

I think we should not remove img_uri to be backward compatible Maybe add both and take as preffered base64 Anyway i will have a look this weekend

EDIT: Sorry I did not read in depth. This looks perfect. I will check

tleyden commented 7 years ago

I think it can be either/or, and if both are provided, then yeah it's fine to pick ImageBase64 first (and emit a warning in the logs that ImgUrl is being ignored)

speedfl commented 7 years ago

Code for deconding and tested in local (decoding part + using ioutil like your saveBytesToFileName):

import base64 "encoding/base64"
...
...
func (t TesseractEngine) tmpFileFromImageBase64(base64Image string) (string, error) {

    tmpFileName, err := createTempFileName()
    if err != nil {
        return "", err
    }

    // decoding into bytes the base64 string
    decoded, decodeError := base64.StdEncoding.DecodeString(data)

    if decodeError != nil {
        return "", err
    }

    err = saveBytesToFileName(decoded, tmpFileName)
    if err != nil {
        return "", err
    }

    return tmpFileName, nil

}

I will test it tomorrow on real conditions :) If working I will create the PR

Have a nice evening

speedfl commented 7 years ago

Hello I did my code. However I am not able to test it. I put in the go file some logg just to see if they are taken into account but nothing (no Hello world printed)

Maybe I miss something (the go files are not compiled?)

tleyden commented 7 years ago

How are you trying to run/test? If you use the docker container, you would need to rebuild docker image first

speedfl commented 7 years ago

I try to run. simple doing the docker-compose up but not working :/

I changed as well in the:

cli-httpd/main.go
cli-preprocessor/main.go
cli-worker/main.go

To use github.com/speedfl/open-ocr but not working... However I did the code change in a feature branch (not on master)

How do I rebuild the wall project with what I have on local?

speedfl commented 7 years ago

I think the problem come from the docker file https://hub.docker.com/r/tleyden5iwx/open-ocr/~/dockerfile/

It takes your code.

However I am a newcomer on docker. So I created my account and now try to figureout how to set up. If you can maybe explain me a bit because I am totally lost :)

speedfl commented 7 years ago

It workss!!!!!

I created a dockerfile locally by copy pasting your https://hub.docker.com/r/tleyden5iwx/open-ocr/~/dockerfile/

I change to use my code. build the docker file and referenced my image in the docker compose

However it works only with "inplace_decode" : true,

I thinks the issue come from here:

https://github.com/tleyden/open-ocr/blob/master/ocr_http_handler.go#L77

We try to decode image without processing the request. I will try to figure out :)

EDIT: Fixed as well :)

Regards

speedfl commented 7 years ago

Now remains test on the stroke width transform.

As I saw the preprocessor is using only image bytes so I need as well to add a check on the base64.

https://github.com/tleyden/open-ocr/blob/master/preprocessor_rpc_worker.go#L199

Can you explain me the sequence of action. If stroke width transform is done before it means that the updated information is in the ImgBytes and no more in the base64

tleyden commented 7 years ago

We try to decode image without processing the request. I will try to figure out :) EDIT: Fixed as well :)

Cool!

tleyden commented 7 years ago

Can you explain me the sequence of action. If stroke width transform is done before it means that the updated information is in the ImgBytes and no more in the base64

In func (c *OcrRpcClient) DecodeImage(ocrRequest OcrRequest) (OcrResult, error)

you'll need to decode the base64 string to a []byte somewhere.

Change:

    if ocrRequest.ImgBytes == nil {
        // if we already have image bytes, ignore image url
        err = ocrRequest.downloadImgUrl()
        if err != nil {
            logg.LogTo("OCR_CLIENT", "Error downloading img url: %v", err)
            return OcrResult{}, err
        }
    }

to something like this:

    if ocrRequest.ImgBytes == nil {

                if ocrRequest.hasBase64() {
           err = ocrRequest.decodeBase64()
           if err != nil {
            logg.LogTo("OCR_CLIENT", "Error decoding base64: %v", err)
            return OcrResult{}, err
           }
                } else {
           // if we already have image bytes, ignore image url
           err = ocrRequest.downloadImgUrl()
           if err != nil {
            logg.LogTo("OCR_CLIENT", "Error downloading img url: %v", err)
            return OcrResult{}, err
           }
                } 

    }
tleyden commented 7 years ago

The PR got merged, so closing out this ticket