在Unity中实现对北京赛车源码出售图像的前后背景分离的效果

北京赛车源码出售Q1157880099

因为项目中需要完成对手部的摄像头识别,识别过程中,需要将指尖识别为五个点,并且映射到VR环境中去。需要对摄像头欧拍到的内容进行图像处理。


主要用到的方法是 grabCut方法。


GrabCut函数说明

void grabCut(InputArray img, InputOutputArray mask, Rect rect, InputOutputArraybgdModel, InputOutputArrayfgdModel, intiterCount, intmode=GC_EVAL)

Parameters:
  • image – Input 8-bit 3-channel image.
  • mask –

    Input/output 8-bit single-channel mask. The mask is initialized by the function whenmode is set to GC_INIT_WITH_RECT. Its elements may have one of following values:

    • GC_BGD defines an obvious background pixels.
    • GC_FGD defines an obvious foreground (object) pixel.
    • GC_PR_BGD defines a possible background pixel.
    • GC_PR_BGD defines a possible foreground pixel.
  • rect – ROI containing a segmented object. The pixels outside of the ROI are marked as “obvious background”. The parameter is only used whenmode==GC_INIT_WITH_RECT .
  • bgdModel – Temporary array for the background model. Do not modify it while you are processing the same image.
  • fgdModel – Temporary arrays for the foreground model. Do not modify it while you are processing the same image.
  • iterCount – Number of iterations the algorithm should make before returning the result. Note that the result can be refined with further calls withmode==GC_INIT_WITH_MASK ormode==GC_EVAL .
  • mode –

    Operation mode that could be one of the following:

    • GC_INIT_WITH_RECT The function initializes the state and the mask using the provided rectangle. After that it runsiterCountiterations of the algorithm.
    • GC_INIT_WITH_MASK The function initializes the state using the provided mask. Note thatGC_INIT_WITH_RECT andGC_INIT_WITH_MASK can be combined. Then, all the pixels outside of the ROI are automatically initialized withGC_BGD .
    • GC_EVAL The value means that the algorithm should just resume.

函数原型:
    void cv::grabCut( const Mat& img, Mat& mask, Rect rect,
             Mat& bgdModel, Mat& fgdModel,
             int iterCount, int mode )
其中:
img——待分割的源图像,必须是8位3通道(CV_8UC3)图像,在处理的过程中不会被修改;
mask——掩码图像,如果使用掩码进行初始化,那么mask保存初始化掩码信息;在执行分割的时候,也可以将用户交互所设定的前景与背景保存到mask中,然后再传入grabCut函数;在处理结束之后,mask中会保存结果。mask只能取以下四种值:
GCD_BGD(=0),背景;
GCD_FGD(=1),前景;
GCD_PR_BGD(=2),可能的背景;
GCD_PR_FGD(=3),可能的前景。
如果没有手工标记GCD_BGD或者GCD_FGD,那么结果只会有GCD_PR_BGD或GCD_PR_FGD;
rect——用于限定需要进行分割的图像范围,只有该矩形窗口内的图像部分才被处理;
bgdModel——背景模型,如果为null,函数内部会自动创建一个bgdModel;bgdModel必须是单通道浮点型(CV_32FC1)图像,且行数只能为1,列数只能为13x5;
fgdModel——前景模型,如果为null,函数内部会自动创建一个fgdModel;fgdModel必须是单通道浮点型(CV_32FC1)图像,且行数只能为1,列数只能为13x5;
iterCount——迭代次数,必须大于0;
mode——用于指示grabCut函数进行什么操作,可选的值有:
GC_INIT_WITH_RECT(=0),用矩形窗初始化GrabCut;
GC_INIT_WITH_MASK(=1),用掩码图像初始化GrabCut;
GC_EVAL(=2),执行分割。


具体代码:

扫描二维码关注公众号,回复: 1549716 查看本文章

