Unity 截取摄像头圆形区域并保存 By Opencv

评论区有人知道的可以插个眼告诉我一下:

  1. 使用Shader 两图片alpah相乘也可以做到只显示摄像头圆形区域,但是我不知道怎么保存这个圆形区域
  2. 使用 Mask,也可以做到只显示摄像头圆形区域,但是我不知道怎么保存这个圆形区域
  3. 所以我使用的是Opencv,其实这种方法实用但是不通用,但是足够解决我的需求了

第一张图假设为摄像头实时画面,第二张为mask遮罩图(opencv copyto()函数 白显示,黑透明)
在这里插入图片描述
在这里插入图片描述
opencv这里有两种方式可以实现一个是使用Core.bitwise_and() ,一个是使用Mat.copyTo()
需要注意的是如果有背景放到它的下一层,还有就是加载的时候最好设置一下 Alpha Is Transparency=true;
效果展示:
在这里插入图片描述
代码:

using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using OpenCVForUnity.UnityUtils;
using QFramework.Example;
using UnityEngine;
using UnityEngine.UI;

public class GetCircleWebcam : MonoBehaviour
{
    
    
    private Texture2D Webcam;
    private Mat webcamMat;
    private Texture2D mask;
    private Mat maskMat;

    // 用于显示最后效果 
    public RawImage webcamRaw;
    private Mat FinalMat;

    // 摄像头分辨率 测试环境值应该为 两张图片的分辨率
    private int _iWebcamWidth = 1920;
    private int _iWebcamHeight = 1080;

    private void Start()
    {
    
    
        // 这个是加载本地Texture2D
        Webcam = TextureKit.Instance.LoadTexture2DSingle(@"D:\_RD\Unity_Projects\20190416_Projects\CouponP20190416D20201210\Assets\_Tint_Projects\Textures\webcam.png");
        mask = TextureKit.Instance.LoadTexture2DSingle(@"D:\_RD\Unity_Projects\20190416_Projects\CouponP20190416D20201210\Assets\_Tint_Projects\Textures\mask.png");

        // 初始化Mat Texture
        webcamMat = new Mat(_iWebcamHeight, _iWebcamWidth, CvType.CV_8UC4);
        maskMat = new Mat(_iWebcamHeight, _iWebcamWidth, CvType.CV_8UC1);
        FinalMat = new Mat(_iWebcamHeight, _iWebcamWidth, CvType.CV_8UC4);
        Texture2D texture = new Texture2D(_iWebcamWidth, _iWebcamHeight, TextureFormat.RGBA32, false);

        //Texture2D 转 Mat
        Utils.texture2DToMat(Webcam, webcamMat);
        Utils.texture2DToMat(mask, maskMat);

        // Copyto() https://www.cnblogs.com/minglou/articles/9594495.html
        webcamMat.copyTo(FinalMat, maskMat);

        // mat 转 Texture2D
        Utils.matToTexture2D(FinalMat, texture);
        webcamRaw.texture = texture;
        // 保存图片
        TextureKit.Instance.SaveTexture2DToPNG(texture, @"D:\_RD\Unity_Projects\20190416_Projects\CouponP20190416D20201210\Assets\_Tint_Projects\Textures\circle.png");

        //第二种方式 转灰度图 二值化 与操作
        //Imgproc.cvtColor(maskMat, maskMat, Imgproc.COLOR_RGB2GRAY);
        //Imgproc.threshold(maskMat, maskMat, 100, 255, 0);
        //Core.bitwise_and(webcamMat, webcamMat, FinalMat, maskMat);
    }
}

摄像头实时:
在这里插入图片描述

/****************************************************************************
 * 2020.12 DESKTOP-J98GMVJ
 ****************************************************************************/

using OpenCVForUnity.CoreModule;
using OpenCVForUnity.UnityUtils;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;

namespace QFramework.Example
{
    
    
    public partial class WebcamCircleRaw : MonoBehaviour
    {
    
    
      
        private Mat webcamMat;
        public Texture2D mask;
        private Mat maskMat;

        // 用于显示最后效果 
        public RawImage webcamRaw;
        private Mat FinalMat;

        // 摄像头分辨率 测试环境值应该为 两张图片的分辨率
        public int _iWebcamWidth = 1920;
        public int _iWebcamHeight = 1080;

        public WebCamTexture cameraTexture;
        public string cameraName = "";
        private Texture2D texture;

        private void Awake()
        {
    
    
            
        }

        private void Start()
        {
    
    
            webcamRaw = GetComponent<RawImage>();

            StartCoroutine(PlayWebCam());


            // 这个是加载本地Texture2D
            mask = TextureKit.Instance.LoadTexture2DSingle(Application.dataPath + @"\_Tint_Projects\Scenes\TestDemos\GetCircleWebcam\mask.png");

            // 初始化Mat Texture
            webcamMat = new Mat(_iWebcamHeight, _iWebcamWidth, CvType.CV_8UC4);
            maskMat = new Mat(_iWebcamHeight, _iWebcamWidth, CvType.CV_8UC1);
            FinalMat = new Mat(_iWebcamHeight, _iWebcamWidth, CvType.CV_8UC4);
            texture = new Texture2D(_iWebcamWidth, _iWebcamHeight, TextureFormat.RGBA32, false);

            Utils.texture2DToMat(mask, maskMat);

             Copyto() https://www.cnblogs.com/minglou/articles/9594495.html
            //webcamMat.copyTo(FinalMat, maskMat);

             mat 转 Texture2D
            //Utils.matToTexture2D(FinalMat, texture);
            //webcamRaw.texture = texture;
             保存图片
            //TextureKit.Instance.SaveTexture2DToPNG(texture, @"D:\_RD\Unity_Projects\20190416_Projects\CouponP20190416D20201210\Assets\_Tint_Projects\Textures\circle.png");

            第二种方式 转灰度图 二值化 与操作
            Imgproc.cvtColor(maskMat, maskMat, Imgproc.COLOR_RGB2GRAY);
            Imgproc.threshold(maskMat, maskMat, 100, 255, 0);
            Core.bitwise_and(webcamMat, webcamMat, FinalMat, maskMat);
        }

        private void Update()
        {
    
    
            if (cameraTexture != null)
            {
    
    
                Utils.webCamTextureToMat(cameraTexture, webcamMat);
                webcamMat.copyTo(FinalMat, maskMat);
                Utils.matToTexture2D(FinalMat, texture);
                webcamRaw.texture = texture;
            }

            if (Input.GetKeyDown(KeyCode.Space))
            {
    
    
                // 保存图片
                TextureKit.Instance.SaveTexture2DToPNG(texture, Application.dataPath + @"\_Tint_Projects\Textures\" + Time.deltaTime + ".png");
            }
        }


        private IEnumerator PlayWebCam()
        {
    
    
            yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
            if (Application.HasUserAuthorization(UserAuthorization.WebCam))
            {
    
    
                WebCamDevice[] devices = WebCamTexture.devices;
                cameraName = devices[0].name;
                cameraTexture = new WebCamTexture(cameraName, 1920, 1080, 30);
                cameraTexture.Play();
                //webcamRaw.texture = cameraTexture;
            }



        }

    }
}

猜你喜欢

转载自blog.csdn.net/qq_39097425/article/details/111406413