2

I am calling the Azure cognitive API for OCR text-recognization and I am passing 10-images at the same time simultaneously (as the code below only accepts one image at a time-- that is 10-independent requests in parallel) which is not efficient to me, regardin processing point of view, as I need to use extra modules i.e: Celery and multiprocessing.

So, is there a way to send all the 10-images in a single request and get the output at once then do post processing?

import time
from io import BytesIO

import cv2
import requests
from PIL import Image as PILImage
from PIL import Image
file_list = []

headers = {
    "Ocp-Apim-Subscription-Key": "<API-KEY>",
    'Content-Type': 'application/octet-stream'}

p = "symbol_sample.jpg"
print(p,"p")

def recognise_text(p):
    p = cv2.imread(p)
    cropped_image = PILImage.fromarray(p)
    buffer = BytesIO()
    cropped_image.save(buffer, format="JPEG")
    image_bytes = buffer.getvalue()
    try:
        response = requests.post(
            "https://centralindia.api.cognitive.microsoft.com/vision/v2.0/recognizeText?mode=Printed",
            headers=headers,
            data=image_bytes
        )
        header_link = str(response.headers['Operation-Location'])
        while (True):
            headers_get = {
                "Ocp-Apim-Subscription-Key": "<API-KEY>"",
                'Content-Type': 'application/json'
            }
            result = requests.get(
                url=header_link,
                headers=headers_get
            )
            response_r = result.json()
            if response_r["status"] == "Succeeded":
                return response_r
            else:
                time.sleep(4)
    except Exception as e:
        print(e)
        return ""

image1="symbol_sample.jpg"
o = recognise_text(image1)
print(o)

Any help would be really appreciated.

The Gr8 Adakron
  • 1,200
  • 1
  • 12
  • 15
  • Multiprocessing or multithreading is the solution for parallel processing.celery is also working on these type of concept only. If you don't want to use any dependency then you can write wrapper for your script. – Vardhman Patil Jun 17 '19 at 17:27
  • Another thing, I am reluctant to use it because I have used google-vision before and they have the batch concept for that API, so in google-vision, if I send 10-images in single-request-- it takes 4-6sec and at if I send an individual request-- single request take 2-3sec. – The Gr8 Adakron Jun 18 '19 at 03:45
  • One more thing, sending multiple requests parallelly brings the possibility of getting an error from Azure side-- then adding try-except-ladder: which I am doing right now and which again not very efficient. Where in batch its rare-- as my reflective perception by using google-vision-api. – The Gr8 Adakron Jun 18 '19 at 03:49
  • Basically, I am searching somehow to send batch-of-images. Not sure, if possible or not. If that feature is allocated by google-vision so I was hoping, same feature should be available in Azure-cognitive as well – The Gr8 Adakron Jun 18 '19 at 03:52
  • 1
    You are right. The solution which you are describing of Google vision is that they accept batch job. that show Google vision has multiprocessing at their end. So right now I am not aware that azure cognitive API provide any batch API call. – Vardhman Patil Jun 18 '19 at 09:51
  • Have you tried this: https://westus.dev.cognitive.microsoft.com/docs/services/5adf991815e1060e6355ad44/operations/2afb498089f74080d7ef85eb? – Thomas Jun 23 '19 at 22:15
  • Can you try this Batch Read File (https://centralindia.api.cognitive.microsoft.com/vision/v2.0/read/core/asyncBatchAnalyze) and Get Read Operation Result(https://centralindia.api.cognitive.microsoft.com/vision/v2.0/read/operations/{operationId}) in Computer Vision API v2.0 instead of the Recognize Text(https://centralindia.api.cognitive.microsoft.com/vision/v2.0/recognizeText). – Ram Jun 24 '19 at 10:49

1 Answers1

2

I guess you are looking for Batch Read File

public class BatchReadFileSample
    {
        public static async Task RunAsync(string endpoint, string key)
        {
            ComputerVisionClient computerVision = new ComputerVisionClient(new ApiKeyServiceClientCredentials(key))
            {
                Endpoint = endpoint
            };
            const int numberOfCharsInOperationId = 36;

            string localImagePath = @"Images\handwritten_text.jpg";  // See this repo's readme.md for info on how to get these images. Alternatively, you can just set the path to any appropriate image on your machine.
            string remoteImageUrl = "https://github.com/Azure-Samples/cognitive-services-sample-data-files/raw/master/ComputerVision/Images/printed_text.jpg";

            Console.WriteLine("Text being batch read ...");
            await BatchReadFileFromStreamAsync(computerVision, localImagePath, numberOfCharsInOperationId); 
            await BatchReadFileFromUrlAsync(computerVision, remoteImageUrl, numberOfCharsInOperationId);
        }

        // Read text from a remote image
        private static async Task BatchReadFileFromUrlAsync(ComputerVisionClient computerVision, string imageUrl, int numberOfCharsInOperationId)
        {
            if (!Uri.IsWellFormedUriString(imageUrl, UriKind.Absolute))
            {
                Console.WriteLine("\nInvalid remote image url:\n{0} \n", imageUrl);
                return;
            }

            // Start the async process to read the text
            BatchReadFileHeaders textHeaders = await computerVision.BatchReadFileAsync(imageUrl);
            await GetTextAsync(computerVision, textHeaders.OperationLocation, numberOfCharsInOperationId);
        }

        // Recognize text from a local image
        private static async Task BatchReadFileFromStreamAsync(ComputerVisionClient computerVision, string imagePath, int numberOfCharsInOperationId)
        {
            if (!File.Exists(imagePath))
            {
                Console.WriteLine("\nUnable to open or read local image path:\n{0} \n", imagePath);
                return;
            }

            using (Stream imageStream = File.OpenRead(imagePath))
            {
                // Start the async process to recognize the text
                BatchReadFileInStreamHeaders textHeaders = await computerVision.BatchReadFileInStreamAsync(imageStream);
                await GetTextAsync(computerVision, textHeaders.OperationLocation, numberOfCharsInOperationId);
            }
        }

Here is the Full Code

Sajeetharan
  • 216,225
  • 63
  • 350
  • 396