打开相机
显示方法
首先需要明确,目前看到的显示图片有两种方法,一种是渲染到实际的gameobject上面去,另一种是draw到GUI上面去。关于gameobject在上一个显示图片里面有了大致的了解。这里主要说的内容包括
- 相机显示的必备步骤
- 关于GUI
- 关于renderer
相机内容显示
- 在unity中,有一个专门的类叫做WebCamTexture,我们需要为读取进来的相机texture创建一个新的对象。一般来说,需要三个部分,相机纹理,相机名字(string)以及相机是否打开(bool)
start部分
- 在这部分,我们首先需要把创建的cameraTexture实例化
- 其次,我们需要调用
StartCoroutine
函数,在其中调用测试函数来确定相机是否打开
StartCoroutine
- 在一般的执行里面,unity是逐帧运行的,所以当操作花费时间的时候,帧率下降,就会发生卡顿
- 这部分开始了一个协程(Coroutine),使用yield,可以在任何部分暂停这个Coroutine的执行。如果被成功暂停,它会在下一帧恢复正常。所以这个方法在多帧运行之中非常好用。
- unity会假装开辟一个新线程来执行,但是不会影响主线程的持续效果
- 参考
- 从这里的功能来说,yield会检查用户有没有授权,如果没有授权的话,运行被终止,跳到下一帧。如果授权成功了的话,运行成功,相机打开。
IEnumerator
- 在StartCoroutine调用的是一个IEnumerator函数,他通过yield一个bool来决定是不是继续运行这个函数
授权
- 在test里面需要考虑有没有用户的授权
- 有授权的情况下,需要把目前的WebCamTexture(注意这里不是建立的实例)的device的数据传递给
WebCamDevice
,包括类型,名字等等。 - 然后需要把包括这个相机名字,size和fps的信息传给之前cameraTexture的实例
- 以上都设定好之后,
WebCamTexture.Play
会激活这个相机,让他开始工作 - 然后再讲相机的texture渲染到object的表面上
1
2
3
4
5
6
7
8
9
10yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
if(Application.HasUserAuthorization(UserAuthorization.WebCam))
{
WebCamDevice[] devices = WebCamTexture.devices;
cameraName = devices[0].name;
cameraTexture = new WebCamTexture(cameraName, 1024, 768, 15);
cameraTexture.Play();
isOpen = true;
renderer.material.mainTexture = cameraTexture;
}
GUI
- GUI主要是提供了图形化的窗口,实际上显示的元素是直接显示在game画面上的,也就是说这部分是和实际相机拍摄到的画面独立的。无论相机如何移动,物体如何改变,最终GUI的画面都会显示到同样的地方
MonoBehaviour.OnGUI()
- 注意OnGUI函数并不需要我们自己去调用,不需要再update里面调用!
- OnGUI是API里面自带的函数,我们需要在这个函数中渲染和处理GUI的event
- 在实际应用中,OnGUI可能每一个frame被call很多次,每次event(例如鼠标操作,键盘等等)发生的时候都会call这个函数
- 例如下面官方的例子,每次鼠标点击的时候,就会print出相应的话来
1
2
3
4
5
6
7
8
9
10
11
12
13using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
void OnGUI()
{
if (GUI.Button(new Rect(10, 10, 150, 100), "I am a button"))
{
print("You clicked the button!");
}
}
}
GUI.DrawTexture
- 在GUI的实现中,我们需要将相机读取到的部分draw的GUI的上面,所以调用了这个函数
- 需要确定的参数包括:位置,需要渲染的texture,缩放比例等等
实现
- 代码部分参考
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class showCamera : MonoBehaviour
{
protected WebCamTexture cameraTexture;
protected string cameraName = "";
protected bool isOpen = false;
//protected MeshRenderer renderer;
// Start is called before the first frame update
void Start()
{
//renderer = this.GetComponent<MeshRenderer>();
cameraTexture = new WebCamTexture();
StartCoroutine(Test());
}
// Update is called once per frame
void Update()
{
}
IEnumerator Test()
{
yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
if(Application.HasUserAuthorization(UserAuthorization.WebCam))
{
WebCamDevice[] devices = WebCamTexture.devices;
cameraName = devices[0].name;
cameraTexture = new WebCamTexture(cameraName, 1024, 768, 15);
cameraTexture.Play();
isOpen = true;
//renderer.material.mainTexture = cameraTexture;
}
}
void OnGUI()
{
if(isOpen)
{
GUI.DrawTexture(new Rect(0, 0, 400, 300), cameraTexture, ScaleMode.ScaleToFit);
}
}
}
渲染到object上面
- 和之前的操作类似,需要
- 构建MeshRenderer的object
- 在start里面读取出物体的MeshRenderer(getcomponent)
- 最后打开相机后,把相机的内容渲染到MeshRenderer上面
1 | using System.Collections; |
将图片放入opencv
- 得到了web的texture之后,可以直接用openCV的部分把这个玩意转换成mat,然后处理
- 这里的问题是刚开始mat的大小莫名其妙的是16,所以需要加上一个判断条件
1 | using System.Collections; |