人生苦短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#调用:
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 = 0bitmap_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_matbgr_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_BGR2RGBh, 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 = 0bitmap = 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 或者包吧;
然后:调用它:
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对象转换回Bitmapdynamic 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}
}
注释已经很清楚了;
当然还有一些问题 看一眼就能发现