评论区有人知道的可以插个眼告诉我一下:
- 使用Shader 两图片alpah相乘也可以做到只显示摄像头圆形区域,但是我不知道怎么保存这个圆形区域
- 使用 Mask,也可以做到只显示摄像头圆形区域,但是我不知道怎么保存这个圆形区域
- 所以我使用的是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;
}
}
}
}