IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity EMGUCV 开启摄像头并根据坐标值截图,并向硬件发送被击中的消息 -> 正文阅读

[游戏开发]Unity EMGUCV 开启摄像头并根据坐标值截图,并向硬件发送被击中的消息

首先需要导入emguCV的库并引用

新建Quad,并创建新的材质球,将材质球的Shader改为Unlit/Texture,将材质球赋给Quad。

上代码

 //截图时中间的小点
    public GameObject hitPoint;
    public GameObject hitPointParent;

    UdpClient clientSend;
    IPEndPoint endpointSend;
    //Quad
    public GameObject myPlan_L;
    UdpClient client;
    IPEndPoint endpoint;
    Thread t;
    string receiveMsg;
    public bool saveFinsh;
    VideoCapture cap;
    Mat frame;
    Mat bgImg;
    Mat result_D = new Mat();
    Mat diff = new Mat();
    //Mat ROI_D;
    Thread t_V;

    public int shootNumber_L;
    //灰度值
    byte grayValue;

    public CombatController combatController;
    /// <summary>
    /// 是否被击中
    /// </summary>
    private bool isHit;

    private int temp =1;

    void Start()
    {
        bgImg = new Mat();
        frame = new Mat();
        
        ///视频帧差法检测运动物体
        cap = new VideoCapture(0);
        cap.SetCaptureProperty(CapProp.FrameWidth, 1920);
        cap.SetCaptureProperty(CapProp.FrameHeight, 1080);

        clientSend = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
        _tex2D = new Texture2D(1920, 1080);//初始化了一个新的2d tex  会占用内存
        
        client = new UdpClient(new IPEndPoint(IPAddress.Any, 6001));
        endpoint = new IPEndPoint(IPAddress.Any, 0);
        t = new Thread(Socket_rend);
        t.IsBackground = true;
        t.Start();

        t_V = new Thread(OpenCameraVideo);
        t_V.IsBackground = true;
        t_V.Start();



    }
    //socket接收接口
    void Socket_rend()
    {
        while (true)
        {
            byte[] buf = client.Receive(ref endpoint);
            receiveMsg = Encoding.Default.GetString(buf);
            //print(receiveMsg);
        }

    }

    Mat MoveDetect(Mat bgImg, Mat fgImg)
    {
        Mat result = fgImg.Clone();
        Mat gray = new Mat();
        Mat gray2 = new Mat();
        CvInvoke.CvtColor(bgImg, gray, ColorConversion.Bgr2Gray);
        CvInvoke.CvtColor(fgImg, gray2, ColorConversion.Bgr2Gray);
        //做差
        
        CvInvoke.AbsDiff(gray, gray2, diff);
        //CvInvoke.Imshow("diff", diff);
        //二值化
        CvInvoke.Threshold(diff, diff, 50, 255, ThresholdType.Binary);
        //CvInvoke.Imshow("threshold", diff);

        //中值滤波
        CvInvoke.MedianBlur(diff, diff, 5);
        //CvInvoke.Imshow("median blur", diff);

        //膨胀
        Mat element = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(9, 9), new Point(-1, -1));
        CvInvoke.Dilate(diff, diff, element, new Point(-1, -1), 1, BorderType.Default, new MCvScalar());
        //CvInvoke.Imshow("dilate", diff);

        //绘制外接椭圆
        //VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
        //CvInvoke.FindContours(diff, contours, null, RetrType.External, ChainApproxMethod.ChainApproxNone);

        //for (int i = 0; i < contours.Size; i++)
        //{

        //    RotatedRect rotatedRect = CvInvoke.FitEllipse(contours[i]);     //计算外接椭圆
        //    Point rcenter = new Point((int)rotatedRect.Center.X, (int)rotatedRect.Center.Y);
        //    CvInvoke.Ellipse(result, rcenter, new Size((int)(rotatedRect.Size.Width / 2), (int)(rotatedRect.Size.Height / 2)), rotatedRect.Angle, 0, 360,
        //                new MCvScalar(0, 0, 255), 2);

        //    //Rectangle rect = CvInvoke.BoundingRectangle(contours[i]);
        //    //CvInvoke.Rectangle(result, rect, new MCvScalar(0, 0, 255), 2);

        //}
        return result;

    }
    //截图并保存
    void PrintScreen(Mat img, string coords,int shootNumber, Mat threshold)
    {
        
        //print("我进来了");
        //获取传过来的坐标值
        string[] str = DisposeString(coords);
        //Console.WriteLine(y);
        int x = int.Parse(str[1]);
        int y = int.Parse(str[2]);

        if (x < 50 || x > 1870 || y < 50 || y > 1030)
        {
            return;
        }
        //根据坐标值截图               图片起始位置与大小
        Mat ROI = new Mat(img, new Rectangle(x - 50, 1080 - y - 50, 100, 100));
        //print(x +"    "+ y);
        //CvInvoke.Line(ROI, x_P, y_P, new MCvScalar(255, 0, 0), s100, LineType.EightConnected,2);
        CvInvoke.Imwrite(Application.dataPath + "/Image/" + str[0] + shootNumber.ToString() + ".png", ROI);
        //CvInvoke.Imwrite(Application.dataPath  + "result_D.png", img);
        Image<Bgr, byte> grayValueImg = threshold.ToImage<Bgr, Byte>();
        grayValue = grayValueImg.Data[ x, 1080 - y, 0];
        receiveMsg = null;
        saveFinsh = true;
        //Destroy(temp);
        
    }

    private string[] DisposeString(string msg)
    {
        string[] str = null;
        if (msg != null)
        {
            str = msg.Split('/');
        }
        return str;
    }

    void OpenCameraVideo()
    {
        if (!cap.IsOpened)
        {
            print("Open video failed..");
            return;
        }
        int count = 0;
        
        while (true)
        {
            cap.Read(frame);
            if (frame.IsEmpty)
            {
                print("frame is empty..");
                break;
            }
            count++;
            if (count == 1)
            {
                bgImg = frame.Clone();
            }
            //String y = Socket_rend();

            //if (y != null)
            //{
            //    PrintScreen(frame.Clone(), y);
            //}
            result_D = MoveDetect(bgImg, frame);
            //CvInvoke.Imshow("move", result_D);
            //bgImg = frame.Clone();  //更新前一帧
            CvInvoke.WaitKey(30);
            if (CvInvoke.WaitKey(30) == 27)
            {
                break;
            }

        }

    }
    Texture2D _tex2D;
    /// <summary>
    /// 不断刷新纹理,制造视频效果
    /// </summary>
    void FileStreamLoadTexture(Mat myMat)
    {
        //Mat src = CvInvoke.Imread(Application.dataPath + "/StreamingAssets/new.png", ImreadModes.Unchanged);
        Image<Bgr, byte> img = myMat.ToImage<Bgr, Byte>();
        _tex2D.LoadImage(img.ToJpegData());
        _tex2D.Apply();
        myPlan_L.GetComponent<MeshRenderer>().material.mainTexture = _tex2D;
        //Destroy(_tex2D);// 释放掉2d  tex的内存占用  注释掉可以看到画面贴图切换的效果
    }

    private void Update()
    {
        if (result_D != null)
        {
            if (Time.frameCount % 2 == 0)
            {
                try
                {
                    FileStreamLoadTexture(result_D);
                }
                catch
                {

                }
                
            }
        }

        if (receiveMsg != null && receiveMsg.Substring(0,1) == "l")
        {
            if (shootNumber_L < combatController.totalBulletNum)
            {
                shootNumber_L += 1;
                PrintScreen(result_D, receiveMsg, shootNumber_L,diff);
                if (grayValue > 245)
                {
                    SendToSerial();//向硬件发送被击中的消息
                    isHit = true;
                }
                else
                {
                    isHit = false;
                }
                combatController.Fire_L(isHit, "l" + shootNumber_L);//左侧玩家开火

            }
        }

        if (Input.GetKeyDown(KeyCode.S))
        {
            PrintScreen(result_D, "l/500/500", temp,diff);
            combatController.Fire_L(isHit, "l" + temp);
            temp++;
        }

        if (Input.GetKeyDown(KeyCode.Escape))
        {
            endpointSend = new IPEndPoint(IPAddress.Parse("255.255.255.255"), 53478);
            byte[] buf = Encoding.Default.GetBytes("Quit");
            clientSend.Send(buf, buf.Length, endpointSend);
        }

    }
public void SendToSerial()
    {
        endpointSend = new IPEndPoint(IPAddress.Parse("255.255.255.255"), 53478);
        byte[] buf = Encoding.Default.GetBytes("32");
        clientSend.Send(buf, buf.Length, endpointSend);
        grayValue = 0;
    }

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-08-29 09:41:08  更:2021-08-29 09:41:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/2 14:47:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码