Vision Master的C#脚本与opencv联合编程

需要在VM的C#脚本设置string类型Out变量和float类型OutF变量,python的输出信息会在Out变量显示

csharp 复制代码
using System;
using System.IO;
using Script.Methods;
using System.Diagnostics;
using System.Net.Sockets;
using System.Text;
using System.Threading;

public partial class UserScript : ScriptMethods, IProcessMethods
{
    private PythonTcpRunner _pythonRunner;
    private Process _pythonProcess; // 保持进程引用
    public new int nErrorCode;
    private string pythonEdio=@"C:\T\python.exe";
    private string python= @"C:\T\清晰度评估.py";

    /// <summary>
    /// 初始化:启动Python进程并建立TCP连接
    /// </summary>
    public void Init()
    {
        // 初始化TCP运行器(使用本地8888端口)
        _pythonRunner = new PythonTcpRunner(
            pythonEdio,
            python,
            "127.0.0.1",
            8888
        );
        
        // 启动Python进程并等待TCP服务就绪
        string errorMsg;
        if (!_pythonRunner.StartProcess(out _pythonProcess, out errorMsg))
        {
            nErrorCode = -1;
            Out = "初始化Python进程失败: " + errorMsg;
        }
    }

    /// <summary>
    /// 执行流程:通过TCP发送请求
    /// </summary>
    public bool Process()
    {
        try
        {
            // 检查进程状态
            if (_pythonProcess == null || _pythonProcess.HasExited)
            {
                string errorMsg;
                if (!_pythonRunner.RestartProcess(out _pythonProcess, out errorMsg))
                {
                    nErrorCode = -1;
                    Out = "重启Python进程失败: " + errorMsg;
                    return false;
                }
            }

            // 通过TCP发送执行请求
            string errorMessage;
            string outputMessage;
            bool success = _pythonRunner.SendRequest("EXECUTE", out errorMessage, out outputMessage, 5000);

            Out = string.IsNullOrWhiteSpace(outputMessage) ? errorMessage : outputMessage;

            
            // 尝试将输出转换为float并赋值给OutF
            float result;
            if (!float.TryParse(outputMessage, out result))
            {
                // 如果转换失败,设置为NaN或其他默认值
                OutF = float.NaN;
            }
            else
            {
                OutF = result;
            }
            
            if (!success)
            {
                nErrorCode = -2;
                return false;
            }

            nErrorCode = 0;
            return true;
        }
        catch (Exception ex)
        {
            nErrorCode = -3;
            Out = string.Format("执行异常: {0}", ex.Message);
            return false;
        }
    }

    /// <summary>
    /// 释放资源:关闭进程和连接,使用override关键字重写基类方法
    /// </summary>
    public override void Dispose()
    {
        // 发送退出指令(修复输出参数错误,兼容.NET 4.6)
        if (_pythonRunner != null)
        {
            string dummyError;
            string dummyOutput;
            _pythonRunner.SendRequest("EXIT", out dummyError, out dummyOutput, 1000);
        }
        
        if (_pythonProcess != null && !_pythonProcess.HasExited)
        {
            try
            {
                _pythonProcess.WaitForExit(2000);
                if (!_pythonProcess.HasExited)
                    _pythonProcess.Kill();
            }
            catch { }
            finally
            {
                _pythonProcess.Dispose();
                _pythonProcess = null;
            }
        }
        
        // 关闭连接(兼容.NET 4.6)
        if (_pythonRunner != null)
        {
            _pythonRunner.Close();
        }
        
        // 调用基类的Dispose方法
        base.Dispose();
    }
}

/// <summary>
/// 基于TCP的Python运行器
/// </summary>
public class PythonTcpRunner
{
    private string _pythonPath;
    private string _scriptPath;
    private string _ip;
    private int _port;
    private TcpClient _client;

    public PythonTcpRunner(string pythonPath, string scriptPath, string ip, int port)
    {
        _pythonPath = pythonPath;
        _scriptPath = scriptPath;
        _ip = ip;
        _port = port;
    }

    /// <summary>
    /// 启动Python进程
    /// </summary>
    public bool StartProcess(out Process process, out string errorMessage)
    {
        errorMessage = string.Empty;
        process = null;

        try
        {
            var startInfo = new ProcessStartInfo
            {
                FileName = _pythonPath,
                Arguments = string.Format("\"{0}\" {1} {2}", _scriptPath, _ip, _port),
                UseShellExecute = false,
                CreateNoWindow = true,
                WorkingDirectory = Path.GetDirectoryName(_scriptPath)
            };

            process = Process.Start(startInfo);
            if (process == null)
            {
                errorMessage = "无法启动Python进程";
                return false;
            }

            // 等待TCP服务启动(最多等3秒)
            int retry = 0;
            while (retry < 30)
            {
                try
                {
                    _client = new TcpClient();
                    var result = _client.BeginConnect(_ip, _port, null, null);
                    var success = result.AsyncWaitHandle.WaitOne(100);
                    if (success)
                    {
                        _client.EndConnect(result);
                        return true;
                    }
                }
                catch { }
                
                retry++;
                Thread.Sleep(100);
            }

            errorMessage = "Python TCP服务启动超时";
            process.Kill();
            return false;
        }
        catch (Exception ex)
        {
            errorMessage = ex.Message;
            return false;
        }
    }

    /// <summary>
    /// 重启进程
    /// </summary>
    public bool RestartProcess(out Process process, out string errorMessage)
    {
        Close();
        return StartProcess(out process, out errorMessage);
    }

