TC——Kinect无背景抠像头发缺失解决方法 2020-07-11

最近用AzureKinect测试无背景抠像,发现头发总是缺失一块。

解决办法:用Opencv图像处理提取头发部分,然后与原图像叠加。

环境:Opencv for unity 、 AzureKinect for unity 、unity2019.2.9

详细说明:

1、首先提取Kinect彩色图像colorTexture和人体alphaTexture(这两个texture在Azure for unity里面的BackgroundRemovalManager可以得到)并转为Mat。(下图位置1)

2、获取头部位置,在该位置画一个圆形遮罩。然后再将彩色图像根据遮罩提取头部,将头部图像转为HSV并通过阈值提取出头发部分的遮罩(需要用opencvForUnity,opencvForUnity 其实是移植的opencv for java,如果找不到unity的实现,建议初学者(包括我哈哈)去寻找java的实现。)(下图位置2)

3、将人像alphaMat与第二部提取的遮罩合并。得到处理过的遮罩。(下图位置3)

4、将彩色图像根据第三步的遮罩提取出来人像,这样就修复了头发破损。

012.png

主要代码块:


void body_getHair()

        {

            Vector3 pos = Camera.main.WorldToViewportPoint(GameObject.Find("GreenBall").transform.position);

            GameObject.Find("01").GetComponent().texture = GetAlphaTex();

            HeadPos = new Point((1-pos.x) * 1920, (pos.y) * 1080+100);

            print("headPos:"+HeadPos);

            if (colorTexture&&alphaTexture)

            {

                RenderTexture2Texture2D_ColorTex(colorTexture);  //将texture转成texture2D方便转成Mat,

                RenderTexture2Texture2D_AlphaTex(alphaTexture);//将texture转成texture2D方便转成Mat

                src = new Mat(tsr.height, tsr.width, CvType.CV_8UC4);

                Utils.texture2DToMat(tsr, src);

                src_alpha = new Mat(tsr_alpha.height, tsr_alpha.width, CvType.CV_8UC1);

                Utils.texture2DToMat(tsr_alpha, src_alpha);

                Mat imgOrigin = src.clone();

                Mat maskCopyTo = Mat.zeros(imgOrigin.size(), CvType.CV_8UC1); // 创建copyTo方法的mask,大小与原图保持一致

                Imgproc.circle(maskCopyTo, HeadPos, 160, Scalar.all(255), -2, 8, 0); // 画出圆的轮廓

                Mat copy = new Mat();

                imgOrigin.copyTo(copy, maskCopyTo);

                Utils.matToTexture2D(copy, t2);

                GameObject.Find("02").GetComponent().texture = t2;

                Mat hsv = new Mat();

                Imgproc.cvtColor(copy, hsv, Imgproc.COLOR_BGR2HSV);

                Mat maskk = hsv.clone();

                Core.inRange(hsv, new Scalar(0, 0, 0), new Scalar(180, 255, 46), maskk);

                Mat newMask = new Mat();

                maskk.copyTo(newMask, maskCopyTo);

                Mat dist = new Mat();

                Core.add(src_alpha, newMask, dist);

                Utils.matToTexture2D(dist, t3);

                GameObject.Find("03").GetComponent().texture = t3;

                Mat last = new Mat();

                src.copyTo(last, dist);

                print(dist.width() + ":" + dist.height());

                Utils.matToTexture2D(last, t4);

                GameObject.Find("04").GetComponent().texture = t4;

            }

        }
  public void RenderTexture2Texture2D_ColorTex(RenderTexture rt)
        {
            RenderTexture preRT = RenderTexture.active;
            RenderTexture.active = rt;
            tsr.ReadPixels(new UnityEngine.Rect(0, 0, rt.width, rt.height), 0, 0);
            tsr.Apply();
            RenderTexture.active = preRT;
        }
        public void RenderTexture2Texture2D_AlphaTex(RenderTexture rt)
        {
            RenderTexture preRT = RenderTexture.active;
            RenderTexture.active = rt;
            tsr_alpha.ReadPixels(new UnityEngine.Rect(0, 0, rt.width, rt.height), 0, 0);
            tsr_alpha.Apply();
            RenderTexture.active = preRT;
        }

你可能感兴趣的:(TC——Kinect无背景抠像头发缺失解决方法 2020-07-11)