OpenCV for Unity(1):获取图片对应像素点的颜色

1,566 阅读3分钟

「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。

概述

OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以在WindowsAndroid等操作系统上运行。可以实现图像处理等多方面的通用算法。地址

OpeCV for UnityOpenCV 是一个资源插件,可以在Unity中实现Texture2D 和 OpenCV 的 Mat 之间的相互转换,可以实现图像的实时处理以及人脸识别等功能。官网地址

本篇文章主要介绍一下,使用OpeCV for Unity获取到图像中某一像素点的颜色。使用的OpenCV for Unity插件版本是2.3.3(在百度上找的他人分享的资源,需要资源的可以在下方留言(包括本篇文章的源代码))。

效果预览

注意看右侧的颜色条
效果1(颜色相近了不太明显)

0118.gif 效果2

0118_1.gif

功能实现

功能分析

本篇文章想要实现的功能:在Unity场景中,有一张Image图片,鼠标点击到图片的对应位置,获取到该像素点的颜色。实际上是读取的本地图片文件,而非读取的是场景中的文件,场景中的文件只是作为显示,让我们知道点击什么位置需要什么位置的颜色。

场景搭建

首先要进行场景搭建,也是非常的简单,在Unity中创建一个Image图片,将需要的识别的图片放到场景中。本篇文章只需要一张图片在场景中供鼠标点击进行颜色获取即可,如下如所示:

image.png

代码编写

在OpenCV中计算像素点的时候要注意一点的是,其位置和在Unity中的像素位置不同,他是从左上角开始计算(0,0),右下角为结束位置,如下图1所示,所用的尺寸是1920*1080.

注意:右下角的点不能使用(1920*1080),要使用(1919,1079),要小一个像素,要不然造成程序报空(见下图2)

image.png 图1

image.png 图2

由于像素计算不同,在Unity中Input.mousePosition是从左下角到右上角,所以要先进行像素的转换。

/// <summary>
/// 获取识别点像素位置
/// </summary>
/// <param name="vector"></param>
/// <returns></returns>
public static Vector2 Vector3ToPixelLocation(Vector3 vector)
{
    Debug.Log(vector);
   float x = vector.x;
   float y = Screen.height-vector.y;
   if (x >= Screen.width) x = Screen.width - 1;
   if (y >= Screen.height) y = Screen.height - 1;
    return new Vector2(x, y);
}

接下来就是通过OpenCV获取对应像素点的颜色

/// <summary>
/// 通过OpenCV获取像素点颜色
/// </summary>
void CheckColorForOpencv()
{
    Mat src =Imgcodecs.imread(Application.dataPath + "/Texture/TestTexture.png");
    Mat dst = new Mat(src.cols(), src.rows(), CvType.CV_8UC4);
    
    Imgproc.cvtColor(src,dst,Imgproc.COLOR_BGR2BGRA);

    double b = dst.get((int) point.y, (int) point.x)[0];
    double g = dst.get((int) point.y, (int) point.x)[1];
    double r = dst.get((int) point.y, (int) point.x)[2];
    double a = dst.get((int) point.y, (int) point.x)[3];

    color = new Color((float) r / 255, (float) g / 255, (float) b / 255, (float) a / 255);
}

在上述代码中我们注意到有一个Mat类,它是OpenCV中的一个非常最重要的类,在我们使用OpenCV处理与图像相关的操作的时候,基本上都是要用到Mat类的。它是OpenCV中保存图像数据的基本容器。它可以存储实数/复数的向量和矩阵,单色或彩色图像等。
那么如何创建Mat呢?使用的是如下

Mat mat = new Mat(行数, 列数, 类型);

image.png

就这样,基本上就能够获取到图片对应像素点的颜色。

写在最后

所有分享的内容均为作者在日常开发过程中使用过的各种小功能点,分享出来也变相的回顾一下,如有写的不好的地方还请多多指教。欢迎大家相互学习进步。本片文章就先写到这里,希望对你能够有所帮助