[csharp]  view plain  copy
  1. using UnityEngine;  
  2. using OpenCVForUnity;  
  3.   
  4. public class TextureCutOut : MonoBehaviour {  
  5.     private Mat image ;  
  6.     private Mat mask, binMask, dstMat;  
  7.     private OpenCVForUnity.Rect rect;  
  8.     private Mat bgModel, fgModel;  
  9.     byte[] maskPixels;  
  10.     // Use this for initialization  
  11.     void Start () {  
  12.         Texture2D inputTexture = Resources.Load("inputTexture"as Texture2D;  
  13.         image = new Mat(inputTexture.height, inputTexture.width, CvType.CV_8UC3);  
  14.         Utils.texture2DToMat(inputTexture, image);  
  15.         mask = new Mat(inputTexture.height, inputTexture.width, CvType.CV_8UC1);  
  16.         mask.setTo(new Scalar(Imgproc.GC_BGD));  
  17.   
  18.         rect = new OpenCVForUnity.Rect(45,25, 175, 210);  
  19.   
  20.         //掩码空间mask对应矩形空间内的掩码设置为GC_PR_FGD(预设为前景)  
  21.         Mat matRectCol = mask.colRange(rect.x, rect.x + rect.width);  
  22.         Mat matRectRow = mask.rowRange(rect.y, rect.y + rect.height);  
  23.         matRectCol.setTo(new Scalar(Imgproc.GC_PR_FGD));  
  24.         matRectRow.setTo(new Scalar(Imgproc.GC_PR_FGD));  
  25.   
  26.         //框出预设前景  
  27.         Imgproc.rectangle(image,new Point(rect.x, rect.y),new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 0, 255, 255), 2);  
  28.         //Texture2D outputTexture = new Texture2D(image.cols(), image.rows(), TextureFormat.RGBA32, false);  
  29.         //Utils.matToTexture2D(image, outputTexture);  
  30.   
  31.         //重新读取原始图片 切割  
  32.         Utils.texture2DToMat(inputTexture, image);  
  33.         bgModel = new Mat();  
  34.         fgModel = new Mat();  
  35.         Imgproc.grabCut(image, mask, rect, bgModel, fgModel, 1);  
  36.         GetBinMask(ref mask, ref binMask);  
  37.         dstMat = new Mat(mask.size(), CvType.CV_8UC1);  
  38.         image.copyTo(dstMat, binMask);  
  39.   
  40.         Texture2D outputTexture = new Texture2D(dstMat.cols(), dstMat.rows(), TextureFormat.RGBA32, false);  
  41.         Utils.matToTexture2D(dstMat, outputTexture);  
  42.   
  43.         gameObject.GetComponent<Renderer>().material.mainTexture = outputTexture;  
  44.     }  
  45.       
  46.     // Update is called once per frame  
  47.     void Update () {  
  48.     }  
  49.   
  50.     void GetBinMask(ref Mat comMask,ref Mat binMask)  
  51.     {  
  52.         binMask = new Mat(comMask.size(), CvType.CV_8UC1);  
  53.         //commask中有0,1,2,3四种取值,这句就是取值为0,2的在binmask都为0,取值1,3的在binmask中为1  
  54.         //binMask = comMask & 1;  
  55.         maskPixels = new byte[comMask.cols() * comMask.rows()*comMask.channels()];  
  56.         comMask.get(0,0,maskPixels);  
  57.         for (int i = 0; i < maskPixels.Length; i++)  
  58.         {  
  59.             if (maskPixels[i] == 0 || maskPixels[i] == 2)  
  60.             {  
  61.                 maskPixels[i] = 0;  
  62.             }  
  63.             if (maskPixels[i] == 1 || maskPixels[i] == 3)  
  64.             {  
  65.                 maskPixels[i] = 1;  
  66.             }  
  67.         }  
  68.         binMask.put(0,0, maskPixels);  
  69.     }  
  70. }  

猜你喜欢

转载自blog.csdn.net/qq_42414541/article/details/80619728