OpenCV For Unity 实现简单抠图

Opencv的抠图的思路非常简单,就是对一个像素点进行判断,如果是需要剔除的像素,就把该像素的A通道改为0,即变为透明了。

        今天就来实现下面这个效果把一个白色的透明通道,抠除的效果。

同样,要对图像操作,首先需要对图片进行读取,这是非常基本的了。而今天要获取图像上的一个像素点,那么就需要用到OpenCVForUnity这个插件中的获取像素点的方法。int[] get()

他是Mat容器上的实例方法他会返回一个Int数组,如果是JPG,这个数组的长度就是3,分别代表RGB值,如果是PNG,这个数组长度就是RGBA值。

首先我们获取图片的Mat,并把尺寸改小增加运行效率。

因为Logo是JPG,所以我们要把这个JPG装进一个四通道的容器里去。



而且我们知道图片中白色的RBA 是(255,255,255),而黑色的RBA是(0,0,0)

而我们只要判断这个像素点是不是等于255就能判断他是不是白色拉。而Mat.Put则是修改图片像素的方法,前面是图片的坐标点,后面跟着RGBA值,并保持原来的值,并把透明通道的值改为0;


但运行结果会发现锯齿很严重,抠不干净。

而我们也知道图片的像素其实是做了插值运算的,所以越是邻近黑色的像素点,并不等于255的。所以我们把他设置一个阈值。



你会发现比刚才干净很多。

但复杂抠图可比简单抠图要难很多,逻辑也要复杂很多,所以这里只是提供一个思路给大家,如何去改变一个像素值,获取一个像素值,你可以自己不断进行新的尝试。



下面是完整代码

void Start()

    {

        //把图片读进三通道的容器

        var src = Imgcodecs.imread(Application.streamingAssetsPath + "/logo.jpg", 1);

        // var mask  = Imgcodecs.imread(Application.streamingAssetsPath+"/testsf.jpg",0);

        //把尺寸设置为大小

        Imgproc.resize(src, src, new Size(500, 500));

        //建立一个四通道的容器

        var dst = new Mat(src.cols(), src.rows(), CvType.CV_8UC4);

        //转换色彩空间

        Imgproc.cvtColor(src, dst, Imgproc.COLOR_BGR2RGBA);


        for (int i = 0; i < dst.cols(); i++)

        {

            for (int j = 0; j < dst.rows(); j++)

            {

                //这个105是阈值,你可以自己定义来试试效果

                if (dst.get(j, i)[0] >105)

                {

                    dst.put(j, i, 255, 255, 255, 0);

                }

            }

        }


        var tex = new Texture2D(dst.cols(), dst.rows(), TextureFormat.RGBA32, false);

        Utils.matToTexture2D(dst, tex);

        var raw = this.GetComponentInChildren();

        raw.texture = tex;

        raw.SetNativeSize();

    }

你可能感兴趣的:(OpenCV For Unity 实现简单抠图)