OpenCVForUnity图像反色

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mseol/article/details/79271315

由于插件数据类型、API与c++版差异较大,这里需要花些功夫学习下Mat中像素的操作。细心的小朋友通过上一篇《锐化与模糊》中关于椒盐噪声的实现,可能已经学习到了具体的方法。

//用一个byte[]类型byteArray容器,从mat中取像素。
byte[] byteArray = new byte[dstMat.width() * dstMat.height()];
Utils.copyFromMat<byte>(dstMat, byteArray);

//可以通过id,控制到单通道中任意像素的值
byteArray[i + dstMat.width() * j] = 255;

//处理完的容器,拷贝回给mat,就是处理完的mat
Utils.copyToMat<byte>(byteArray, dstMat);

椒盐噪声中是对单通道(灰度图)随机添加白点,如果要处理RGB彩色图,需要先把通道单独拆出来处理像素,处理完再合并回去。

代码

[SerializeField] private Image m_showImage;
Mat srcMat;
List<Mat> channels;
byte[] byteArrayR, byteArrayG, byteArrayB;

void Start()
{
    srcMat = Imgcodecs.imread(Application.dataPath + "/Textures/sample.jpg");
    Imgproc.cvtColor(srcMat, srcMat, Imgproc.COLOR_BGR2RGB);
    //Debug.Log(srcMat.channels()); //3

    //提取通道
    channels = new List<Mat>();
    Core.split(srcMat, channels);

    //byteArray = new byte[srcMat.width() * srcMat.height()];
    byteArrayR = new byte[channels[0].width() * channels[0].height()];
    byteArrayG = new byte[channels[0].width() * channels[0].height()];
    byteArrayB = new byte[channels[0].width() * channels[0].height()];
    Utils.copyFromMat<byte>(channels[0], byteArrayR);
    Utils.copyFromMat<byte>(channels[1], byteArrayG);
    Utils.copyFromMat<byte>(channels[2], byteArrayB);

    //遍历像素
    int width = srcMat.width();
    int height = srcMat.height();
    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            //反色操作
            int rValue = 255 - byteArrayR[x + width * y];
            byteArrayR[x + width * y] = (byte)rValue;
            //Debug.Log(rValue); //r通道值

            int gValue = 255 - byteArrayG[x + width * y];
            byteArrayG[x + width * y] = (byte)gValue;

            int bValue = 255 - byteArrayB[x + width * y];
            byteArrayB[x + width * y] = (byte)bValue;
        }
    }

    //拷贝回Mat
    Utils.copyToMat(byteArrayR, channels[0]);
    Utils.copyToMat(byteArrayG, channels[1]);
    Utils.copyToMat(byteArrayB, channels[2]);
    //合并通道
    Core.merge(channels, srcMat);

    //ugui显示
    Texture2D t2d = new Texture2D(srcMat.width(), srcMat.height());
    Sprite sp = Sprite.Create(t2d, new UnityEngine.Rect(0, 0, t2d.width, t2d.height), Vector2.zero);
    m_showImage.sprite = sp;
    Utils.matToTexture2D(srcMat, t2d);
}

最终效果

效果

猜你喜欢

转载自blog.csdn.net/mseol/article/details/79271315