You may want to move the process created by python (mainly deep learning system such as tensorflow, pytorch) from GUI and display the result. It may be possible to use PyQt, but since there are many people around me who can handle C #, I thought it would be nice to be able to incorporate it, and I found out. The following ancestors have summarized how to use it, so I would like to write an article on the procedure up to making an application using the model actually made with tensorflow based on it. ** This article is about preparation and operation check. ** ** (** As of January 2021, the source code of pythonnet itself has been updated, so the latest procedure will be posted **) I'm a C # beginner, so please understand that there may be some mistakes ...
Reference (1): Call python from .NET (C #) Reference (2): I tried to execute Python code from .Net using Pythonnet (Hallo World edition)
** Development environment **
visualstudio2019 community Version 16.7.7
NuGet Package Manager 5.7.0
Anaconda Navigator 1.9.12
** C # environment **
.NET Framework 4.7.2
** python environment **
Python 3.7.6
tensorflow 2.3.0
numpy 1.18.5
** Prerequisite knowledge ** ・ People who can build environment with pip etc. with python and can code ・ People who understand C # a little
If you use python3.7, you can easily install it using Nuget (as of 2021/01/10) ⇒ 2. Please skip until you call and use
I referred to the following article. If you have an old source code of pythonnet, please refer to the following article.
Reference: Call python from .NET (C #) Reference: I tried running Python code from .Net using Pythonnet (Hallo World)
** This section describes how to build with the latest source code as of January 10, 2021. ** **
Clone Latest Code from pythonnet's github repository and open pythonnet.sln
Open the project properties of project Python.Runtime
and manually enter the compile symbol.
If you want to use python3.8, enter PYTHON38; WINDOWS
. For 3.7, change PYTHON38 to 37.
By the way, if you look at the contents of runtime.cs
, you can see how to set the compile symbol.
** If you do not enter WINDOWS
, the content of the dll will be python38, and when you actually use it, you will go looking for python3.8, so you will not be able to load the dll properly. ** **
Right-click in Python.Runtime in Solution Explorer and select Build
If the build passes successfully, the root folder
src\runtime\bin\Debug\netstandard2.0
To
Python.Runtime.dll
I think that has been generated.
Reference: Call python from .NET (C #) I'm just imitating how to write the code of the ancestor, but I will try to make an application that puts a label on the form, displays the version of numpy, and makes a simple calculation with numpy.
Make sure the platform is x64.
Browse to the DLL file you just created
Make sure Python.Runtime is added.
Please make a form like this.
Reference: Call python from .NET (C #) All you have to do is refer to the code of the predecessor.
Form.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
using Python.Runtime;
namespace pythonnet_numpy_version
{
public partial class Form1 : Form
{
/// <summary>
///Variables for sharing and using the python library
/// </summary>
public dynamic np;
public Form1()
{
InitializeComponent();
}
/// <summary>
///Add the specified directory to the process's environment variable PATH(Pass through)。
/// </summary>
/// <param name="paths">The directory to add to your PATH.</param>
public static void AddEnvPath(params string[] paths)
{
var envPaths = Environment.GetEnvironmentVariable("PATH").Split(Path.PathSeparator).ToList();
foreach (var path in paths)
{
if (path.Length > 0 && !envPaths.Contains(path))
{
envPaths.Insert(0, path);
}
}
Environment.SetEnvironmentVariable("PATH", string.Join(Path.PathSeparator.ToString(), envPaths), EnvironmentVariableTarget.Process);
}
//Process when the form is called
private void Form1_Load(object sender, EventArgs e)
{
// *-------------------------------------------------------*
// *python environment settings
// *-------------------------------------------------------*
//Pass the path to the python environment
// TODO:Correct the path according to the environment
var PYTHON_HOME = Environment.ExpandEnvironmentVariables(@@"%userprofile%\Anaconda3\envs\tensorflow-2-3-0");
//Allows pythonnet to find python body DLLs and dependent DLLs
AddEnvPath(
PYTHON_HOME,
Path.Combine(PYTHON_HOME, @"Library\bin")
);
//PYTHON in python environment_HOME(Location of standard python library)The set
PythonEngine.PythonHome = PYTHON_HOME;
//Process python = Display numpy definition and version on label
using (Py.GIL())
{
//numpy import
np = Py.Import("numpy");
//Store numpy version in variable
dynamic np_version = np.__version__;
//Make it a string type, concatenate it with a character string, and display it on the label
labelNumpyVersion.Text = "numpy version:" + np_version.ToString();
}
}
//Click the button to do a simple calculation using the numpy method and display it on the label
private void buttonCalc_Click(object sender, EventArgs e)
{
//Do a simple calculation and store it in a variable
dynamic result = np.cos(np.pi / 3);
//Even if you do not ToString, if you attach it to a character string, it will change the type without permission
labelResult.Text = "np.cos(np.pi / 3)=" + result;
}
}
}
Basically, just write according to the article you are referring to, but one point is that in the case of a form application, you want to use numpy with various controls, so you need to define the member variables to be stored when importing. The summary is as follows. (Depending on how you use it, there may be an appropriate setting for the access modifier ... I decided to make it public for the time being)
Definition of member variables
hogehoge.cs
public partial class Form1 : Form
{
/// <summary>
///Variables for sharing and using the python library
/// </summary>
public dynamic np;
Definition of numpy
hogehoge.cs
//Process python = Display numpy definition and version on label
using (Py.GIL())
{
//numpy import
np = Py.Import("numpy");
Use of numpy
hogehoge.cs
//Do a simple calculation and store it in a variable
dynamic result = np.cos(np.pi / 3);
I started programming from python, and after studying C #, it took me about half a day to build pythonnet in a few months, which seemed to break my heart, but I was relieved to be able to shape it.
Next, I will write an article to make an application that reads an image on the C # side using tensorflow and opencv and displays the result inferred by the segmentation model with python in the picturebox of C #.
that's all. If you have any questions or concerns, please leave a comment.
Recommended Posts