Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass Image object as a parameter from C# to Python

I want to pass an image object from my c# project to my python script however from my understanding whatever there is in the arguments it is considered as string and also when I try type(passedImage) in python it identifies it as a string even if I try to put a number instead of the image variable.

ProcessStartInfo start = new ProcessStartInfo();
            start.FileName = @"C:\Python\Python36\python.exe";
            start.Arguments = string.Format("{0} {1}", @"C:\OCRonImage2.py", image );
            start.UseShellExecute = false;
            start.RedirectStandardOutput = true;
            start.CreateNoWindow = true;
            using (Process process = Process.Start(start))
            {

            }
like image 367
cylegend Avatar asked Dec 13 '19 16:12

cylegend


People also ask

How do you pass an object as an argument in C++?

In C++ we can pass class’s objects as arguments and also return them from a function the same way we pass and return other variables. No special keyword or header file is required to do so. To pass an object as an argument we write the object name as the argument while calling the function the same way we do it for other variables.

How do you pass an object as an argument in Python?

Passing an Object as argument. To pass an object as an argument we write the object name as the argument while calling the function the same way we do it for other variables. Syntax: function_name(object_name); Example: In this Example there is a class which has an integer variable ‘a’ and a function ‘add’ which takes an object as argument.

How do you pass data to a method in Java?

We can pass the data to the methods in form of arguments and an object is an instance of a class that is created dynamically. The basic data types can be passed as arguments to the C# methods in the same way the object can also be passed as an argument to a method.

How to return an object from a function in C++?

In C++ we can pass class’s objects as arguments and also return them from a function the same way we pass and return other variables. No special keyword or header file is required to do so.


2 Answers

When executing OCRonImage2.py manually, is it an image file location that you would pass as an argument? I would be surprise if you would pass in a stream from the command line. It is no surprise that attempting to put the entire image's bytes into an argument would create a string too long. But with the error you reported, I would also believe that the python script was expecting a file path to the image. However, if you look at that python code, I wouldn't be surprised if you find it using the filepath argument to open the file, probably using Image.open(filepath,mode=r). Mode is optional, r is the default.

You are in luck however, Image.open also takes a stream. If you are willing to modify the python code there are two options:

  1. Try converting the argument to a stream object, since the argument is a string maybe use io.StringIO()
  2. Use input() instead of the argument passed, then you could redirect the input of the process and stream the file into your python.
    ProcessStartInfo start = new ProcessStartInfo();
    start.FileName = @"C:\Python\Python36\python.exe";
    start.Arguments = string.Format("{0}", @"C:\OCRonImage2.py");
    start.UseShellExecute = false;
    start.RedirectStandardOutput = true;
    start.RedirectStandardInput = true;
    start.CreateNoWindow = true;
    using (Process process = Process.Start(start))
    {
        StreamWriter streamWriter = process.StandardInput;
        streamWriter.Write({imageString});
        // ...
    }

Be sure the way you encode imageString the same as the decoding is performed in the python script.

Hopefully one of these solutions will work for you.

like image 140
Larry Dukek Avatar answered Sep 18 '22 00:09

Larry Dukek


As I work with the Anaconda distribution of Python, in my tests on an isolated conda environment, the OCR is successful with pytesseract through a Python script, on a test image.

Prerequisites to test:

  • install Anaconda and create an env called py3.7.4: conda create --name py3.7.4
  • activate the env with conda activate py3.7.4
  • install pytesseract with conda install -c conda-forge pytesseract
  • create a folder called Test and place a jpg file called ocr.jpg with the following sample image: enter image description here
  • in the same Test folder also place a Python script called ocr_test.py with the following code:

    import pytesseract
    from PIL import Image
    import argparse
    
    parser = argparse.ArgumentParser(
        description='perform OCR on image')
    parser.add_argument("--path", "-p", help="path for image")
    args = parser.parse_args()
    print(pytesseract.image_to_string(Image.open(args.path)))
    print("done")
    

The above snippet accepts the image path as a command line argument. The --path flag must be specified in order to pass the image path as an arg.

Now, in the C# code snippet below, we will:

  • launch the cmd shell
  • navigate to the workingDirectory Test folder by specifying the WorkingDirectory arg for the process.start() method.
  • activate Anaconda with the anaconda.bat file(replace the file path as per its location on your computer)
  • activate the above conda environment
  • call the Python script passing the imageFileName as an arg.

C# snippet:

using System.Diagnostics;
using System.Threading;


namespace PyTest
{
    class Program
    {

        static void Main(string[] args)
        {
            string workingDirectory = @"C:\Test";
            string imageFileName = "ocr.JPG";

            var process = new Process
            {                
                StartInfo = new ProcessStartInfo
                {
                    FileName = "cmd.exe",
                    RedirectStandardInput = true,
                    UseShellExecute = false,
                    RedirectStandardOutput = false,
                    WorkingDirectory = workingDirectory
                }

            };
            process.Start();


            using (var sw = process.StandardInput)
            {
                if (sw.BaseStream.CanWrite)
                {
                    // Vital to activate Anaconda
                    sw.WriteLine(@"C:\Users\xxxxxxx\Anaconda3\Scripts\activate.bat");
                    Thread.Sleep(500);
                    // Activate your environment
                    sw.WriteLine("conda activate py3.7.4");
                    Thread.Sleep(500);
                    sw.WriteLine($"python ocr_test.py --path {imageFileName}");
                    Thread.Sleep(50000);
                }                  

            }           
        }
    }   
    }

If you have followed the above steps, you should receive the following output on executing the C# snippet in Visual Studio:

Output:

Microsoft Windows [Version 10.0.18362.535]
(c) 2019 Microsoft Corporation. All rights reserved.

C:\xxxxxxx\Projects\Scripts>C:\Users\xxxxx\Anaconda3\Scripts\activate.bat

(base) C:\xxxxxx\Projects\Scripts>conda activate py3.7.4

(py3.7.4) C:\xxxxxxx\Projects\Scripts>python ocr_test.py --path ocr.JPG
Introduction

This is a test to see accuracy of Tesseract OCR
Test 1

Test 2
done

Note: I am unable to test with a standalone Python distro but I believe it should work just fine with that too. The key is to pass the image file path as an argument to the Python script too. That way, the image file path passed as argument from C# is treated similarly by Python too. Also, using Image.open() does the following(from the docs):

Opens and identifies the given image file. This is a lazy operation; this function identifies the file, but the file remains open and the actual image data is not read from the file until you try to process the data

like image 28
amanb Avatar answered Sep 21 '22 00:09

amanb