人生苦短python续命,听闻各大国产图像处理程序支持python ;而我用的海康VM是支持C#脚本的;但是原生并不支持python做图像处理;
于是心生一计; C#通过pythonnet嵌入并调用python不就可以??? 只需要实现对应图像类型转换;
而前面已经讲过 python 里面 使用.net 的图像处理方法; 函数前面已经用python写好了可以直接由C#调用并直接返回 C#支持的 Bitmap 图像 (双向的) ;当然这个py写的可以直接在py里面使用;由于pythonnet是C#和python的桥梁 那么 Bitmap 和 numpy格式的图像是 两者都支持的;
但是这样有个缺点就是python和C#都要安装pythonnet 而只安装C#端pythonnet是不行的;
假设在C#端导入并调用py的模块 bitmap_to_mat; mat_to_bitmap;这两个函数 那么他是依赖C#端和py端的pythonnet的;我并不想说的太绕口 ;总之 C# py 都要装pythonnet
直接先python模块:这个模块完全是为了给C#调用:
python
import os,sys,time,copy,socket,_thread,threading
import cv2,qrcode
import numpy as np
from PIL import Image
#region 初始化CLR环境
import clr,System
from System.IO import MemoryStream
clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")
import System.Drawing
from System.Drawing import Bitmap, Imaging
import System.Drawing.Imaging
import System.Windows.Forms as Forms
# 这部分是 .NET的东西 #region# 初始化CLR环境
def getnowtime(): return f"{time.strftime('%Y-%m-%d_%H_%M_%S')}"
def bitmap_to_mat(bitmap,flag=False):
r"""
System.Drawing.Bitmap对象
转换为
opencv 图像
"""
stream = MemoryStream()
bitmap.Save(stream, bitmap.RawFormat)
stream.Position = 0
bitmap_data = np.frombuffer(stream.ToArray(), dtype=np.uint8)
stream.Close() #一定要
mat = cv2.imdecode(bitmap_data, cv2.IMREAD_COLOR)
if flag :
gray_mat = cv2.cvtColor(mat, cv2.COLOR_BGR2GRAY)
return gray_mat
bgr_mat = mat #imdecode #已经是BGR 所以 不需要#bgr_mat = cv2.cvtColor(mat, cv2.COLOR_RGB2BGR)
return bgr_mat
def mat_to_bitmap(cv_image):
r"""
opencv 图像
转换为
System.Drawing.Bitmap对象
"""
cv_image_rgb = cv_image#imencode imdecode 已经是BGR 所以 不需要cv2.COLOR_BGR2RGB
h, w, c = cv_image_rgb.shape# 创建一个与图像数据相匹配的numpy数组
numpy_array = np.array(cv_image_rgb, dtype=np.uint8).reshape((h, w, c))
stream = MemoryStream()# 创建一个MemoryStream对象并将numpy数组写入
cv2.imencode('.png', numpy_array)[1].tobytes()
stream.Write(cv2.imencode('.png', numpy_array)[1].tobytes(), 0, len(cv2.imencode('.png', numpy_array)[1].tobytes()))
stream.Position = 0
bitmap = Bitmap.FromStream(stream)# 使用.NET的System.Drawing命名空间中的Bitmap类从MemoryStream创建Bitmap对象
stream.Close()# 清理资源
return bitmap # 现在有一个System.Drawing.Bitmap对象,可以在.NET环境中使用
def imageprocess(mat):
r"""
1 水平翻转
0 垂直翻转
-1 水平垂直翻转
"""
h_flip = cv2.flip(mat, 1)
v_flip = cv2.flip(mat, 0)
hv_flip = cv2.flip(mat, -1)
return h_flip #
好了 现在当他是一个DLL 或者包吧;
然后:调用它:
cs
using System.Net;
using System.Xml.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System;
using System.IO;
using Python.Runtime; // 这个是 nuget下载的,并不是python安装目录里那个dll
using SC = System.Console;
using System.Drawing;
using System.Drawing.Imaging;
using System.Diagnostics;
namespace cspy
{
internal class Program
{
static string pythonHomePath = @"C:\Users\Administrator\AppData\Local\Programs\Python\Python38";
// 这是我的python安装路径;
// 如果不想安装python 理论上可以将 python解释器连同依赖文件复制在C#工程文件跟目录
/**/
static string dllPath = pythonHomePath + @"\python38.dll";
static string[] py_paths =
{
"DLLs",
"Lib",
"Lib/site-packages",
"Lib/site-packages/win32" ,
"Lib/site-packages/win32/lib",
"Lib/site-packages/Pythonwin"
};
public static readonly string Semicolon = ";";
static string pySearchPath = pythonHomePath + Semicolon;
static void Main(string[] args)
{
foreach (string p in py_paths)
{
pySearchPath += pythonHomePath + "//" + p + Semicolon;
}
System.Environment.SetEnvironmentVariable("PYTHONNET_PYDLL", dllPath);
PythonEngine.PythonHome = pythonHomePath;
PythonEngine.PythonPath = pySearchPath;
PythonEngine.Initialize();
//Python.Runtime.dll
//netstandard.dll
//Microsoft.CSharp.dll
/* //"Python.Runtime.dll","netstandard.dll"","Microsoft.CSharp.dll"*/
// 初始化Python引擎
// 导入Python中的numpy和cv2库
dynamic np = Py.Import("numpy");
dynamic cv2 = Py.Import("cv2");
dynamic sys = Py.Import("sys");
sys.path.append("C:\\Users\\Administrator\\Desktop\\VM_00\\VM_脚本嵌入python处理图像");// 模块路径
dynamic pynModule = Py.Import("pyn"); //
dynamic CreateQR = pynModule.CreateQR();//
dynamic vision = Py.Import("vision_converte"); // 导入模块
// 图像处理在英文中通常被称为 "image processing"。
Bitmap bitmap = new Bitmap("lena.jpg");// 创建一个C#中的Bitmap对象
// 调用Python函数
dynamic mat = vision.bitmap_to_mat(bitmap, false); // 第二个参数根据需要设置
// 可以在这里进行进一步的图像处理 我脑子一片空白 演示一个翻转
dynamic matprocess = vision.imageprocess(mat); // python 里面进行翻转
Bitmap convertedBitmap = vision.mat_to_bitmap(matprocess);// 将py Mat对象转换回Bitmap
dynamic getnowtime = vision.getnowtime();
string strgetnowtime = getnowtime;
convertedBitmap.Save("converted_image"+ strgetnowtime + ".png", ImageFormat.Png); //图像返回给C# 我这里只保存 保存的是翻转的图;
convertedBitmap.Dispose(); // 释放Bitmap资源
PythonEngine.Shutdown();// 关闭Python引擎
// SC.WriteLine("____结束");SC.ReadKey();
//########### wait ############# //##################################################################################################
}//Main
}
}
注释已经很清楚了;
当然还有一些问题 看一眼就能发现