    /// <summary>
    /// 发送TCP请求
    /// </summary>
    public bool SendRequest(string command, out string errorMessage, out string outputMessage, int timeout)
    {
        errorMessage = string.Empty;
        outputMessage = string.Empty;

        try
        {
            if (_client == null || !_client.Connected)
            {
                errorMessage = "TCP连接已断开";
                return false;
            }

            var stream = _client.GetStream();
            stream.ReadTimeout = timeout;
            stream.WriteTimeout = timeout;

            // 发送指令(UTF8编码,以换行符结束)
            byte[] data = Encoding.UTF8.GetBytes(command + "\n");
            stream.Write(data, 0, data.Length);

            // 读取响应(直到收到结束标记)
            using (var ms = new MemoryStream())
            {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, bytesRead);
                    // 检查是否包含结束标记
                    string temp = Encoding.UTF8.GetString(ms.ToArray());
                    if (temp.Contains("\nEOF\n"))
                    {
                        outputMessage = temp.Replace("\nEOF\n", "").Trim();
                        return true;
                    }
                }
            }

            errorMessage = "未收到完整响应";
            return false;
        }
        catch (Exception ex)
        {
            errorMessage = ex.Message;
            return false;
        }
    }

    /// <summary>
    /// 关闭连接
    /// </summary>
    public void Close()
    {
        try
        {
            if (_client != null)
            {
                _client.Close();
            }
        }
        catch { }
        _client = null;
    }
}
    
python 复制代码
import sys
import time
import socket


# 简单的数字运算函数
def simple_calculation(input_num):
    result = (input_num ** 2) + (input_num * 1.5) - 42
    time.sleep(0.1)
    return round(result, 2)


# 简化的TCP服务器
class SimpleServer:
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.bind((host, port))
        self.server_socket.listen(1)
        self.running = True
        self.client_socket = None
        self.test_numbers = [12, 34, 56, 78, 90]

    def handle_client(self):
        while self.running and self.client_socket:
            try:
                data = self.client_socket.recv(1024).decode('utf-8').strip()
                if not data:
                    break
                if data == "EXECUTE":
                    result = self.process_numbers()
                    self.client_socket.sendall((result + "\nEOF\n").encode('utf-8'))
                elif data == "EXIT":
                    self.running = False
                    self.client_socket.sendall("已退出\nEOF\n".encode('utf-8'))
                    break
                else:
                    self.client_socket.sendall(("未知指令\nEOF\n").encode('utf-8'))
            except Exception as e:
                error_msg = f"处理请求出错: {str(e)}\nEOF\n"
                self.client_socket.sendall(error_msg.encode('utf-8'))
                break

    def process_numbers(self):
        total_start = time.perf_counter()
        results = []
        for num in self.test_numbers:
            try:
                result = simple_calculation(num)
                results.append(f"数字 {num} 的计算结果: {result}")
            except Exception as e:
                results.append(f"错误: {str(e)}")
        total_elapsed = time.perf_counter() - total_start
        results.append(f"\n总处理时间: {total_elapsed:.4f}秒")
        return "\n".join(results)

    def start(self):
        print(f"TCP服务器启动在 {self.host}:{self.port}")
        try:
            self.client_socket, addr = self.server_socket.accept()
            print(f"客户端 {addr} 已连接")
            self.handle_client()
        finally:
            self.stop()

    def stop(self):
        if self.client_socket:
            self.client_socket.close()
        self.server_socket.close()
        print("服务器已停止")


if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("用法: python simple_server.py [host] [port]")
        sys.exit(1)

    host = sys.argv[1]
    port = int(sys.argv[2])

    server = SimpleServer(host, port)
    try:
        server.start()
    except KeyboardInterrupt:
        server.stop()
    sys.exit(0)
    
相关推荐
波力海苔夹心脆6756 小时前
C# 序列化与反序列化详解:System.Text.Json、Newtonsoft.Json、XmlSerializer 用法、特性选项与安全实践
经验分享·后端·c#·json·.net
李航19837 小时前
给自己的图形引擎,配上了AI渲染,做设计真是太方便了
人工智能·python·计算机视觉·ai·ai编程
Zentceh8 小时前
安防监控夜视方案2026:AI全彩+边缘计算+云平台
图像处理·人工智能·科技·计算机视觉·车载系统·无人机·边缘计算
YOLO数据集集合10 小时前
风机叶片表面损伤检测数据集 | 风机叶片 表面损伤 污渍检测 无人机巡检 风电运维9119期
运维·人工智能·计算机视觉·目标跟踪·无人机·智慧城市·电力巡检
小羊没烦恼!11 小时前
在Scrum中实施敏捷建模
java·开发语言·windows·算法·c#
小蒋观天下12 小时前
行业拆解|两轮车检测AI摄像头的核心技术迭代、产品演进及未来技术发展
大数据·人工智能·安全·计算机视觉·ai大模型
Lost of 程序猿12 小时前
建造者模式实战:告别“十参数构造函数“的数据导出任务
后端·设计模式·c#·asp.net
szxinmai主板定制专家12 小时前
半导体设备控制器:RK3576+CODESYS+RK182X异构架构,实现晶圆视觉检测与运动联动闭环
人工智能·fpga开发·架构·视觉检测·边缘计算·codesys·rk3576
鬼手点金13 小时前
Claude Code示范案例-常用快捷命令
java·服务器·前端·计算机视觉·前向传播
mudtools14 小时前
在.NET现有系统中快速集成飞书任务分配能力
后端·c#·.net