Opencv for Unity KinectV2 圖像降噪 漫畫

不知道爲啥感覺咋那麼少這種文章,要做個功能只能自己一點一點去做,找個參考文檔都沒,那些大佬是不是 星星星 的都忙着賺錢去了,心累

 

 

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<RawImage>();
        }

        rect = GetComponent<RectTransform>();
        // 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);

                }
            }
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章