不知道为啥感觉咋那么少这种文章,要做个功能只能自己一点一点去做,找个参考文档都没,那些大佬是不是 星星星 的都忙着赚钱去了,心累
1. KinectManager 设置如下
2. 将代码挂上去就好了
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgcodecsModule;
using OpenCVForUnity.ImgprocModule;
using OpenCVForUnity.UnityUtils;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class OpencvKinect : MonoBehaviour
{
int kinectDepthWidth = 512;
int kinectDepthHeight = 424;
KinectManager manager;
public RawImage comicRaw;
public RawImage grayRaw;
public RawImage lineRaw;
public RawImage bgRaw;
public RawImage BodyColorRaw;
public RawImage maskRaw;
public Texture2D ComicTex;
public Texture2D GrayTex;
public Texture2D lineTex;
public Texture2D bgTex;
public Texture2D BodyColorTex;
public Texture2D maskTex;
RectTransform rect;
Mat rgbaMat;
Mat grayMat;
Mat bgMat;
Mat lineMat2;
Mat maskMat;
Mat dstMat;
Mat dstMat3;
Mat bodyColorMat;
byte[] grayPixels;
byte[] maskPixels;
void Start()
{
manager = KinectManager.Instance;
if (comicRaw == null)
{
comicRaw = GetComponent();
}
rect = GetComponent();
// kinect 深度摄像头分辨率 512,424
//rect.sizeDelta = new Vector2(kinectDepthWidth, kinectDepthHeight);
//// 自适应 Game 窗口
//float scaleValue = Camera.main.pixelRect.width / kinectDepthWidth;
//rect.localScale = new Vector3(scaleValue, -scaleValue, 1);
rgbaMat = new Mat(kinectDepthHeight, kinectDepthWidth, CvType.CV_8UC4);
bodyColorMat = new Mat(kinectDepthHeight, kinectDepthWidth, CvType.CV_8UC4);
grayMat = new Mat(kinectDepthHeight, kinectDepthWidth, CvType.CV_8UC1);
lineMat2 = new Mat(kinectDepthHeight, kinectDepthWidth, CvType.CV_8UC1);
maskMat = new Mat(kinectDepthHeight, kinectDepthWidth, CvType.CV_8UC1);
bgMat = new Mat(kinectDepthHeight, kinectDepthWidth, CvType.CV_8UC1, new Scalar(255));
//create a striped background.
for (int i = 0; i < bgMat.rows() * 2.5f; i = i + 4)
{
Imgproc.line(bgMat, new Point(0, 0 + i), new Point(bgMat.cols(), -bgMat.cols() + i), new Scalar(0), 1);
}
dstMat = new Mat(kinectDepthHeight, kinectDepthWidth, CvType.CV_8UC1);
dstMat3 = new Mat(kinectDepthHeight, kinectDepthWidth, CvType.CV_8UC4);
grayPixels = new byte[grayMat.cols() * grayMat.rows() * grayMat.channels()];
maskPixels = new byte[maskMat.cols() * maskMat.rows() * maskMat.channels()];
ComicTex = new Texture2D(kinectDepthWidth, kinectDepthHeight, TextureFormat.RGBA32, false);
GrayTex = new Texture2D(kinectDepthWidth, kinectDepthHeight, TextureFormat.RGBA32, false);
lineTex = new Texture2D(kinectDepthWidth, kinectDepthHeight, TextureFormat.RGBA32, false);
bgTex = new Texture2D(kinectDepthWidth, kinectDepthHeight, TextureFormat.RGBA32, false);
BodyColorTex = new Texture2D(kinectDepthWidth, kinectDepthHeight, TextureFormat.RGBA32, false);
maskTex = new Texture2D(kinectDepthWidth, kinectDepthHeight, TextureFormat.RGBA32, false);
}
void Update()
{
if (manager && manager.IsInitialized())
{
if (manager.GetUsersCount() > 0)
{
// bodyTexture 转 mat GetUsersClrTex(); GetUsersLblTex();
Utils.texture2DToMat(manager.GetUsersLblTex(), rgbaMat);
////// ----------------对深度图降噪-------------
Imgproc.medianBlur(rgbaMat, lineMat2, 13); // 中值过滤
Imgproc.Canny(lineMat2, lineMat2, 20, 120); // 线平滑
Core.bitwise_not(lineMat2, lineMat2); // 反转
//// 如果只需要扣人的身体原图 请 return,不要运行GetComicMat(),否则算法会延迟;
// GetBodyColorMat();
// return;
// 如果只需要 漫画 请不要调用 GetBodyColorMat(); 否则算法会延迟
GetComicMat();
}
}
}
// 将人漫画
void GetComicMat()
{
//--------------------- 漫画 ------------------
//创立一个Gray的Mat容器
Imgproc.cvtColor(rgbaMat, grayMat, Imgproc.COLOR_BGR2GRAY);
bgMat.copyTo(dstMat);
grayMat.get(0, 0, grayPixels);
for (int i = 0; i < grayPixels.Length; i++)
{
maskPixels[i] = 0;
if (grayPixels[i] < 70)
{
grayPixels[i] = 50;
maskPixels[i] = 1;
}
else if (70 <= grayPixels[i] && grayPixels[i] < 120)
{
grayPixels[i] = 100;
}
else
{
grayPixels[i] = 255;
maskPixels[i] = 1;
}
}
grayMat.put(0, 0, grayPixels);
maskMat.put(0, 0, maskPixels);
grayMat.copyTo(dstMat, maskMat);
Imgproc.cvtColor(dstMat, dstMat3, Imgproc.COLOR_GRAY2RGBA);
//遍历一下这个 dst 容器, 里面是处理图像的逻辑 会输出一个处理过的 dst 返回出来
for (int i = 0; i < lineMat2.cols(); i++)
{
for (int j = 0; j < lineMat2.rows(); j++)
{
//这个150是阈值,你可以自己定义来试试效果
if (lineMat2.get(j, i)[0] > 250)
{
//根据 mask 图 对原图相应位置的点设置
dstMat3.put(j, i, 255, 255, 255, 0);
}
}
}
dstMat3.copyTo(rgbaMat);
Utils.matToTexture2D(rgbaMat, ComicTex);
comicRaw.texture = ComicTex;
Utils.matToTexture2D(grayMat, GrayTex);
grayRaw.texture = GrayTex;
Utils.matToTexture2D(lineMat2, lineTex);
lineRaw.texture = lineTex;
Utils.matToTexture2D(bgMat, bgTex);
bgRaw.texture = bgTex;
Utils.matToTexture2D(dstMat, maskTex);
maskRaw.texture = maskTex;
}
// 只显示人的颜色图
void GetBodyColorMat()
{
for (int i = 0; i < lineMat2.cols(); i++)
{
for (int j = 0; j < lineMat2.rows(); j++)
{
//这个150是阈值,你可以自己定义来试试效果
if (lineMat2.get(j, i)[0] > 250)
{
// 根据 mask 图 对原图相应位置的点设置
rgbaMat.put(j, i, 255, 255, 255, 0);
}
}
}
rgbaMat.copyTo(bodyColorMat);
Utils.matToTexture2D(bodyColorMat, BodyColorTex);
BodyColorRaw.texture = BodyColorTex;
}
// 用于黑白遮罩图
void MaskBlack()
{
// 黑白遮罩图
for (int i = 0; i < lineMat2.cols(); i++)
{
for (int j = 0; j < lineMat2.rows(); j++)
{
//这个150是阈值,你可以自己定义来试试效果
if (lineMat2.get(j, i)[0] > 250)
{
// 根据 mask 图 对原图相应位置的点设置
lineMat2.put(j, i, 0, 0, 0, 255);
}
else
{
// 根据 mask 图 对原图相应位置的点设置
lineMat2.put(j, i, 255, 255, 255, 255);
}
}
}
}
}