halkar / Tesseract.Xamarin

Tesseract OCR wrapper for Xamarin
MIT License
121 stars 40 forks source link

Having an issue with Byte[] input. #4

Closed dazinator closed 9 years ago

dazinator commented 9 years ago

So my big idea is to try and capture frames from camera preview, and do OCR on the fly!

However when I pass in the byte array for the current frame:

                await _Api.SetImage(imageBytes);

It essentially hangs and doesn't return.

Does this Byte array need to be encoded before I pass it in? Any ideas on why it might hang?

My code is doing this:


            _Camera = Android.Hardware.Camera.Open();          
            _Camera.SetPreviewCallback(this); // the call back method is OnPreviewFrame, below.
            _Camera.StartPreview();      
...      
        public void OnPreviewFrame(byte[] data, Android.Hardware.Camera camera)
        {
            // data is the bytes representing the current frame.
            var text = GetText(data).Result;
        }
        public async Task<string> GetText(byte[] imageBytes)
        {
            // todo: call web api, send image, and get back text.
            try
            {
                EnsureInitialised();
                await _Api.SetImage(imageBytes); /// this hangs
                // await api.SetImage(imagePath);
                string text = _Api.Text;
                return text;          
            }
            catch (Exception ex)
            {
                throw;
            }     
        }
    }

Any help or advice is much appreciated.

dazinator commented 9 years ago

I've asked this on stackoverflow as well: http://stackoverflow.com/questions/30920675/camera-preview-and-ocr?noredirect=1#comment49878574_30920675

halkar commented 9 years ago

There is an answer there. Being honest I didn't play much with byte array format as I use XLabs MediaService to get images from camera and it returns stream or file name. Will try using camera directly today.

dazinator commented 9 years ago

So apparently the byte[] data coming from the camera preview is YuvImage format. So I am now doing this to convert it to JPEG:

  public byte[] TranscodeImageBytesToJpeg(byte[] imageBytes, Android.Hardware.Camera camera)
        {
            var parameters = camera.GetParameters();
            int width = parameters.PreviewSize.Width;
            int height = parameters.PreviewSize.Height;          

            Rect rect = new Rect(0, 0, width, height);
            YuvImage yuvimage = new YuvImage(imageBytes, ImageFormatType.Nv21, width, height, null);

            using (MemoryStream memStream = new MemoryStream())
            {
                if (yuvimage.CompressToJpeg(rect, 100, memStream))
                {
                    return memStream.ToArray();
                }
                throw new InvalidOperationException("Could not compress camera to Jpeg");
            }

        }  

Now interestingly, If i pass this new byte[] directly to SetImage() - it still hangs. However, if i write the same data to a file on disk, and then call the SetImage() with the filepath overload - it runs ok. It gives me back gibberish text but guessing that's just the quality of my image that I'm passing in (not very good). This does seem to suggest there may be something wrong with the byte array overload

halkar commented 9 years ago

Could you please give me an example of your image? I'll have a look. I'll check what's wrong with SetImage(byte[]).

halkar commented 9 years ago

Thank you!

halkar commented 9 years ago

Oh, this text is definitely not recognisable :)

dazinator commented 9 years ago

haha yeah - definately not!

dazinator commented 9 years ago

Did you get the image file ok?

halkar commented 9 years ago

Yes.

dazinator commented 9 years ago

Cool beans :)