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)
    
相关推荐
若天明1 小时前
深度学习-计算机视觉-微调 Fine-tune
人工智能·python·深度学习·机器学习·计算机视觉·ai·cnn
GitLqr1 小时前
AI洞察 | 混元、昆仑 重塑 3D 世界新方向
计算机视觉·游戏开发·音视频开发
图灵学术计算机论文辅导3 小时前
论文推荐|迁移学习+多模态特征融合
论文阅读·人工智能·深度学习·计算机网络·算法·计算机视觉·目标跟踪
一百天成为python专家3 小时前
Python循环语句 从入门到精通
开发语言·人工智能·python·opencv·支持向量机·计算机视觉
AI视觉网奇3 小时前
kafka 冲突解决 kafka安装
c#·linq
hqwest3 小时前
C#WPF实战出真汁07--【系统设置】--菜品类型设置
开发语言·c#·wpf·grid设计·stackpanel布局
萘柰奈4 小时前
Unity进阶--C#补充知识点--【Unity跨平台的原理】Mono与IL2CPP
unity·c#·游戏引擎
程序设计实验室4 小时前
StarBlog v1.3.0 新版本,一大波更新以及迁移服务器部署
c#·aspnetcore·starblog番外
淡海水5 小时前
【原理】Struct 和 Class 辨析
开发语言·c++·c#·struct·class