This commit is contained in:
EnoxSoftware 2019-01-18 04:58:21 +09:00
Родитель c71b4a68f5
Коммит 4587fd7431
38 изменённых файлов: 1485 добавлений и 2484 удалений

Просмотреть файл

@ -4,9 +4,9 @@ using System.Collections.Generic;
namespace FaceMaskExample
{
[CustomEditor(typeof(FaceMaskData))]
[CustomEditor (typeof(FaceMaskData))]
public class FaceMaskDataEditor : Editor
{
{
SerializedProperty image;
SerializedProperty isDynamicMode;
SerializedProperty enableColorCorrection;
@ -16,25 +16,24 @@ namespace FaceMaskExample
bool isDrag = false;
int currentPointID = -1;
private void OnEnable()
private void OnEnable ()
{
image = serializedObject.FindProperty("_image");
isDynamicMode = serializedObject.FindProperty("isDynamicMode");
enableColorCorrection = serializedObject.FindProperty("enableColorCorrection");
faceRect = serializedObject.FindProperty("_faceRect");
landmarkPoints = serializedObject.FindProperty("_landmarkPoints");
image = serializedObject.FindProperty ("_image");
isDynamicMode = serializedObject.FindProperty ("isDynamicMode");
enableColorCorrection = serializedObject.FindProperty ("enableColorCorrection");
faceRect = serializedObject.FindProperty ("_faceRect");
landmarkPoints = serializedObject.FindProperty ("_landmarkPoints");
}
public override void OnInspectorGUI()
public override void OnInspectorGUI ()
{
serializedObject.Update();
serializedObject.Update ();
Texture2D tex = image.objectReferenceValue as Texture2D;
// Draw image.
if (tex != null)
{
GUILayout.Box(GUIContent.none, GUILayout.Width(tex.width), GUILayout.Height(tex.height));
if (tex != null) {
GUILayout.Box (GUIContent.none, GUILayout.Width (tex.width), GUILayout.Height (tex.height));
Rect imageRect = GUILayoutUtility.GetLastRect ();
GUI.DrawTexture (imageRect, tex);
@ -106,20 +105,21 @@ namespace FaceMaskExample
}
// Display input field.
EditorGUILayout.PropertyField(image);
EditorGUILayout.PropertyField(isDynamicMode);
EditorGUILayout.PropertyField(enableColorCorrection);
EditorGUILayout.PropertyField(faceRect);
EditorGUILayout.PropertyField(landmarkPoints, true);
EditorGUILayout.PropertyField (image);
EditorGUILayout.PropertyField (isDynamicMode);
EditorGUILayout.PropertyField (enableColorCorrection);
EditorGUILayout.PropertyField (faceRect);
EditorGUILayout.PropertyField (landmarkPoints, true);
serializedObject.ApplyModifiedProperties();
serializedObject.ApplyModifiedProperties ();
}
private void DrawFaceRect (Rect imageRect, Rect faceRect, Color color)
{
faceRect.x += imageRect.x; faceRect.y += imageRect.y;
faceRect.x += imageRect.x;
faceRect.y += imageRect.y;
Handles.color = color;
Handles.DrawSolidRectangleWithOutline(faceRect, new Color(0, 0, 0, 0), Color.white);
Handles.DrawSolidRectangleWithOutline (faceRect, new Color (0, 0, 0, 0), Color.white);
}
private void DrawFaceLandmark (Rect imageRect, SerializedProperty landmarkPoints, Color lineColor, Color pointColor)
@ -129,49 +129,52 @@ namespace FaceMaskExample
Handles.color = lineColor;
for (int i = 1; i <= 16; ++i)
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
for (int i = 28; i <= 30; ++i)
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
for (int i = 18; i <= 21; ++i)
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
for (int i = 23; i <= 26; ++i)
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
for (int i = 31; i <= 35; ++i)
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(30).vector2Value, landmarkPoints.GetArrayElementAtIndex(35).vector2Value);
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (30).vector2Value, landmarkPoints.GetArrayElementAtIndex (35).vector2Value);
for (int i = 37; i <= 41; ++i)
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(36).vector2Value, landmarkPoints.GetArrayElementAtIndex(41).vector2Value);
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (36).vector2Value, landmarkPoints.GetArrayElementAtIndex (41).vector2Value);
for (int i = 43; i <= 47; ++i)
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(42).vector2Value, landmarkPoints.GetArrayElementAtIndex(47).vector2Value);
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (42).vector2Value, landmarkPoints.GetArrayElementAtIndex (47).vector2Value);
for (int i = 49; i <= 59; ++i)
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(48).vector2Value, landmarkPoints.GetArrayElementAtIndex(59).vector2Value);
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (48).vector2Value, landmarkPoints.GetArrayElementAtIndex (59).vector2Value);
for (int i = 61; i <= 67; ++i)
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(60).vector2Value, landmarkPoints.GetArrayElementAtIndex(67).vector2Value);
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (60).vector2Value, landmarkPoints.GetArrayElementAtIndex (67).vector2Value);
// Draw Points.
Handles.color = pointColor;
for (int i = 0; i < landmarkPoints.arraySize; i++) {
Vector2 pt = landmarkPoints.GetArrayElementAtIndex(i).vector2Value;
pt.x += imageRect.x; pt.y += imageRect.y;
Handles.DrawSolidDisc(pt, Vector3.forward, 2f);
Vector2 pt = landmarkPoints.GetArrayElementAtIndex (i).vector2Value;
pt.x += imageRect.x;
pt.y += imageRect.y;
Handles.DrawSolidDisc (pt, Vector3.forward, 2f);
}
}
}
private void DrawLine (Rect imageRect, Vector2 pt1, Vector2 pt2)
{
pt1.x += imageRect.x; pt1.y += imageRect.y;
pt2.x += imageRect.x; pt2.y += imageRect.y;
pt1.x += imageRect.x;
pt1.y += imageRect.y;
pt2.x += imageRect.x;
pt2.y += imageRect.y;
Handles.DrawLine (pt1, pt2);
}
@ -179,9 +182,10 @@ namespace FaceMaskExample
{
if (landmarkPoints.isArray && landmarkPoints.arraySize == 68) {
for (int i = 0; i < landmarkPoints.arraySize; i++) {
Vector2 pt = landmarkPoints.GetArrayElementAtIndex(i).vector2Value;
pt.x += imageRect.x; pt.y += imageRect.y;
if (rect.Contains(pt))
Vector2 pt = landmarkPoints.GetArrayElementAtIndex (i).vector2Value;
pt.x += imageRect.x;
pt.y += imageRect.y;
if (rect.Contains (pt))
return i;
}

Просмотреть файл

@ -1,12 +1,11 @@
#if UNITY_5 || UNITY_5_3_OR_NEWER
using UnityEngine;
using UnityEditor;
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System;
namespace FaceMaskExample
{
@ -15,17 +14,17 @@ namespace FaceMaskExample
/// <summary>
/// Create face mask tracked mesh prefab.
/// </summary>
[MenuItem("Tools/Face Mask Example/Create Face Mask Prefab")]
[MenuItem ("Tools/Face Mask Example/Create Face Mask Prefab")]
private static void CreateFaceMaskPrefab ()
{
float width = 512f;
float height = 512f;
string basePath = "Assets/FaceMaskExample/FaceMaskPrefab/";
GameObject newObj = new GameObject("FaceMaskTrackedMesh");
GameObject newObj = new GameObject ("FaceMaskTrackedMesh");
//Add MeshFilter Component.
MeshFilter meshFilter = newObj.AddComponent<MeshFilter>();
MeshFilter meshFilter = newObj.AddComponent<MeshFilter> ();
// Create Mesh.
meshFilter.mesh = new Mesh ();
@ -33,230 +32,230 @@ namespace FaceMaskExample
mesh.name = "DlibFaceLandmark68Mesh";
// Mesh_vertices
Vector3[] vertices = new Vector3[68]{
new Vector3(117, 250),
new Vector3(124, 291),
new Vector3(131, 330),
new Vector3(136, 369),
new Vector3(146, 404),
new Vector3(167, 433),
new Vector3(192, 459),
new Vector3(222, 480),
new Vector3(261, 485),
new Vector3(300, 478),
Vector3[] vertices = new Vector3[68] {
new Vector3 (117, 250),
new Vector3 (124, 291),
new Vector3 (131, 330),
new Vector3 (136, 369),
new Vector3 (146, 404),
new Vector3 (167, 433),
new Vector3 (192, 459),
new Vector3 (222, 480),
new Vector3 (261, 485),
new Vector3 (300, 478),
new Vector3(328, 453),
new Vector3(353, 425),
new Vector3(372, 394),
new Vector3(383, 357),
new Vector3(387, 319),
new Vector3(392, 281),
new Vector3(397, 241),
new Vector3(135, 224),
new Vector3(151, 205),
new Vector3(175, 196),
new Vector3 (328, 453),
new Vector3 (353, 425),
new Vector3 (372, 394),
new Vector3 (383, 357),
new Vector3 (387, 319),
new Vector3 (392, 281),
new Vector3 (397, 241),
new Vector3 (135, 224),
new Vector3 (151, 205),
new Vector3 (175, 196),
new Vector3(202, 192),
new Vector3 (202, 192),
//22^23
new Vector3(228, 205), //new Vector3(228, 197), y+10
new Vector3(281, 205), //new Vector3(281, 197), y+10
new Vector3 (228, 205), //new Vector3(228, 197), y+10
new Vector3 (281, 205), //new Vector3(281, 197), y+10
new Vector3(308, 191),
new Vector3(334, 195),
new Vector3(358, 205),
new Vector3(374, 222),
new Vector3(255, 228),
new Vector3(256, 254),
new Vector3(257, 279),
new Vector3 (308, 191),
new Vector3 (334, 195),
new Vector3 (358, 205),
new Vector3 (374, 222),
new Vector3 (255, 228),
new Vector3 (256, 254),
new Vector3 (257, 279),
new Vector3(258, 306),
new Vector3(230, 322),
new Vector3(243, 325),
new Vector3(259, 329),
new Vector3(274, 324),
new Vector3(288, 320),
new Vector3(168, 237),
new Vector3(182, 229),
new Vector3(200, 229),
new Vector3(214, 239),
new Vector3 (258, 306),
new Vector3 (230, 322),
new Vector3 (243, 325),
new Vector3 (259, 329),
new Vector3 (274, 324),
new Vector3 (288, 320),
new Vector3 (168, 237),
new Vector3 (182, 229),
new Vector3 (200, 229),
new Vector3 (214, 239),
new Vector3(199, 241),
new Vector3(182, 242),
new Vector3(296, 238),
new Vector3(310, 228),
new Vector3(327, 228),
new Vector3(341, 235),
new Vector3(328, 240),
new Vector3(311, 240),
new Vector3 (199, 241),
new Vector3 (182, 242),
new Vector3 (296, 238),
new Vector3 (310, 228),
new Vector3 (327, 228),
new Vector3 (341, 235),
new Vector3 (328, 240),
new Vector3 (311, 240),
//49
new Vector3(198, 372), //new Vector3(198, 367), y+5
new Vector3 (198, 372), //new Vector3(198, 367), y+5
new Vector3(219, 360),
new Vector3 (219, 360),
new Vector3(242, 357),
new Vector3(261, 360),
new Vector3(280, 357),
new Vector3(301, 357),
new Vector3 (242, 357),
new Vector3 (261, 360),
new Vector3 (280, 357),
new Vector3 (301, 357),
//55
new Vector3(322, 367), //new Vector3(322, 362), y+5
new Vector3 (322, 367), //new Vector3(322, 362), y+5
new Vector3(303, 387),
new Vector3(282, 396),
new Vector3(261, 398),
new Vector3(241, 396),
new Vector3(218, 388),
new Vector3 (303, 387),
new Vector3 (282, 396),
new Vector3 (261, 398),
new Vector3 (241, 396),
new Vector3 (218, 388),
//61^65
new Vector3(205, 373), //new Vector3(205, 368), y+5
new Vector3(242, 371), //new Vector3(242, 366), y+5
new Vector3(261, 373), //new Vector3(261, 368), y+5
new Vector3(280, 370), //new Vector3(280, 365), y+5
new Vector3(314, 368), //new Vector3(314, 363) y+5
new Vector3 (205, 373), //new Vector3(205, 368), y+5
new Vector3 (242, 371), //new Vector3(242, 366), y+5
new Vector3 (261, 373), //new Vector3(261, 368), y+5
new Vector3 (280, 370), //new Vector3(280, 365), y+5
new Vector3 (314, 368), //new Vector3(314, 363) y+5
new Vector3(281, 382),
new Vector3(261, 384),
new Vector3(242, 383)
new Vector3 (281, 382),
new Vector3 (261, 384),
new Vector3 (242, 383)
};
Vector3[] vertices2 = (Vector3[])vertices.Clone();
Vector3[] vertices2 = (Vector3[])vertices.Clone ();
for (int j = 0; j < vertices2.Length; j++) {
vertices2 [j].x = (vertices2 [j].x - width/2f) / width;
vertices2 [j].y = (height/2f - vertices2 [j].y) / height;
vertices2 [j].x = (vertices2 [j].x - width / 2f) / width;
vertices2 [j].y = (height / 2f - vertices2 [j].y) / height;
}
mesh.vertices = vertices2;
// Mesh_triangles
int[] triangles = new int[327]{
int[] triangles = new int[327] {
// Around the right eye 21
0,36,1,
1,36,41,
1,41,31,
41,40,31,
40,29,31,
40,39,29,
39,28,29,
39,27,28,
39,21,27,
38,21,39,
20,21,38,
37,20,38,
37,19,20,
18,19,37,
18,37,36,
17,18,36,
0,17,36,
0, 36, 1,
1, 36, 41,
1, 41, 31,
41, 40, 31,
40, 29, 31,
40, 39, 29,
39, 28, 29,
39, 27, 28,
39, 21, 27,
38, 21, 39,
20, 21, 38,
37, 20, 38,
37, 19, 20,
18, 19, 37,
18, 37, 36,
17, 18, 36,
0, 17, 36,
// (inner right eye 4)
36,37,41,
37,40,41,
37,38,40,
38,39,40,
36, 37, 41,
37, 40, 41,
37, 38, 40,
38, 39, 40,
// Around the left eye 21
45,16,15,
46,45,15,
46,15,35,
47,46,35,
29,47,35,
42,47,29,
28,42,29,
27,42,28,
27,22,42,
22,43,42,
22,23,43,
23,44,43,
23,24,44,
24,25,44,
44,25,45,
25,26,45,
45,26,16,
45, 16, 15,
46, 45, 15,
46, 15, 35,
47, 46, 35,
29, 47, 35,
42, 47, 29,
28, 42, 29,
27, 42, 28,
27, 22, 42,
22, 43, 42,
22, 23, 43,
23, 44, 43,
23, 24, 44,
24, 25, 44,
44, 25, 45,
25, 26, 45,
45, 26, 16,
// (inner left eye 4)
44,45,46,
47,44,46,
43,44,47,
42,43,47,
44, 45, 46,
47, 44, 46,
43, 44, 47,
42, 43, 47,
// Eyebrows, nose and cheeks 13
20,23,21,
21,23,22,
21,22,27,
29,30,31,
29,35,30,
30,32,31,
30,33,32,
30,34,33,
30,35,34,
1,31,2,
2,31,3,
35,15,14,
35,14,13,
20, 23, 21,
21, 23, 22,
21, 22, 27,
29, 30, 31,
29, 35, 30,
30, 32, 31,
30, 33, 32,
30, 34, 33,
30, 35, 34,
1, 31, 2,
2, 31, 3,
35, 15, 14,
35, 14, 13,
// mouth 48
33,51,50,
32,33,50,
31,32,50,
31,50,49,
31,49,48,
3,31,48,
3,48,4,
4,48,5,
48,59,5,
5,59,6,
59,58,6,
58,7,6,
58,57,7,
57,8,7,
57,9,8,
57,56,9,
56,10,9,
56,55,10,
55,11,10,
55,54,11,
54,12,11,
54,13,12,
35,13,54,
35,54,53,
35,53,52,
34,35,52,
33,34,52,
33,52,51,
33, 51, 50,
32, 33, 50,
31, 32, 50,
31, 50, 49,
31, 49, 48,
3, 31, 48,
3, 48, 4,
4, 48, 5,
48, 59, 5,
5, 59, 6,
59, 58, 6,
58, 7, 6,
58, 57, 7,
57, 8, 7,
57, 9, 8,
57, 56, 9,
56, 10, 9,
56, 55, 10,
55, 11, 10,
55, 54, 11,
54, 12, 11,
54, 13, 12,
35, 13, 54,
35, 54, 53,
35, 53, 52,
34, 35, 52,
33, 34, 52,
33, 52, 51,
48,49,60,
48,60,59,
49,50,61,
49,61,60,
60,67,59,
59,67,58,
50,51,61,
51,62,61,
67,66,58,
66,57,58,
51,52,63,
51,63,62,
66,65,56,
66,56,57,
52,53,63,
53,64,63,
65,64,55,
65,55,56,
53,54,64,
64,54,55,
48, 49, 60,
48, 60, 59,
49, 50, 61,
49, 61, 60,
60, 67, 59,
59, 67, 58,
50, 51, 61,
51, 62, 61,
67, 66, 58,
66, 57, 58,
51, 52, 63,
51, 63, 62,
66, 65, 56,
66, 56, 57,
52, 53, 63,
53, 64, 63,
65, 64, 55,
65, 55, 56,
53, 54, 64,
64, 54, 55,
// inner mouth 6
60,61,67,
61,62,67,
62,66,67,
62,63,65,
62,65,66,
63,64,65
60, 61, 67,
61, 62, 67,
62, 66, 67,
62, 63, 65,
62, 65, 66,
63, 64, 65
};
mesh.triangles = triangles;
// Mesh_uv
Vector2[] uv = new Vector2[68];
for (int j = 0; j < uv.Length; j++) {
uv [j].x = vertices[j].x / width;
uv [j].y = (height - vertices[j].y) / height;
uv [j].x = vertices [j].x / width;
uv [j].y = (height - vertices [j].y) / height;
}
mesh.uv = uv;
mesh.uv2 = (Vector2[])uv.Clone ();
@ -264,40 +263,40 @@ namespace FaceMaskExample
mesh.RecalculateNormals ();
// Add Collider Component.
MeshCollider meshCollider = newObj.AddComponent<MeshCollider>();
MeshCollider meshCollider = newObj.AddComponent<MeshCollider> ();
meshCollider.sharedMesh = CreatePrimitiveQuadMesh ();
// Add Renderer Component.
MeshRenderer meshRenderer = newObj.AddComponent<MeshRenderer>();
Material material = new Material(Shader.Find("Hide/FaceMaskShader"));
MeshRenderer meshRenderer = newObj.AddComponent<MeshRenderer> ();
Material material = new Material (Shader.Find ("Hide/FaceMaskShader"));
// Create alpha mask texture.
Vector2[] facialContourUVPoints = new Vector2[]{
uv[0],
uv[1],
uv[2],
uv[3],
uv[4],
uv[5],
uv[6],
uv[7],
uv[8],
uv[9],
uv[10],
uv[11],
uv[12],
uv[13],
uv[14],
uv[15],
uv[16],
uv[26],
uv[25],
uv[24],
uv[23],
uv[20],
uv[19],
uv[18],
uv[17]
Vector2[] facialContourUVPoints = new Vector2[] {
uv [0],
uv [1],
uv [2],
uv [3],
uv [4],
uv [5],
uv [6],
uv [7],
uv [8],
uv [9],
uv [10],
uv [11],
uv [12],
uv [13],
uv [14],
uv [15],
uv [16],
uv [26],
uv [25],
uv [24],
uv [23],
uv [20],
uv [19],
uv [18],
uv [17]
};
/*
@ -320,20 +319,20 @@ namespace FaceMaskExample
};
*/
Vector2[] mouthContourUVPoints = new Vector2[]{
uv[60],
uv[61],
uv[62],
uv[63],
uv[64],
uv[65],
uv[66],
uv[67]
Vector2[] mouthContourUVPoints = new Vector2[] {
uv [60],
uv [61],
uv [62],
uv [63],
uv [64],
uv [65],
uv [66],
uv [67]
};
Texture2D alphaMaskTexture = AlphaMaskTextureCreater.CreateAlphaMaskTexture (width, height, facialContourUVPoints, /*rightEyeContourUVPoints, leftEyeContourUVPoints,*/ mouthContourUVPoints);
Texture2D alphaMaskTexture = AlphaMaskTextureCreater.CreateAlphaMaskTexture (width, height, facialContourUVPoints, /*rightEyeContourUVPoints, leftEyeContourUVPoints,*/mouthContourUVPoints);
string alphaMaskTexturePath = basePath + "FaceMaskAlphaMask.png";
byte [] pngData = alphaMaskTexture.EncodeToPNG();
byte[] pngData = alphaMaskTexture.EncodeToPNG ();
if (CreateWithoutFolder (basePath)) {
File.WriteAllBytes (alphaMaskTexturePath, pngData);
@ -346,18 +345,18 @@ namespace FaceMaskExample
importer.mipmapEnabled = false;
importer.wrapMode = TextureWrapMode.Clamp;
importer.maxTextureSize = 1024;
importer.textureFormat = TextureImporterFormat.RGBA16;
// importer.textureFormat = TextureImporterFormat.RGBA16;
EditorUtility.SetDirty (importer);
AssetDatabase.ImportAsset (alphaMaskTexturePath, ImportAssetOptions.ForceUpdate);
AssetDatabase.SaveAssets ();
GameObject.DestroyImmediate (alphaMaskTexture);
alphaMaskTexture = AssetDatabase.LoadAssetAtPath(alphaMaskTexturePath, typeof(Texture2D)) as Texture2D;
alphaMaskTexture = AssetDatabase.LoadAssetAtPath (alphaMaskTexturePath, typeof(Texture2D)) as Texture2D;
material.SetTexture ("_MaskTex", alphaMaskTexture);
meshRenderer.material = material;
// Add TracedMesh Compornent.
newObj.AddComponent<TrackedMesh>();
newObj.AddComponent<TrackedMesh> ();
// Save FaceMask Assets.
if (CreateWithoutFolder (basePath)) {
@ -365,10 +364,10 @@ namespace FaceMaskExample
AssetDatabase.CreateAsset (mesh, basePath + "DlibFaceLandmark68Mesh.asset");
AssetDatabase.SaveAssets ();
UnityEngine.Object prefab = AssetDatabase.LoadAssetAtPath(basePath + "FaceMaskTrackedMesh.prefab", typeof(UnityEngine.Object));
if (prefab == null){
UnityEngine.Object prefab = AssetDatabase.LoadAssetAtPath (basePath + "FaceMaskTrackedMesh.prefab", typeof(UnityEngine.Object));
if (prefab == null) {
UnityEditor.PrefabUtility.CreatePrefab (basePath + "FaceMaskTrackedMesh.prefab", newObj);
}else{
} else {
UnityEditor.PrefabUtility.ReplacePrefab (newObj, prefab);
}
AssetDatabase.SaveAssets ();
@ -377,31 +376,32 @@ namespace FaceMaskExample
GameObject.DestroyImmediate (newObj);
}
private static Mesh CreatePrimitiveQuadMesh()
private static Mesh CreatePrimitiveQuadMesh ()
{
GameObject gameObject = GameObject.CreatePrimitive(PrimitiveType.Quad);
Mesh mesh = gameObject.GetComponent<MeshFilter>().sharedMesh;
GameObject.DestroyImmediate(gameObject);
GameObject gameObject = GameObject.CreatePrimitive (PrimitiveType.Quad);
Mesh mesh = gameObject.GetComponent<MeshFilter> ().sharedMesh;
GameObject.DestroyImmediate (gameObject);
return mesh;
}
private static bool CreateWithoutFolder( string filename )
private static bool CreateWithoutFolder (string filename)
{
string directory = Path.GetDirectoryName(filename);
string directory = Path.GetDirectoryName (filename);
if (Directory.Exists (directory + "/") == true) return true;
if (Directory.Exists (directory + "/") == true)
return true;
string[] values = directory.Split( new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries );
string[] values = directory.Split (new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
string checkFolder = string.Empty;
foreach( var folder in values ) {
foreach (var folder in values) {
string baseFolder = checkFolder;
if(!string.IsNullOrEmpty(checkFolder)){
baseFolder = Path.GetDirectoryName(checkFolder);
if (!string.IsNullOrEmpty (checkFolder)) {
baseFolder = Path.GetDirectoryName (checkFolder);
}
checkFolder += folder;
if (System.IO.Directory.Exists(checkFolder + "/") != true) {
UnityEditor.AssetDatabase.CreateFolder( baseFolder, folder );
if (System.IO.Directory.Exists (checkFolder + "/") != true) {
UnityEditor.AssetDatabase.CreateFolder (baseFolder, folder);
}
checkFolder += "/";
}

Просмотреть файл

@ -1,15 +1,13 @@
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
#endif
using UnityEngine.UI;
using OpenCVForUnity.CoreModule;
namespace FaceMaskExample
{
/// <summary>
/// Face mask example.
/// FaceMask Example
/// </summary>
public class FaceMaskExample : MonoBehaviour
{
@ -23,8 +21,8 @@ namespace FaceMaskExample
{
exampleTitle.text = "FaceMask Example " + Application.version;
versionInfo.text = OpenCVForUnity.Core.NATIVE_LIBRARY_NAME + " " + OpenCVForUnity.Utils.getVersion () + " (" + OpenCVForUnity.Core.VERSION + ")";
versionInfo.text += " / " + "dlibfacelandmarkdetector" + " " + DlibFaceLandmarkDetector.Utils.getVersion ();
versionInfo.text = Core.NATIVE_LIBRARY_NAME + " " + OpenCVForUnity.UnityUtils.Utils.getVersion () + " (" + Core.VERSION + ")";
versionInfo.text += " / " + "dlibfacelandmarkdetector" + " " + DlibFaceLandmarkDetector.UnityUtils.Utils.getVersion ();
versionInfo.text += " / UnityEditor " + Application.unityVersion;
versionInfo.text += " / ";
@ -45,9 +43,9 @@ namespace FaceMaskExample
#elif UNITY_WEBGL
versionInfo.text += "WebGL";
#endif
versionInfo.text += " ";
versionInfo.text += " ";
#if ENABLE_MONO
versionInfo.text += "Mono";
versionInfo.text += "Mono";
#elif ENABLE_IL2CPP
versionInfo.text += "IL2CPP";
#elif ENABLE_DOTNET
@ -71,47 +69,27 @@ namespace FaceMaskExample
public void OnShowLicenseButtonClick ()
{
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
SceneManager.LoadScene ("ShowLicense");
#else
Application.LoadLevel ("ShowLicense");
#endif
}
public void OnTexture2DFaceMaskExampleButtonClick ()
{
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
SceneManager.LoadScene ("Texture2DFaceMaskExample");
#else
Application.LoadLevel ("Texture2DFaceMaskExample");
#endif
}
public void OnVideoCaptureFaceMaskExampleButtonClick ()
{
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
SceneManager.LoadScene ("VideoCaptureFaceMaskExample");
#else
Application.LoadLevel ("VideoCaptureFaceMaskExample");
#endif
}
public void OnWebCamTextureFaceMaskExampleButtonClick ()
{
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
SceneManager.LoadScene ("WebCamTextureFaceMaskExample");
#else
Application.LoadLevel ("WebCamTextureFaceMaskExample");
#endif
}
public void OnWebCamTextureFaceMaskAdditionalExampleButtonClick ()
{
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
SceneManager.LoadScene ("WebCamTextureFaceMaskAdditionalExample");
#else
Application.LoadLevel ("WebCamTextureFaceMaskAdditionalExample");
#endif
}
}
}

Просмотреть файл

@ -1,19 +1,19 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
SceneSettings:
OcclusionCullingSettings:
m_ObjectHideFlags: 0
m_PVSData:
m_PVSObjectsArray: []
m_PVSPortalsArray: []
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 6
serializedVersion: 8
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
@ -25,6 +25,7 @@ RenderSettings:
m_AmbientGroundColor: {r: 0.2, g: 0.2, b: 0.2, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 3
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
@ -37,12 +38,12 @@ RenderSettings:
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
--- !u!157 &4
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 6
serializedVersion: 9
m_GIWorkflowMode: 1
m_LightmapsMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
@ -53,51 +54,75 @@ LightmapSettings:
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 3
serializedVersion: 8
m_Resolution: 1
m_BakeResolution: 50
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AO: 0
m_AOMaxDistance: 1
m_Padding: 2
m_CompAOExponent: 0
m_CompAOExponentDirect: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 0
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 1024
m_ReflectionCompression: 2
m_MixedBakeMode: 1
m_BakeBackend: 0
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVRFilteringMode: 0
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_LightingDataAsset: {fileID: 0}
m_RuntimeCPUUsage: 25
m_ShadowMaskMode: 2
--- !u!196 &5
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
accuratePlacement: 0
minRegionArea: 2
cellSize: 0.16666666
manualCellSize: 0
cellSize: 0.16666666
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &96283524
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 4: {fileID: 96283530}
- 20: {fileID: 96283529}
- 92: {fileID: 96283528}
- 124: {fileID: 96283527}
- 81: {fileID: 96283526}
- 114: {fileID: 96283525}
- component: {fileID: 96283530}
- component: {fileID: 96283529}
- component: {fileID: 96283528}
- component: {fileID: 96283527}
- component: {fileID: 96283526}
- component: {fileID: 96283525}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
@ -170,6 +195,8 @@ Camera:
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_AllowMSAA: 1
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
@ -183,21 +210,21 @@ Transform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &235587655
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100058, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 235587656}
- 222: {fileID: 235587659}
- 114: {fileID: 235587658}
- 114: {fileID: 235587657}
- component: {fileID: 235587656}
- component: {fileID: 235587659}
- component: {fileID: 235587658}
- component: {fileID: 235587657}
m_Layer: 5
m_Name: Scrollbar
m_TagString: Untagged
@ -215,11 +242,11 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 707767033}
m_Father: {fileID: 537841981}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: -10, y: 0}
@ -264,7 +291,7 @@ MonoBehaviour:
m_TargetGraphic: {fileID: 1039786616}
m_HandleRect: {fileID: 1039786615}
m_Direction: 2
m_Value: 0
m_Value: 1
m_Size: 1
m_NumberOfSteps: 0
m_OnValueChanged:
@ -312,12 +339,12 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100000, guid: 1ccccd5701fc6ee48964a3c728b8ab62, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 4: {fileID: 399121681}
- 114: {fileID: 399121680}
- 114: {fileID: 399121679}
- 114: {fileID: 399121678}
- component: {fileID: 399121681}
- component: {fileID: 399121680}
- component: {fileID: 399121679}
- component: {fileID: 399121678}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
@ -381,19 +408,19 @@ Transform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &537841980
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100012, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 537841981}
- 114: {fileID: 537841982}
- component: {fileID: 537841981}
- component: {fileID: 537841982}
m_Layer: 5
m_Name: SceneList
m_TagString: Untagged
@ -411,12 +438,12 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 976017881}
- {fileID: 235587656}
m_Father: {fileID: 1661287683}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
@ -445,13 +472,13 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100078, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 542799651}
- 222: {fileID: 542799655}
- 114: {fileID: 542799654}
- 114: {fileID: 542799653}
- 114: {fileID: 542799652}
- component: {fileID: 542799651}
- component: {fileID: 542799655}
- component: {fileID: 542799654}
- component: {fileID: 542799653}
- component: {fileID: 542799652}
m_Layer: 5
m_Name: VideoCaptureFaceMaskExampleButton
m_TagString: Untagged
@ -469,11 +496,11 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 1149847639}
m_Father: {fileID: 1339781662}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
@ -591,11 +618,11 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100030, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 629095087}
- 222: {fileID: 629095089}
- 114: {fileID: 629095088}
- component: {fileID: 629095087}
- component: {fileID: 629095089}
- component: {fileID: 629095088}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
@ -613,10 +640,10 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children: []
m_Father: {fileID: 2121722087}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
@ -668,10 +695,10 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 683672276}
- 114: {fileID: 683672277}
- component: {fileID: 683672276}
- component: {fileID: 683672277}
m_Layer: 0
m_Name: Spacer
m_TagString: Untagged
@ -688,10 +715,10 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children: []
m_Father: {fileID: 1339781662}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
@ -720,9 +747,9 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100044, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 707767033}
- component: {fileID: 707767033}
m_Layer: 5
m_Name: Sliding Area
m_TagString: Untagged
@ -740,11 +767,11 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 1039786615}
m_Father: {fileID: 235587656}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
@ -755,11 +782,11 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 942732234}
- 222: {fileID: 942732236}
- 114: {fileID: 942732235}
- component: {fileID: 942732234}
- component: {fileID: 942732236}
- component: {fileID: 942732235}
m_Layer: 5
m_Name: VersionInfo
m_TagString: Untagged
@ -775,11 +802,11 @@ RectTransform:
m_GameObject: {fileID: 942732233}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1.1062992, y: 1.1062992, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1661287683}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
@ -829,13 +856,13 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100010, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 976017881}
- 114: {fileID: 976017885}
- 114: {fileID: 976017884}
- 222: {fileID: 976017883}
- 114: {fileID: 976017882}
- component: {fileID: 976017881}
- component: {fileID: 976017885}
- component: {fileID: 976017884}
- component: {fileID: 976017883}
- component: {fileID: 976017882}
m_Layer: 0
m_Name: ScrollView
m_TagString: Untagged
@ -853,11 +880,11 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 1339781662}
m_Father: {fileID: 537841981}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: -15, y: 0}
@ -948,11 +975,11 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100050, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 1020154883}
- 222: {fileID: 1020154885}
- 114: {fileID: 1020154884}
- component: {fileID: 1020154883}
- component: {fileID: 1020154885}
- component: {fileID: 1020154884}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
@ -970,10 +997,10 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children: []
m_Father: {fileID: 1088752999}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
@ -1025,11 +1052,11 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100024, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 1039786615}
- 222: {fileID: 1039786617}
- 114: {fileID: 1039786616}
- component: {fileID: 1039786615}
- component: {fileID: 1039786617}
- component: {fileID: 1039786616}
m_Layer: 5
m_Name: Handle
m_TagString: Untagged
@ -1047,10 +1074,10 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children: []
m_Father: {fileID: 707767033}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
@ -1096,13 +1123,13 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100000, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 1088752999}
- 222: {fileID: 1088753003}
- 114: {fileID: 1088753002}
- 114: {fileID: 1088753001}
- 114: {fileID: 1088753000}
- component: {fileID: 1088752999}
- component: {fileID: 1088753003}
- component: {fileID: 1088753002}
- component: {fileID: 1088753001}
- component: {fileID: 1088753000}
m_Layer: 5
m_Name: ShowLicenseButton
m_TagString: Untagged
@ -1120,11 +1147,11 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 1020154883}
m_Father: {fileID: 1339781662}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
@ -1242,11 +1269,11 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100030, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 1097508684}
- 222: {fileID: 1097508686}
- 114: {fileID: 1097508685}
- component: {fileID: 1097508684}
- component: {fileID: 1097508686}
- component: {fileID: 1097508685}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
@ -1264,10 +1291,10 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children: []
m_Father: {fileID: 1718137805}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
@ -1319,11 +1346,11 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100030, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 1149847639}
- 222: {fileID: 1149847641}
- 114: {fileID: 1149847640}
- component: {fileID: 1149847639}
- component: {fileID: 1149847641}
- component: {fileID: 1149847640}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
@ -1341,10 +1368,10 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children: []
m_Father: {fileID: 542799651}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
@ -1396,11 +1423,11 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100014, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 1266655927}
- 222: {fileID: 1266655929}
- 114: {fileID: 1266655928}
- component: {fileID: 1266655927}
- component: {fileID: 1266655929}
- component: {fileID: 1266655928}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
@ -1418,10 +1445,10 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children: []
m_Father: {fileID: 1775689014}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
@ -1473,11 +1500,11 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100064, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 1339781662}
- 114: {fileID: 1339781664}
- 114: {fileID: 1339781663}
- component: {fileID: 1339781662}
- component: {fileID: 1339781664}
- component: {fileID: 1339781663}
m_Layer: 0
m_Name: List
m_TagString: Untagged
@ -1495,7 +1522,6 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 1088752999}
- {fileID: 683672276}
@ -1505,9 +1531,10 @@ RectTransform:
- {fileID: 2121722087}
m_Father: {fileID: 976017881}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: -0.000030517578}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 1}
--- !u!114 &1339781663
@ -1531,6 +1558,8 @@ MonoBehaviour:
m_Spacing: 5
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 1
m_ChildControlHeight: 1
--- !u!114 &1339781664
MonoBehaviour:
m_ObjectHideFlags: 0
@ -1550,11 +1579,11 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 1369632058}
- 222: {fileID: 1369632057}
- 114: {fileID: 1369632056}
- component: {fileID: 1369632058}
- component: {fileID: 1369632057}
- component: {fileID: 1369632056}
m_Layer: 5
m_Name: ExampleTitle
m_TagString: Untagged
@ -1609,11 +1638,11 @@ RectTransform:
m_GameObject: {fileID: 1369632055}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1.1062992, y: 1.1062992, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1661287683}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
@ -1624,12 +1653,12 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100070, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 1488394138}
- 223: {fileID: 1488394141}
- 114: {fileID: 1488394140}
- 114: {fileID: 1488394139}
- component: {fileID: 1488394138}
- component: {fileID: 1488394141}
- component: {fileID: 1488394140}
- component: {fileID: 1488394139}
m_Layer: 5
m_Name: Canvas
m_TagString: Untagged
@ -1647,11 +1676,11 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 1661287683}
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
@ -1704,7 +1733,7 @@ Canvas:
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1488394137}
m_Enabled: 1
serializedVersion: 2
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
@ -1713,6 +1742,7 @@ Canvas:
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 25
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
@ -1721,10 +1751,10 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 1661287683}
- 114: {fileID: 1661287684}
- component: {fileID: 1661287683}
- component: {fileID: 1661287684}
m_Layer: 5
m_Name: Panel
m_TagString: Untagged
@ -1741,13 +1771,13 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 1369632058}
- {fileID: 942732234}
- {fileID: 537841981}
m_Father: {fileID: 1488394138}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
@ -1773,18 +1803,20 @@ MonoBehaviour:
m_Spacing: 10
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 1
m_ChildControlHeight: 1
--- !u!1 &1718137804
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100078, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 1718137805}
- 222: {fileID: 1718137809}
- 114: {fileID: 1718137808}
- 114: {fileID: 1718137807}
- 114: {fileID: 1718137806}
- component: {fileID: 1718137805}
- component: {fileID: 1718137809}
- component: {fileID: 1718137808}
- component: {fileID: 1718137807}
- component: {fileID: 1718137806}
m_Layer: 5
m_Name: WebCamTextureFaceMaskExampleButton
m_TagString: Untagged
@ -1802,11 +1834,11 @@ RectTransform:
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 1097508684}
m_Father: {fileID: 1339781662}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
@ -1924,13 +1956,13 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100056, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 1775689014}
- 222: {fileID: 1775689018}
- 114: {fileID: 1775689017}
- 114: {fileID: 1775689016}
- 114: {fileID: 1775689015}
- component: {fileID: 1775689014}
- component: {fileID: 1775689018}
- component: {fileID: 1775689017}
- component: {fileID: 1775689016}
- component: {fileID: 1775689015}
m_Layer: 5
m_Name: Texture2DFaceMaskExampleButton
m_TagString: Untagged
@ -1948,11 +1980,11 @@ RectTransform:
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 1266655927}
m_Father: {fileID: 1339781662}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
@ -2070,13 +2102,13 @@ GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100078, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
serializedVersion: 5
m_Component:
- 224: {fileID: 2121722087}
- 222: {fileID: 2121722091}
- 114: {fileID: 2121722090}
- 114: {fileID: 2121722089}
- 114: {fileID: 2121722088}
- component: {fileID: 2121722087}
- component: {fileID: 2121722091}
- component: {fileID: 2121722090}
- component: {fileID: 2121722089}
- component: {fileID: 2121722088}
m_Layer: 5
m_Name: WebCamTextureFaceMaskAdditionalExampleButton
m_TagString: Untagged
@ -2094,11 +2126,11 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 629095087}
m_Father: {fileID: 1339781662}
m_RootOrder: 5
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}

Просмотреть файл

@ -1,7 +1,7 @@
fileFormatVersion: 2
guid: 67f7db10ac869ee479d4495c3d7af34d
timeCreated: 1527248034
licenseType: Free
timeCreated: 1543732417
licenseType: Pro
NativeFormatImporter:
mainObjectFileID: 4300000
userData:

Просмотреть файл

@ -1,7 +1,7 @@
fileFormatVersion: 2
guid: 470faf94133e4a741bb9abe37e1dfb1f
timeCreated: 1527248034
licenseType: Free
timeCreated: 1543732416
licenseType: Pro
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
@ -24,8 +24,8 @@ TextureImporter:
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 13
maxTextureSize: 1024
textureFormat: 1
maxTextureSize: 2048
textureSettings:
filterMode: -1
aniso: -1
@ -53,7 +53,7 @@ TextureImporter:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 1024
textureFormat: -1
textureCompression: 0
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0

Просмотреть файл

@ -1,7 +1,7 @@
fileFormatVersion: 2
guid: 61fa2fcb482ca224e991e0be29d75304
timeCreated: 1527248034
licenseType: Free
timeCreated: 1543732416
licenseType: Pro
NativeFormatImporter:
mainObjectFileID: 2100000
userData:

Просмотреть файл

@ -9,20 +9,20 @@ Prefab:
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1138294731141240}
m_RootGameObject: {fileID: 1150371196015818}
m_IsPrefabParent: 1
--- !u!1 &1138294731141240
--- !u!1 &1150371196015818
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 4506640658691720}
- component: {fileID: 33613210590286308}
- component: {fileID: 64714649276791744}
- component: {fileID: 23122890318565152}
- component: {fileID: 114248784669247606}
- component: {fileID: 4046574357089060}
- component: {fileID: 33026588760814164}
- component: {fileID: 64386665923618390}
- component: {fileID: 23993217649141104}
- component: {fileID: 114013133127415782}
m_Layer: 0
m_Name: FaceMaskTrackedMesh
m_TagString: Untagged
@ -30,12 +30,12 @@ GameObject:
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &4506640658691720
--- !u!4 &4046574357089060
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1138294731141240}
m_GameObject: {fileID: 1150371196015818}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
@ -43,12 +43,12 @@ Transform:
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!23 &23122890318565152
--- !u!23 &23993217649141104
MeshRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1138294731141240}
m_GameObject: {fileID: 1150371196015818}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
@ -75,19 +75,19 @@ MeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!33 &33613210590286308
--- !u!33 &33026588760814164
MeshFilter:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1138294731141240}
m_GameObject: {fileID: 1150371196015818}
m_Mesh: {fileID: 4300000, guid: 67f7db10ac869ee479d4495c3d7af34d, type: 2}
--- !u!64 &64714649276791744
--- !u!64 &64386665923618390
MeshCollider:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1138294731141240}
m_GameObject: {fileID: 1150371196015818}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
@ -96,12 +96,12 @@ MeshCollider:
m_InflateMesh: 0
m_SkinWidth: 0.01
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
--- !u!114 &114248784669247606
--- !u!114 &114013133127415782
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1138294731141240}
m_GameObject: {fileID: 1150371196015818}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c47754ddde934e14c95f9de06ad6413d, type: 3}

Двоичные данные
Assets/FaceMaskExample/ReadMe.pdf

Двоичный файл не отображается.

Просмотреть файл

@ -2,83 +2,76 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using OpenCVForUnity.CoreModule;
using Rect = OpenCVForUnity.CoreModule.Rect;
namespace OpenCVForUnity.RectangleTrack
{
/// <summary>
/// Rectangle tracker.
/// Referring to https://github.com/Itseez/opencv/blob/master/modules/objdetect/src/detection_based_tracker.cpp.
/// v 1.0.2
/// v 1.0.3
/// </summary>
public class RectangleTracker
{
public List<TrackedObject> trackedObjects
{
public List<TrackedObject> trackedObjects {
get { return _trackedObjects; }
}
private List<TrackedObject> _trackedObjects;
public TrackerParameters trackerParameters
{
public TrackerParameters trackerParameters {
get { return _trackerParameters; }
set
{
if (value == null)
{
throw new ArgumentNullException("value");
set {
if (value == null) {
throw new ArgumentNullException ("value");
}
_trackerParameters = value;
}
}
private TrackerParameters _trackerParameters;
public List<float> weightsPositionsSmoothing
{
public List<float> weightsPositionsSmoothing {
get { return _weightsPositionsSmoothing; }
set
{
if (value == null)
{
throw new ArgumentNullException("value");
set {
if (value == null) {
throw new ArgumentNullException ("value");
}
_weightsPositionsSmoothing = value;
}
}
private List<float> _weightsPositionsSmoothing = new List<float>();
public List<float> weightsSizesSmoothing
{
private List<float> _weightsPositionsSmoothing = new List<float> ();
public List<float> weightsSizesSmoothing {
get { return _weightsSizesSmoothing; }
set
{
if (value == null)
{
throw new ArgumentNullException("value");
set {
if (value == null) {
throw new ArgumentNullException ("value");
}
_weightsSizesSmoothing = value;
}
}
private List<float> _weightsSizesSmoothing = new List<float>();
public RectangleTracker(TrackerParameters trackerParamerers = null)
private List<float> _weightsSizesSmoothing = new List<float> ();
public RectangleTracker (TrackerParameters trackerParamerers = null)
{
_trackedObjects = new List<TrackedObject>();
_trackedObjects = new List<TrackedObject> ();
if (trackerParamerers != null)
{
if (trackerParamerers != null) {
this._trackerParameters = trackerParamerers;
}
else
{
this._trackerParameters = new TrackerParameters();
} else {
this._trackerParameters = new TrackerParameters ();
}
_weightsPositionsSmoothing.Add(1);
_weightsSizesSmoothing.Add(0.5f);
_weightsSizesSmoothing.Add(0.3f);
_weightsSizesSmoothing.Add(0.2f);
_weightsPositionsSmoothing.Add (1);
_weightsSizesSmoothing.Add (0.5f);
_weightsSizesSmoothing.Add (0.3f);
_weightsSizesSmoothing.Add (0.2f);
}
public enum TrackedRectState : int
@ -88,76 +81,66 @@ namespace OpenCVForUnity.RectangleTrack
}
public void GetObjects(List<Rect> result, bool smoothing = true)
public void GetObjects (List<Rect> result, bool smoothing = true)
{
result.Clear();
result.Clear ();
int count = _trackedObjects.Count;
for (int i = 0; i < count; i++)
{
for (int i = 0; i < count; i++) {
Rect r;
if (smoothing)
{
r = GetSmoothingRect(i);
}
else
{
r = _trackedObjects[i].position;
if (smoothing) {
r = GetSmoothingRect (i);
} else {
r = _trackedObjects [i].position;
}
if (_trackedObjects[i].state > TrackedState.NEW_DISPLAYED && _trackedObjects[i].state < TrackedState.NEW_HIDED)
result.Add(r);
if (_trackedObjects [i].state > TrackedState.NEW_DISPLAYED && _trackedObjects [i].state < TrackedState.NEW_HIDED)
result.Add (r);
//LOGD("DetectionBasedTracker::process: found a object with SIZE %d x %d, rect={%d, %d, %d x %d}", r.width, r.height, r.x, r.y, r.width, r.height);
//Debug.Log("GetObjects" + r.width + " " + r.height + " " + r.x + " " + r.y + " " + r.width + " " + r.height + " " + trackedObjects[i].state + " " + trackedObjects[i].numDetectedFrames + " " + trackedObjects[i].numFramesNotDetected);
}
}
public void GetObjects(List<TrackedRect> result, bool smoothing = true)
public void GetObjects (List<TrackedRect> result, bool smoothing = true)
{
result.Clear();
result.Clear ();
int count = _trackedObjects.Count;
for (int i = 0; i < count; i++)
{
for (int i = 0; i < count; i++) {
Rect r;
if (smoothing)
{
r = GetSmoothingRect(i);
}
else
{
r = _trackedObjects[i].position;
if (smoothing) {
r = GetSmoothingRect (i);
} else {
r = _trackedObjects [i].position;
}
result.Add(new TrackedRect(_trackedObjects[i].id, r, _trackedObjects[i].state, _trackedObjects[i].numDetectedFrames, _trackedObjects[i].numFramesNotDetected));
result.Add (new TrackedRect (_trackedObjects [i].id, r, _trackedObjects [i].state, _trackedObjects [i].numDetectedFrames, _trackedObjects [i].numFramesNotDetected));
//LOGD("DetectionBasedTracker::process: found a object with SIZE %d x %d, rect={%d, %d, %d x %d}", r.width, r.height, r.x, r.y, r.width, r.height);
//Debug.Log("GetObjects" + r.width + " " + r.height + " " + r.x + " " + r.y + " " + r.width + " " + r.height + " " + trackedObjects[i].state + " " + trackedObjects[i].numDetectedFrames + " " + trackedObjects[i].numFramesNotDetected);
}
}
public void UpdateTrackedObjects(List<Rect> detectedObjects)
public void UpdateTrackedObjects (List<Rect> detectedObjects)
{
if (detectedObjects == null)
throw new ArgumentNullException("detectedObjects");
throw new ArgumentNullException ("detectedObjects");
Rect[] correctionRects = CreateCorrectionBySpeedOfRects();
Rect[] correctionRects = CreateCorrectionBySpeedOfRects ();
int N1 = (int)_trackedObjects.Count;
int N2 = (int)detectedObjects.Count;
for (int i = 0; i < N1; i++)
{
_trackedObjects[i].numDetectedFrames++;
for (int i = 0; i < N1; i++) {
_trackedObjects [i].numDetectedFrames++;
}
int[] correspondence = Enumerable.Repeat<int>((int)TrackedRectState.NEW_RECTANGLE, N2).ToArray();
int[] correspondence = Enumerable.Repeat<int> ((int)TrackedRectState.NEW_RECTANGLE, N2).ToArray ();
for (int i = 0; i < N1; i++)
{
TrackedObject curObject = _trackedObjects[i];
for (int i = 0; i < N1; i++) {
TrackedObject curObject = _trackedObjects [i];
int bestIndex = -1;
int bestArea = -1;
@ -165,101 +148,83 @@ namespace OpenCVForUnity.RectangleTrack
//int numpositions = (int)curObject.lastPositions.Count;
//if (numpositions > 0) UnityEngine.Debug.LogError("numpositions > 0 is false");
//Rect prevRect = curObject.lastPositions[numpositions - 1];
Rect prevRect = correctionRects[i];
//OpenCVRect prevRect = curObject.lastPositions[numpositions - 1];
Rect prevRect = correctionRects [i];
for (int j = 0; j < N2; j++)
{
if (correspondence[j] >= 0)
{
for (int j = 0; j < N2; j++) {
if (correspondence [j] >= 0) {
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: j=" + j + " is rejected, because it has correspondence=" + correspondence[j]);
continue;
}
if (correspondence[j] != (int)TrackedRectState.NEW_RECTANGLE)
{
if (correspondence [j] != (int)TrackedRectState.NEW_RECTANGLE) {
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: j=" + j + " is rejected, because it is intersected with another rectangle");
continue;
}
if (IsCollideByRectangle(prevRect, detectedObjects[j], _trackerParameters.coeffRectangleOverlap))
{
Rect r = Intersect(prevRect, detectedObjects[j]);
if ((r.width > 0) && (r.height > 0))
{
if (IsCollideByRectangle (prevRect, detectedObjects [j], _trackerParameters.coeffRectangleOverlap)) {
Rect r = Intersect (prevRect, detectedObjects [j]);
if ((r.width > 0) && (r.height > 0)) {
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: There is intersection between prevRect and detectedRect r={" + r.x + ", " + r.y + ", " + r.width + ", " + r.height + "]");
correspondence[j] = (int)TrackedRectState.INTERSECTED_RECTANGLE;
correspondence [j] = (int)TrackedRectState.INTERSECTED_RECTANGLE;
if (r.area() > bestArea)
{
if (r.area () > bestArea) {
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: The area of intersection is " + r.area() + " it is better than bestArea= " + bestArea);
bestIndex = j;
bestArea = (int)r.area();
bestArea = (int)r.area ();
}
}
}
}
if (bestIndex >= 0)
{
if (bestIndex >= 0) {
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: The best correspondence for i=" + i + " is j=" + bestIndex);
correspondence[bestIndex] = i;
correspondence [bestIndex] = i;
Rect bestRect = detectedObjects[bestIndex];
Rect bestRect = detectedObjects [bestIndex];
for (int j = 0; j < N2; j++)
{
if (correspondence[j] >= 0)
for (int j = 0; j < N2; j++) {
if (correspondence [j] >= 0)
continue;
if (IsCollideByRectangle(detectedObjects[j], bestRect, _trackerParameters.coeffRectangleOverlap))
{
Rect r = Intersect(detectedObjects[j], bestRect);
if (IsCollideByRectangle (detectedObjects [j], bestRect, _trackerParameters.coeffRectangleOverlap)) {
Rect r = Intersect (detectedObjects [j], bestRect);
if ((r.width > 0) && (r.height > 0))
{
if ((r.width > 0) && (r.height > 0)) {
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: Found intersection between rectangles j= " + j + " and bestIndex= " + bestIndex + " rectangle j= " + j + " is marked as intersected");
correspondence[j] = (int)TrackedRectState.INTERSECTED_RECTANGLE;
correspondence [j] = (int)TrackedRectState.INTERSECTED_RECTANGLE;
}
}
}
}
else
{
} else {
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: There is no correspondence for i= " + i);
curObject.numFramesNotDetected++;
}
}
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: start second cycle");
for (int j = 0; j < N2; j++)
{
int i = correspondence[j];
if (i >= 0)
{//add position
for (int j = 0; j < N2; j++) {
int i = correspondence [j];
if (i >= 0) {//add position
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: add position");
_trackedObjects[i].lastPositions.Add(detectedObjects[j]);
while ((int)_trackedObjects[i].lastPositions.Count > (int)_trackerParameters.numLastPositionsToTrack)
{
_trackedObjects[i].lastPositions.Remove(_trackedObjects[i].lastPositions[0]);
_trackedObjects [i].lastPositions.Add (detectedObjects [j]);
while ((int)_trackedObjects [i].lastPositions.Count > (int)_trackerParameters.numLastPositionsToTrack) {
_trackedObjects [i].lastPositions.Remove (_trackedObjects [i].lastPositions [0]);
}
_trackedObjects[i].numFramesNotDetected = 0;
if (_trackedObjects[i].state != TrackedState.DELETED) _trackedObjects[i].state = TrackedState.DISPLAYED;
}
else if (i == (int)TrackedRectState.NEW_RECTANGLE)
{ //new object
_trackedObjects [i].numFramesNotDetected = 0;
if (_trackedObjects [i].state != TrackedState.DELETED)
_trackedObjects [i].state = TrackedState.DISPLAYED;
} else if (i == (int)TrackedRectState.NEW_RECTANGLE) { //new object
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: new object");
_trackedObjects.Add(new TrackedObject(detectedObjects[j]));
}
else
{
_trackedObjects.Add (new TrackedObject (detectedObjects [j]));
} else {
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: was auxiliary intersection");
}
}
@ -267,66 +232,49 @@ namespace OpenCVForUnity.RectangleTrack
int t = 0;
TrackedObject it;
while (t < _trackedObjects.Count)
{
it = _trackedObjects[t];
while (t < _trackedObjects.Count) {
it = _trackedObjects [t];
if (it.state == TrackedState.DELETED)
{
_trackedObjects.Remove(it);
}
else if ((it.numFramesNotDetected > _trackerParameters.maxTrackLifetime)//ALL
||
((it.numDetectedFrames <= _trackerParameters.numStepsToWaitBeforeFirstShow)
&&
(it.numFramesNotDetected > _trackerParameters.numStepsToTrackWithoutDetectingIfObjectHasNotBeenShown))
)
{
if (it.state == TrackedState.DELETED) {
_trackedObjects.Remove (it);
} else if ((it.numFramesNotDetected > _trackerParameters.maxTrackLifetime)//ALL
||
((it.numDetectedFrames <= _trackerParameters.numStepsToWaitBeforeFirstShow)
&&
(it.numFramesNotDetected > _trackerParameters.numStepsToTrackWithoutDetectingIfObjectHasNotBeenShown))) {
it.state = TrackedState.DELETED;
t++;
}
else if (it.state >= TrackedState.DISPLAYED)//DISPLAYED, NEW_DISPLAYED, HIDED
{
} else if (it.state >= TrackedState.DISPLAYED) {//DISPLAYED, NEW_DISPLAYED, HIDED
if (it.numDetectedFrames < _trackerParameters.numStepsToWaitBeforeFirstShow)
{
if (it.numDetectedFrames < _trackerParameters.numStepsToWaitBeforeFirstShow) {
it.state = TrackedState.PENDING;
}
else if (it.numDetectedFrames == _trackerParameters.numStepsToWaitBeforeFirstShow)
{
} else if (it.numDetectedFrames == _trackerParameters.numStepsToWaitBeforeFirstShow) {
//i, trackedObjects[i].numDetectedFrames, innerParameters.numStepsToWaitBeforeFirstShow);
it.state = TrackedState.NEW_DISPLAYED;
}
else if (it.numFramesNotDetected == _trackerParameters.numStepsToShowWithoutDetecting)
{
} else if (it.numFramesNotDetected == _trackerParameters.numStepsToShowWithoutDetecting) {
it.state = TrackedState.NEW_HIDED;
}
else if (it.numFramesNotDetected > _trackerParameters.numStepsToShowWithoutDetecting)
{
} else if (it.numFramesNotDetected > _trackerParameters.numStepsToShowWithoutDetecting) {
it.state = TrackedState.HIDED;
}
t++;
}
else//NEW
{
} else {//NEW
t++;
}
}
}
public Rect[] CreateCorrectionBySpeedOfRects()
public Rect[] CreateCorrectionBySpeedOfRects ()
{
//Debug.Log("DetectionBasedTracker::process: get _rectsWhereRegions from previous positions");
Rect[] rectsWhereRegions = new Rect[_trackedObjects.Count];
int count = _trackedObjects.Count;
for (int i = 0; i < count; i++)
{
int n = _trackedObjects[i].lastPositions.Count;
for (int i = 0; i < count; i++) {
int n = _trackedObjects [i].lastPositions.Count;
//if (n > 0) UnityEngine.Debug.LogError("n > 0 is false");
Rect r = _trackedObjects[i].lastPositions[n - 1].clone();
Rect r = _trackedObjects [i].lastPositions [n - 1].clone ();
/*
if (r.area() == 0)
{
@ -336,127 +284,117 @@ namespace OpenCVForUnity.RectangleTrack
*/
//correction by speed of rectangle
if (n > 1)
{
Point center = CenterRect(r);
Point center_prev = CenterRect(_trackedObjects[i].lastPositions[n - 2]);
Point shift = new Point((center.x - center_prev.x) * _trackerParameters.coeffObjectSpeedUsingInPrediction,
(center.y - center_prev.y) * _trackerParameters.coeffObjectSpeedUsingInPrediction);
if (n > 1) {
Point center = CenterRect (r);
Point center_prev = CenterRect (_trackedObjects [i].lastPositions [n - 2]);
Point shift = new Point ((center.x - center_prev.x) * _trackerParameters.coeffObjectSpeedUsingInPrediction,
(center.y - center_prev.y) * _trackerParameters.coeffObjectSpeedUsingInPrediction);
r.x += (int)Math.Round(shift.x);
r.y += (int)Math.Round(shift.y);
r.x += (int)Math.Round (shift.x);
r.y += (int)Math.Round (shift.y);
}
rectsWhereRegions[i] = r;
rectsWhereRegions [i] = r;
}
return rectsWhereRegions;
}
private Point CenterRect(Rect r)
private Point CenterRect (Rect r)
{
return new Point(r.x + (r.width / 2), r.y + (r.height / 2));
return new Point (r.x + (r.width / 2), r.y + (r.height / 2));
}
private Rect GetSmoothingRect(int i)
private Rect GetSmoothingRect (int i)
{
//Debug.Log("trackedObjects[i].numFramesNotDetected: " + trackedObjects[i].numFramesNotDetected);
List<float> weightsSizesSmoothing = _weightsSizesSmoothing;
List<float> weightsPositionsSmoothing = _weightsPositionsSmoothing;
List<Rect> lastPositions = _trackedObjects[i].lastPositions;
List<Rect> lastPositions = _trackedObjects [i].lastPositions;
int N = lastPositions.Count;
if (N <= 0)
{
Debug.Log("DetectionBasedTracker::calcTrackedObjectPositionToShow: ERROR: no positions for i=" + i);
return new Rect();
if (N <= 0) {
Debug.Log ("DetectionBasedTracker::calcTrackedObjectPositionToShow: ERROR: no positions for i=" + i);
return new Rect ();
}
int Nsize = Math.Min(N, (int)weightsSizesSmoothing.Count);
int Ncenter = Math.Min(N, (int)weightsPositionsSmoothing.Count);
int Nsize = Math.Min (N, (int)weightsSizesSmoothing.Count);
int Ncenter = Math.Min (N, (int)weightsPositionsSmoothing.Count);
Point center = new Point();
Point center = new Point ();
double w = 0, h = 0;
if (Nsize > 0)
{
if (Nsize > 0) {
double sum = 0;
for (int j = 0; j < Nsize; j++)
{
for (int j = 0; j < Nsize; j++) {
int k = N - j - 1;
w += lastPositions[k].width * weightsSizesSmoothing[j];
h += lastPositions[k].height * weightsSizesSmoothing[j];
sum += weightsSizesSmoothing[j];
w += lastPositions [k].width * weightsSizesSmoothing [j];
h += lastPositions [k].height * weightsSizesSmoothing [j];
sum += weightsSizesSmoothing [j];
}
w /= sum;
h /= sum;
}
else
{
w = lastPositions[N - 1].width;
h = lastPositions[N - 1].height;
} else {
w = lastPositions [N - 1].width;
h = lastPositions [N - 1].height;
}
if (Ncenter > 0)
{
if (Ncenter > 0) {
double sum = 0;
for (int j = 0; j < Ncenter; j++)
{
for (int j = 0; j < Ncenter; j++) {
int k = N - j - 1;
Point tl = lastPositions[k].tl();
Point br = lastPositions[k].br();
Point tl = lastPositions [k].tl ();
Point br = lastPositions [k].br ();
Point c1;
c1 = new Point(tl.x * 0.5f, tl.y * 0.5f);
c1 = new Point (tl.x * 0.5f, tl.y * 0.5f);
Point c2;
c2 = new Point(br.x * 0.5f, br.y * 0.5f);
c1 = new Point(c1.x + c2.x, c1.y + c2.y);
c2 = new Point (br.x * 0.5f, br.y * 0.5f);
c1 = new Point (c1.x + c2.x, c1.y + c2.y);
center = new Point(center.x + (c1.x * weightsPositionsSmoothing[j]), center.y + (c1.y * weightsPositionsSmoothing[j]));
sum += weightsPositionsSmoothing[j];
center = new Point (center.x + (c1.x * weightsPositionsSmoothing [j]), center.y + (c1.y * weightsPositionsSmoothing [j]));
sum += weightsPositionsSmoothing [j];
}
center = new Point(center.x * (1 / sum), center.y * (1 / sum));
}
else
{
center = new Point (center.x * (1 / sum), center.y * (1 / sum));
} else {
int k = N - 1;
Point tl = lastPositions[k].tl();
Point br = lastPositions[k].br();
Point tl = lastPositions [k].tl ();
Point br = lastPositions [k].br ();
Point c1;
c1 = new Point(tl.x * 0.5f, tl.y * 0.5f);
c1 = new Point (tl.x * 0.5f, tl.y * 0.5f);
Point c2;
c2 = new Point(br.x * 0.5f, br.y * 0.5f);
c2 = new Point (br.x * 0.5f, br.y * 0.5f);
center = new Point(c1.x + c2.x, c1.y + c2.y);
center = new Point (c1.x + c2.x, c1.y + c2.y);
}
Point tl2 = new Point(center.x - (w * 0.5f), center.y - (h * 0.5f));
Rect res = new Rect((int)Math.Round(tl2.x), (int)Math.Round(tl2.y), (int)Math.Round(w), (int)Math.Round(h));
Point tl2 = new Point (center.x - (w * 0.5f), center.y - (h * 0.5f));
Rect res = new Rect ((int)Math.Round (tl2.x), (int)Math.Round (tl2.y), (int)Math.Round (w), (int)Math.Round (h));
//Debug.Log("DetectionBasedTracker::calcTrackedObjectPositionToShow: Result for i=" + i + ": {" + res.x + ", " + res.y + ", " + res.width + ", " + res.height + "}");
return res;
}
public void Reset()
public void Reset ()
{
_trackedObjects.Clear();
_trackedObjects.Clear ();
}
private Rect Intersect(Rect a, Rect b)
private Rect Intersect (Rect a, Rect b)
{
int x1 = Math.Max(a.x, b.x);
int x2 = Math.Min(a.x + a.width, b.x + b.width);
int y1 = Math.Max(a.y, b.y);
int y2 = Math.Min(a.y + a.height, b.y + b.height);
int x1 = Math.Max (a.x, b.x);
int x2 = Math.Min (a.x + a.width, b.x + b.width);
int y1 = Math.Max (a.y, b.y);
int y2 = Math.Min (a.y + a.height, b.y + b.height);
if (x2 >= x1 && y2 >= y1)
return new Rect(x1, y1, x2 - x1, y2 - y1);
return new Rect (x1, y1, x2 - x1, y2 - y1);
else
return new Rect();
return new Rect ();
}
/*
private bool IsCollideByCircle(Rect a, Rect b, float coeffRectangleOverlap)
@ -474,7 +412,7 @@ namespace OpenCVForUnity.RectangleTrack
return false;
}
*/
private bool IsCollideByRectangle(Rect a, Rect b, float coeffRectangleOverlap)
private bool IsCollideByRectangle (Rect a, Rect b, float coeffRectangleOverlap)
{
int mw = (int)(a.width * coeffRectangleOverlap);
int mh = (int)(a.height * coeffRectangleOverlap);
@ -496,9 +434,9 @@ namespace OpenCVForUnity.RectangleTrack
return false;
}
public void Dispose()
public void Dispose ()
{
Reset();
Reset ();
}
}
}

Просмотреть файл

@ -1,4 +1,5 @@
using PositionsVector = System.Collections.Generic.List<OpenCVForUnity.Rect>;
using OpenCVForUnity.CoreModule;
using PositionsVector = System.Collections.Generic.List<OpenCVForUnity.CoreModule.Rect>;
namespace OpenCVForUnity.RectangleTrack
{
@ -21,31 +22,30 @@ namespace OpenCVForUnity.RectangleTrack
public int id;
public TrackedState state;
public OpenCVForUnity.Rect position
{
get { return lastPositions [lastPositions.Count - 1].clone(); }
public Rect position {
get { return lastPositions [lastPositions.Count - 1].clone (); }
}
static private int _id = 0;
public TrackedObject(OpenCVForUnity.Rect rect)
public TrackedObject (Rect rect)
{
lastPositions = new PositionsVector();
lastPositions = new PositionsVector ();
numDetectedFrames = 1;
numFramesNotDetected = 0;
state = TrackedState.NEW;
lastPositions.Add(rect.clone());
lastPositions.Add (rect.clone ());
_id = GetNextId();
_id = GetNextId ();
id = _id;
}
static int GetNextId()
static int GetNextId ()
{
_id++;
return _id;
}
}
}
}

Просмотреть файл

@ -1,4 +1,6 @@
namespace OpenCVForUnity.RectangleTrack
using OpenCVForUnity.CoreModule;
namespace OpenCVForUnity.RectangleTrack
{
public class TrackedRect : Rect
{
@ -7,8 +9,8 @@
public int id;
public TrackedState state;
public TrackedRect(int id, Rect rect, TrackedState state, int numDetectedFrames, int numFramesNotDetected)
: base(rect.x, rect.y, rect.width, rect.height)
public TrackedRect (int id, Rect rect, TrackedState state, int numDetectedFrames, int numFramesNotDetected)
: base (rect.x, rect.y, rect.width, rect.height)
{
this.numDetectedFrames = numDetectedFrames;
this.numFramesNotDetected = numFramesNotDetected;
@ -16,4 +18,4 @@
this.state = state;
}
}
}
}

Просмотреть файл

@ -12,12 +12,13 @@
public float coeffObjectSpeedUsingInPrediction = 0.8f;
public float coeffRectangleOverlap = 0.7f;
public TrackerParameters() {
public TrackerParameters ()
{
}
public TrackerParameters Clone()
public TrackerParameters Clone ()
{
TrackerParameters trackerParameters = new TrackerParameters();
TrackerParameters trackerParameters = new TrackerParameters ();
trackerParameters.numLastPositionsToTrack = numLastPositionsToTrack;
trackerParameters.numStepsToWaitBeforeFirstShow = numStepsToWaitBeforeFirstShow;
trackerParameters.numStepsToTrackWithoutDetectingIfObjectHasNotBeenShown = numStepsToTrackWithoutDetectingIfObjectHasNotBeenShown;

Просмотреть файл

@ -1,8 +1,10 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using OpenCVForUnity;
using System;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using Rect = OpenCVForUnity.CoreModule.Rect;
namespace FaceMaskExample
{
@ -42,23 +44,23 @@ namespace FaceMaskExample
src_mask.Dispose ();
src_mask = null;
}
src_mask = src_mask ?? new Mat (src.rows(), src.cols(), CvType.CV_8UC1, Scalar.all(0));
src_mask = src_mask ?? new Mat (src.rows (), src.cols (), CvType.CV_8UC1, Scalar.all (0));
if (dst_mask != null && (dst.width () != dst_mask.width () || dst.height () != dst_mask.height ())) {
dst_mask.Dispose ();
dst_mask = null;
}
dst_mask = dst_mask ?? new Mat (dst.rows(), dst.cols(), CvType.CV_8UC1, Scalar.all(0));
dst_mask = dst_mask ?? new Mat (dst.rows (), dst.cols (), CvType.CV_8UC1, Scalar.all (0));
// Get facial contour points.
GetFacialContourPoints (src_landmarkPoints, src_facialContourPoints);
GetFacialContourPoints (dst_landmarkPoints, dst_facialContourPoints);
// Get facial contour rect.
OpenCVForUnity.Rect src_facialContourRect = Imgproc.boundingRect(new MatOfPoint(src_facialContourPoints));
OpenCVForUnity.Rect dst_facialContourRect = Imgproc.boundingRect(new MatOfPoint(dst_facialContourPoints));
src_facialContourRect = src_facialContourRect.intersect (new OpenCVForUnity.Rect(0, 0, src.width(), src.height()));
dst_facialContourRect = dst_facialContourRect.intersect (new OpenCVForUnity.Rect(0, 0, dst.width(), dst.height()));
Rect src_facialContourRect = Imgproc.boundingRect (new MatOfPoint (src_facialContourPoints));
Rect dst_facialContourRect = Imgproc.boundingRect (new MatOfPoint (dst_facialContourPoints));
src_facialContourRect = src_facialContourRect.intersect (new Rect (0, 0, src.width (), src.height ()));
dst_facialContourRect = dst_facialContourRect.intersect (new Rect (0, 0, dst.width (), dst.height ()));
Mat src_ROI = new Mat (src, src_facialContourRect);
Mat dst_ROI = new Mat (dst, dst_facialContourRect);
@ -68,17 +70,17 @@ namespace FaceMaskExample
GetPointsInFrame (src_mask_ROI, src_facialContourPoints, src_facialContourPoints);
GetPointsInFrame (dst_mask_ROI, dst_facialContourPoints, dst_facialContourPoints);
src_mask_ROI.setTo (new Scalar(0));
dst_mask_ROI.setTo (new Scalar(0));
Imgproc.fillConvexPoly(src_mask_ROI, new MatOfPoint(src_facialContourPoints), new Scalar(255));
Imgproc.fillConvexPoly(dst_mask_ROI, new MatOfPoint(dst_facialContourPoints), new Scalar(255));
src_mask_ROI.setTo (new Scalar (0));
dst_mask_ROI.setTo (new Scalar (0));
Imgproc.fillConvexPoly (src_mask_ROI, new MatOfPoint (src_facialContourPoints), new Scalar (255));
Imgproc.fillConvexPoly (dst_mask_ROI, new MatOfPoint (dst_facialContourPoints), new Scalar (255));
Texture2D LUTTex;
if (LUTTexDict.ContainsKey (id)) {
LUTTex = LUTTexDict[id];
LUTTex = LUTTexDict [id];
} else {
LUTTex = new Texture2D (256, 1, TextureFormat.RGB24, false);
LUTTexDict.Add (id ,LUTTex);
LUTTexDict.Add (id, LUTTex);
}
FaceMaskShaderUtils.CalculateLUT (src_ROI, dst_ROI, src_mask_ROI, dst_mask_ROI, LUTTex);
@ -89,7 +91,7 @@ namespace FaceMaskExample
public virtual void DeleteLUTTex (int id)
{
if (LUTTexDict.ContainsKey (id)) {
Texture2D.Destroy(LUTTexDict [id]);
Texture2D.Destroy (LUTTexDict [id]);
LUTTexDict.Remove (id);
}
}
@ -102,38 +104,46 @@ namespace FaceMaskExample
return null;
}
protected virtual void GetFacialContourPoints(List<Vector2> landmark_points, Point[] dst_points)
protected virtual void GetFacialContourPoints (List<Vector2> landmark_points, Point[] dst_points)
{
if (landmark_points.Count < 9)
throw new ArgumentException("Invalid landmark_points.");
throw new ArgumentException ("Invalid landmark_points.");
if (dst_points.Length != 9)
throw new ArgumentException("Invalid points.");
throw new ArgumentException ("Invalid points.");
dst_points[0].x = landmark_points[0].x; dst_points[0].y = landmark_points[0].y;
dst_points[1].x = landmark_points[3].x; dst_points[1].y = landmark_points[3].y;
dst_points[2].x = landmark_points[5].x; dst_points[2].y = landmark_points[5].y;
dst_points[3].x = landmark_points[8].x; dst_points[3].y = landmark_points[8].y;
dst_points[4].x = landmark_points[11].x; dst_points[4].y = landmark_points[11].y;
dst_points[5].x = landmark_points[13].x; dst_points[5].y = landmark_points[13].y;
dst_points[6].x = landmark_points[16].x; dst_points[6].y = landmark_points[16].y;
float nose_length_x = landmark_points[27].x - landmark_points[30].x;
float nose_length_y = landmark_points[27].y - landmark_points[30].y;
dst_points [7].x = landmark_points [26].x + nose_length_x; dst_points [7].y = landmark_points [26].y + nose_length_y;
dst_points [8].x = landmark_points [17].x + nose_length_x; dst_points [8].y = landmark_points [17].y + nose_length_y;
dst_points [0].x = landmark_points [0].x;
dst_points [0].y = landmark_points [0].y;
dst_points [1].x = landmark_points [3].x;
dst_points [1].y = landmark_points [3].y;
dst_points [2].x = landmark_points [5].x;
dst_points [2].y = landmark_points [5].y;
dst_points [3].x = landmark_points [8].x;
dst_points [3].y = landmark_points [8].y;
dst_points [4].x = landmark_points [11].x;
dst_points [4].y = landmark_points [11].y;
dst_points [5].x = landmark_points [13].x;
dst_points [5].y = landmark_points [13].y;
dst_points [6].x = landmark_points [16].x;
dst_points [6].y = landmark_points [16].y;
float nose_length_x = landmark_points [27].x - landmark_points [30].x;
float nose_length_y = landmark_points [27].y - landmark_points [30].y;
dst_points [7].x = landmark_points [26].x + nose_length_x;
dst_points [7].y = landmark_points [26].y + nose_length_y;
dst_points [8].x = landmark_points [17].x + nose_length_x;
dst_points [8].y = landmark_points [17].y + nose_length_y;
}
protected virtual void GetPointsInFrame(Mat frame, Point[] points, Point[] dst_points)
protected virtual void GetPointsInFrame (Mat frame, Point[] points, Point[] dst_points)
{
if (points.Length != dst_points.Length)
throw new ArgumentException("points.Length != dst_points.Length");
throw new ArgumentException ("points.Length != dst_points.Length");
Size wholesize = new Size();
Point ofs = new Point();
frame.locateROI(wholesize, ofs);
Size wholesize = new Size ();
Point ofs = new Point ();
frame.locateROI (wholesize, ofs);
for (int i = 0; i < points.Length; i++)
{
for (int i = 0; i < points.Length; i++) {
dst_points [i].x = points [i].x - ofs.x;
dst_points [i].y = points [i].y - ofs.y;
}
@ -142,7 +152,7 @@ namespace FaceMaskExample
public virtual void Reset ()
{
foreach (var key in LUTTexDict.Keys) {
Texture2D.Destroy(LUTTexDict [key]);
Texture2D.Destroy (LUTTexDict [key]);
}
LUTTexDict.Clear ();
}

Просмотреть файл

@ -1,8 +1,9 @@
using UnityEngine;
using System.Collections;
using OpenCVForUnity;
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Collections;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.UnityUtils;
namespace FaceMaskExample
{
@ -11,32 +12,44 @@ namespace FaceMaskExample
// Match histograms of 'src' to that of 'dst', according to both masks.
public static void CalculateLUT (Mat src, Mat dst, Mat src_mask, Mat dst_mask, Texture2D LUTTex)
{
if (src.channels() < 3)
if (src.channels () < 3)
throw new ArgumentException ("src.channels() < 3");
if (dst.channels() < 3)
if (dst.channels () < 3)
throw new ArgumentException ("dst.channels() < 3");
if (src_mask.channels() != 1)
if (src_mask.channels () != 1)
throw new ArgumentException ("src_mask.channels() != 1");
if (dst_mask.channels() != 1)
if (dst_mask.channels () != 1)
throw new ArgumentException ("dst_mask.channels() != 1");
if (src_mask != null && src.total() != src_mask.total())
if (src_mask != null && src.total () != src_mask.total ())
throw new ArgumentException ("src.total() != src_mask.total()");
if (dst_mask != null && dst.total() != dst_mask.total())
if (dst_mask != null && dst.total () != dst_mask.total ())
throw new ArgumentException ("dst.total() != dst_mask.total()");
if (LUTTex.width != 256 || LUTTex.height != 1 || LUTTex.format != TextureFormat.RGB24)
throw new ArgumentException ("Invalid LUTTex.");
byte[] LUT = new byte[3 * 256];
double[][] src_hist = new double[3][]; for(int i=0; i<src_hist.Length; i++ ){ src_hist[i] = new double[256];}
double[][] dst_hist = new double[3][]; for(int i=0; i<dst_hist.Length; i++ ){ dst_hist[i] = new double[256];}
double[][] src_cdf = new double[3][]; for(int i=0; i<src_cdf.Length; i++ ){ src_cdf[i] = new double[256];}
double[][] dst_cdf = new double[3][]; for(int i=0; i<dst_cdf.Length; i++ ){ dst_cdf[i] = new double[256];}
double[][] src_hist = new double[3][];
for (int i = 0; i < src_hist.Length; i++) {
src_hist [i] = new double[256];
}
double[][] dst_hist = new double[3][];
for (int i = 0; i < dst_hist.Length; i++) {
dst_hist [i] = new double[256];
}
double[][] src_cdf = new double[3][];
for (int i = 0; i < src_cdf.Length; i++) {
src_cdf [i] = new double[256];
}
double[][] dst_cdf = new double[3][];
for (int i = 0; i < dst_cdf.Length; i++) {
dst_cdf [i] = new double[256];
}
double[] src_histMax = new double[3];
double[] dst_histMax = new double[3];
@ -44,22 +57,22 @@ namespace FaceMaskExample
byte[] src_mask_byte = null;
byte[] dst_mask_byte = null;
if (src_mask != null) {
src_mask_byte = new byte[src_mask.total() * src_mask.channels()];
Utils.copyFromMat<byte>(src_mask, src_mask_byte);
src_mask_byte = new byte[src_mask.total () * src_mask.channels ()];
Utils.copyFromMat<byte> (src_mask, src_mask_byte);
}
if (dst_mask != null) {
dst_mask_byte = new byte[dst_mask.total () * dst_mask.channels ()];
Utils.copyFromMat<byte> (dst_mask, dst_mask_byte);
}
byte[] src_byte = new byte[src.total() * src.channels()];
Utils.copyFromMat<byte>(src, src_byte);
byte[] dst_byte = new byte[dst.total() * dst.channels()];
Utils.copyFromMat<byte>(dst, dst_byte);
byte[] src_byte = new byte[src.total () * src.channels ()];
Utils.copyFromMat<byte> (src, src_byte);
byte[] dst_byte = new byte[dst.total () * dst.channels ()];
Utils.copyFromMat<byte> (dst, dst_byte);
int pixel_i = 0;
int channels = src.channels();
int total = (int)src.total();
int channels = src.channels ();
int total = (int)src.total ();
if (src_mask_byte != null) {
for (int i = 0; i < total; i++) {
if (src_mask_byte [i] != 0) {
@ -152,43 +165,41 @@ namespace FaceMaskExample
//normalize hist
for (int i = 0; i < 256; i++) {
src_hist [0][i] /= src_histMax[0];
src_hist [1][i] /= src_histMax[1];
src_hist [2][i] /= src_histMax[2];
src_hist [0] [i] /= src_histMax [0];
src_hist [1] [i] /= src_histMax [1];
src_hist [2] [i] /= src_histMax [2];
dst_hist [0][i] /= dst_histMax[0];
dst_hist [1][i] /= dst_histMax[1];
dst_hist [2][i] /= dst_histMax[2];
dst_hist [0] [i] /= dst_histMax [0];
dst_hist [1] [i] /= dst_histMax [1];
dst_hist [2] [i] /= dst_histMax [2];
}
// Calc cumulative distribution function (CDF)
src_cdf[0][0] = src_hist[0][0];
src_cdf[1][0] = src_hist[1][0];
src_cdf[2][0] = src_hist[2][0];
dst_cdf[0][0] = dst_hist[0][0];
dst_cdf[1][0] = dst_hist[1][0];
dst_cdf[2][0] = dst_hist[2][0];
for (int i = 1; i < 256; i++)
{
src_cdf[0][i] = src_cdf[0][i - 1] + src_hist[0][i];
src_cdf[1][i] = src_cdf[1][i - 1] + src_hist[1][i];
src_cdf[2][i] = src_cdf[2][i - 1] + src_hist[2][i];
src_cdf [0] [0] = src_hist [0] [0];
src_cdf [1] [0] = src_hist [1] [0];
src_cdf [2] [0] = src_hist [2] [0];
dst_cdf [0] [0] = dst_hist [0] [0];
dst_cdf [1] [0] = dst_hist [1] [0];
dst_cdf [2] [0] = dst_hist [2] [0];
for (int i = 1; i < 256; i++) {
src_cdf [0] [i] = src_cdf [0] [i - 1] + src_hist [0] [i];
src_cdf [1] [i] = src_cdf [1] [i - 1] + src_hist [1] [i];
src_cdf [2] [i] = src_cdf [2] [i - 1] + src_hist [2] [i];
dst_cdf[0][i] = dst_cdf[0][i - 1] + dst_hist[0][i];
dst_cdf[1][i] = dst_cdf[1][i - 1] + dst_hist[1][i];
dst_cdf[2][i] = dst_cdf[2][i - 1] + dst_hist[2][i];
dst_cdf [0] [i] = dst_cdf [0] [i - 1] + dst_hist [0] [i];
dst_cdf [1] [i] = dst_cdf [1] [i - 1] + dst_hist [1] [i];
dst_cdf [2] [i] = dst_cdf [2] [i - 1] + dst_hist [2] [i];
}
// Normalize CDF
for (int i = 0; i < 256; i++)
{
src_cdf[0][i] /= src_cdf[0][255];
src_cdf[1][i] /= src_cdf[1][255];
src_cdf[2][i] /= src_cdf[2][255];
for (int i = 0; i < 256; i++) {
src_cdf [0] [i] /= src_cdf [0] [255];
src_cdf [1] [i] /= src_cdf [1] [255];
src_cdf [2] [i] /= src_cdf [2] [255];
dst_cdf[0][i] /= dst_cdf[0][255];
dst_cdf[1][i] /= dst_cdf[1][255];
dst_cdf[2][i] /= dst_cdf[2][255];
dst_cdf [0] [i] /= dst_cdf [0] [255];
dst_cdf [1] [i] /= dst_cdf [1] [255];
dst_cdf [2] [i] /= dst_cdf [2] [255];
}
// Create lookup table
@ -196,10 +207,10 @@ namespace FaceMaskExample
for (int i = 0; i < 3; i++) {
int last = 0;
for (int j = 0; j < 256; j++) {
double F1j = src_cdf [i][j];
double F1j = src_cdf [i] [j];
for (int k = last; k < 256; k++) {
double F2k = dst_cdf [i][k];
double F2k = dst_cdf [i] [k];
if (Math.Abs (F2k - F1j) < HISTMATCH_EPSILON || F2k > F1j) {
LUT [(j * 3) + i] = (byte)k;
last = k;

Просмотреть файл

@ -6,8 +6,8 @@ public class FaceMaskData : MonoBehaviour
{
[SerializeField]
private Texture2D _image;
public Texture2D image
{
public Texture2D image {
get { return this._image; }
set { this._image = value; }
}
@ -25,87 +25,86 @@ public class FaceMaskData : MonoBehaviour
public bool enableColorCorrection = true;
[SerializeField]
private Rect _faceRect = new Rect(78, 95, 151, 150);
public Rect faceRect
{
private Rect _faceRect = new Rect (78, 95, 151, 150);
public Rect faceRect {
get { return this._faceRect; }
set { this._faceRect = value; }
}
[SerializeField]
private List<Vector2> _landmarkPoints = new List<Vector2> ()
{
new Vector2(84, 148),
new Vector2(84, 167),
new Vector2(86, 187),
new Vector2(89, 206),
new Vector2(96, 224),
new Vector2(106, 240),
new Vector2(119, 253),
new Vector2(134, 264),
new Vector2(151, 266),
new Vector2(168, 264),
new Vector2(184, 254),
new Vector2(197, 241),
new Vector2(207, 226),
new Vector2(214, 209),
new Vector2(218, 190),
new Vector2(221, 170),
new Vector2(221, 150),
new Vector2(100, 125),
new Vector2(108, 117),
new Vector2(119, 114),
new Vector2(130, 116),
new Vector2(141, 120),
new Vector2(164, 120),
new Vector2(176, 116),
new Vector2(187, 115),
new Vector2(199, 118),
new Vector2(206, 126),
new Vector2(153, 133),
new Vector2(153, 144),
new Vector2(154, 156),
new Vector2(154, 168),
new Vector2(142, 181),
new Vector2(148, 182),
new Vector2(154, 184),
new Vector2(160, 182),
new Vector2(165, 181),
new Vector2(113, 134),
new Vector2(120, 127),
new Vector2(129, 127),
new Vector2(136, 136),
new Vector2(128, 137),
new Vector2(119, 137),
new Vector2(170, 137),
new Vector2(177, 128),
new Vector2(187, 128),
new Vector2(193, 136),
new Vector2(188, 139),
new Vector2(178, 138),
new Vector2(127, 215),
new Vector2(135, 204),
new Vector2(145, 199),
new Vector2(154, 201),
new Vector2(163, 199),
new Vector2(173, 205),
new Vector2(178, 218),
new Vector2(173, 225),
new Vector2(163, 229),
new Vector2(154, 230),
new Vector2(144, 228),
new Vector2(134, 224),
new Vector2(131, 215),
new Vector2(145, 206),
new Vector2(154, 207),
new Vector2(163, 207),
new Vector2(175, 217),
new Vector2(163, 219),
new Vector2(154, 220),
new Vector2(144, 218)
private List<Vector2> _landmarkPoints = new List<Vector2> () {
new Vector2 (84, 148),
new Vector2 (84, 167),
new Vector2 (86, 187),
new Vector2 (89, 206),
new Vector2 (96, 224),
new Vector2 (106, 240),
new Vector2 (119, 253),
new Vector2 (134, 264),
new Vector2 (151, 266),
new Vector2 (168, 264),
new Vector2 (184, 254),
new Vector2 (197, 241),
new Vector2 (207, 226),
new Vector2 (214, 209),
new Vector2 (218, 190),
new Vector2 (221, 170),
new Vector2 (221, 150),
new Vector2 (100, 125),
new Vector2 (108, 117),
new Vector2 (119, 114),
new Vector2 (130, 116),
new Vector2 (141, 120),
new Vector2 (164, 120),
new Vector2 (176, 116),
new Vector2 (187, 115),
new Vector2 (199, 118),
new Vector2 (206, 126),
new Vector2 (153, 133),
new Vector2 (153, 144),
new Vector2 (154, 156),
new Vector2 (154, 168),
new Vector2 (142, 181),
new Vector2 (148, 182),
new Vector2 (154, 184),
new Vector2 (160, 182),
new Vector2 (165, 181),
new Vector2 (113, 134),
new Vector2 (120, 127),
new Vector2 (129, 127),
new Vector2 (136, 136),
new Vector2 (128, 137),
new Vector2 (119, 137),
new Vector2 (170, 137),
new Vector2 (177, 128),
new Vector2 (187, 128),
new Vector2 (193, 136),
new Vector2 (188, 139),
new Vector2 (178, 138),
new Vector2 (127, 215),
new Vector2 (135, 204),
new Vector2 (145, 199),
new Vector2 (154, 201),
new Vector2 (163, 199),
new Vector2 (173, 205),
new Vector2 (178, 218),
new Vector2 (173, 225),
new Vector2 (163, 229),
new Vector2 (154, 230),
new Vector2 (144, 228),
new Vector2 (134, 224),
new Vector2 (131, 215),
new Vector2 (145, 206),
new Vector2 (154, 207),
new Vector2 (163, 207),
new Vector2 (175, 217),
new Vector2 (163, 219),
new Vector2 (154, 220),
new Vector2 (144, 218)
};
public List<Vector2> landmarkPoints
{
public List<Vector2> landmarkPoints {
get { return this._landmarkPoints; }
set { this._landmarkPoints = value; }
}

Просмотреть файл

@ -1,13 +1,14 @@
using OpenCVForUnity;
using System;
using System.Collections.Generic;
using UnityEngine;
using System;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
namespace FaceMaskExample
{
/// <summary>
/// Low Pass Points Filter.
/// v 1.0.1
/// v 1.0.2
/// </summary>
public class LowPassPointsFilter : PointsFilterBase
{
@ -89,7 +90,7 @@ namespace FaceMaskExample
{
flag = false;
for (int i = 0; i < lastPoints.Count; i++) {
lastPoints[i] = new Vector2 ();
lastPoints [i] = new Vector2 ();
}
}

Просмотреть файл

@ -1,13 +1,15 @@
using OpenCVForUnity;
using System;
using System.Collections.Generic;
using UnityEngine;
using System;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using OpenCVForUnity.VideoModule;
namespace FaceMaskExample
{
/// <summary>
/// Optical Flow Points Filter.
/// v 1.0.2
/// v 1.0.3
/// </summary>
public class OFPointsFilter : PointsFilterBase
{
@ -67,7 +69,7 @@ namespace FaceMaskExample
}
for (int i = 0; i < numberOfElements; i++) {
prevTrackPts[i] = new Point (srcPoints [i].x, srcPoints [i].y);
prevTrackPts [i] = new Point (srcPoints [i].x, srcPoints [i].y);
}
flag = true;
@ -106,7 +108,7 @@ namespace FaceMaskExample
// clac diffDlib
prevTrackPtsMat.fromList (prevTrackPts);
OpenCVForUnity.Rect rect = Imgproc.boundingRect (prevTrackPtsMat);
OpenCVForUnity.CoreModule.Rect rect = Imgproc.boundingRect (prevTrackPtsMat);
double diffDlib = this.diffDlib * rect.area () / 40000.0 * diffCheckSensitivity;
// if the face is moving so fast, use dlib to detect the face
@ -156,21 +158,21 @@ namespace FaceMaskExample
// Reset Optical Flow
for (int i = 0; i < numberOfElements; i++) {
prevTrackPts[i].x = 0.0;
prevTrackPts[i].y = 0.0;
prevTrackPts [i].x = 0.0;
prevTrackPts [i].y = 0.0;
}
for (int i = 0; i < numberOfElements; i++) {
nextTrackPts[i].x = 0.0;
nextTrackPts[i].y = 0.0;
nextTrackPts [i].x = 0.0;
nextTrackPts [i].y = 0.0;
}
if (prevgray != null) {
prevgray.Dispose ();
prevgray = new Mat();
prevgray = new Mat ();
}
if (gray != null) {
gray.Dispose ();
gray = new Mat();
gray = new Mat ();
}
}

Просмотреть файл

@ -1,13 +1,13 @@
using OpenCVForUnity;
using System;
using System;
using System.Collections.Generic;
using UnityEngine;
using OpenCVForUnity.CoreModule;
namespace FaceMaskExample
{
/// <summary>
/// Points Filter Base.
/// v 1.0.0
/// v 1.0.1
/// </summary>
public abstract class PointsFilterBase
{

Просмотреть файл

@ -13,114 +13,102 @@ namespace FaceMaskExample
[SerializeField]
private int interval = 1;
private List<GameObject> pooledObjectList = new List<GameObject>();
private List<GameObject> pooledObjectList = new List<GameObject> ();
private IEnumerator removeObjectCheckCoroutine;
void OnEnable()
void OnEnable ()
{
if (interval > 0){
removeObjectCheckCoroutine = RemoveObjectCheck();
StartCoroutine(removeObjectCheckCoroutine);
if (interval > 0) {
removeObjectCheckCoroutine = RemoveObjectCheck ();
StartCoroutine (removeObjectCheckCoroutine);
}
}
void OnDisable()
void OnDisable ()
{
if (removeObjectCheckCoroutine != null){
StopCoroutine(removeObjectCheckCoroutine);
if (removeObjectCheckCoroutine != null) {
StopCoroutine (removeObjectCheckCoroutine);
removeObjectCheckCoroutine = null;
}
}
void OnDestroy()
void OnDestroy ()
{
DestroyAllObjects ();
}
public int Interval
{
get
{
public int Interval {
get {
return interval;
}
set
{
if (interval != value)
{
set {
if (interval != value) {
interval = value;
if (removeObjectCheckCoroutine != null){
StopCoroutine(removeObjectCheckCoroutine);
if (removeObjectCheckCoroutine != null) {
StopCoroutine (removeObjectCheckCoroutine);
removeObjectCheckCoroutine = null;
}
if (interval > 0){
removeObjectCheckCoroutine = RemoveObjectCheck();
StartCoroutine(removeObjectCheckCoroutine);
if (interval > 0) {
removeObjectCheckCoroutine = RemoveObjectCheck ();
StartCoroutine (removeObjectCheckCoroutine);
}
}
}
}
public GameObject GetInstance()
public GameObject GetInstance ()
{
return GetInstance(transform);
return GetInstance (transform);
}
public GameObject GetInstance(Transform parent)
public GameObject GetInstance (Transform parent)
{
if (prefab == null){
Debug.LogWarning("prefab object is not set.");
if (prefab == null) {
Debug.LogWarning ("prefab object is not set.");
return null;
}
pooledObjectList.RemoveAll((obj) => obj == null);
pooledObjectList.RemoveAll ((obj) => obj == null);
foreach (GameObject obj in pooledObjectList)
{
if (obj.activeSelf == false)
{
obj.SetActive(true);
foreach (GameObject obj in pooledObjectList) {
if (obj.activeSelf == false) {
obj.SetActive (true);
return obj;
}
}
if (pooledObjectList.Count < maxCount)
{
GameObject obj = (GameObject)GameObject.Instantiate(prefab);
obj.SetActive(true);
obj.transform.SetParent(parent, false);
pooledObjectList.Add(obj);
if (pooledObjectList.Count < maxCount) {
GameObject obj = (GameObject)GameObject.Instantiate (prefab);
obj.SetActive (true);
obj.transform.SetParent (parent, false);
pooledObjectList.Add (obj);
return obj;
}
return null;
}
IEnumerator RemoveObjectCheck()
IEnumerator RemoveObjectCheck ()
{
while (true)
{
RemoveObject(prepareCount);
yield return new WaitForSeconds(interval);
while (true) {
RemoveObject (prepareCount);
yield return new WaitForSeconds (interval);
}
}
public void RemoveObject(int max)
public void RemoveObject (int max)
{
if (pooledObjectList.Count > max)
{
if (pooledObjectList.Count > max) {
int needRemoveCount = pooledObjectList.Count - max;
foreach (GameObject obj in pooledObjectList.ToArray())
{
if (needRemoveCount == 0)
{
foreach (GameObject obj in pooledObjectList.ToArray()) {
if (needRemoveCount == 0) {
break;
}
if (obj.activeSelf == false)
{
pooledObjectList.Remove(obj);
Destroy(obj);
if (obj.activeSelf == false) {
pooledObjectList.Remove (obj);
Destroy (obj);
needRemoveCount--;
}
}
@ -129,11 +117,10 @@ namespace FaceMaskExample
public void DestroyAllObjects ()
{
foreach (var obj in pooledObjectList)
{
Destroy(obj);
foreach (var obj in pooledObjectList) {
Destroy (obj);
}
pooledObjectList.Clear();
pooledObjectList.Clear ();
}
}
}

Просмотреть файл

@ -3,63 +3,62 @@ using UnityEngine;
namespace FaceMaskExample
{
[RequireComponent(typeof(MeshRenderer), typeof(MeshFilter), typeof(MeshCollider))]
[RequireComponent (typeof(MeshRenderer), typeof(MeshFilter), typeof(MeshCollider))]
public class TrackedMesh : MonoBehaviour
{
public MeshFilter meshFilter
{
public MeshFilter meshFilter {
get { return _meshFilter; }
}
protected MeshFilter _meshFilter;
public MeshRenderer meshRenderer
{
public MeshRenderer meshRenderer {
get { return _meshRenderer; }
}
protected MeshRenderer _meshRenderer;
public MeshCollider meshCollider
{
public MeshCollider meshCollider {
get { return _meshCollider; }
}
protected MeshCollider _meshCollider;
public int id
{
public int id {
get { return _id; }
set { _id = value; }
}
protected int _id = 0;
public Material material
{
public Material material {
get { return _meshRenderer.material; }
}
public Material sharedMaterial
{
public Material sharedMaterial {
get { return _meshRenderer.sharedMaterial; }
}
void Awake()
void Awake ()
{
_meshFilter = this.GetComponent<MeshFilter>();
_meshRenderer = this.GetComponent<MeshRenderer>();
_meshCollider = this.GetComponent<MeshCollider>();
_meshFilter = this.GetComponent<MeshFilter> ();
_meshRenderer = this.GetComponent<MeshRenderer> ();
_meshCollider = this.GetComponent<MeshCollider> ();
if (_meshRenderer.material == null)
throw new Exception("material does not exist.");
throw new Exception ("material does not exist.");
_meshRenderer.sortingOrder = 32767;
}
void OnDestroy(){
if(_meshFilter != null && _meshFilter.mesh != null){
DestroyImmediate(_meshFilter.mesh);
void OnDestroy ()
{
if (_meshFilter != null && _meshFilter.mesh != null) {
DestroyImmediate (_meshFilter.mesh);
}
if(_meshRenderer != null && _meshRenderer.materials != null){
foreach(var m in _meshRenderer.materials){
DestroyImmediate(m);
if (_meshRenderer != null && _meshRenderer.materials != null) {
foreach (var m in _meshRenderer.materials) {
DestroyImmediate (m);
}
}
}

Просмотреть файл

@ -12,26 +12,24 @@ namespace FaceMaskExample
[SerializeField]
protected GameObject _baseObject;
public GameObject baseObject
{
public GameObject baseObject {
get {
return _baseObject;
}
set {
_baseObject = value;
SetBaseObject(_baseObject);
SetBaseObject (_baseObject);
}
}
public float width
{
public float width {
get {
return targetWidth;
}
}
public float height
{
public float height {
get {
return targetHeight;
}
@ -42,73 +40,71 @@ namespace FaceMaskExample
protected float targetHeight = 0;
protected Transform overlayTransform;
protected ObjectPool objectPool;
protected Dictionary<int, TrackedMesh> showingObjects = new Dictionary<int, TrackedMesh>();
protected Dictionary<int, TrackedMesh> showingObjects = new Dictionary<int, TrackedMesh> ();
void Awake()
void Awake ()
{
Initialize("TrackedMeshOverlay");
Initialize ("TrackedMeshOverlay");
}
void OnDestroy()
void OnDestroy ()
{
overlayTransform = null;
targetTransform = null;
targetWidth = 0;
targetHeight = 0;
showingObjects.Clear();
if(objectPool != null)
{
Destroy(objectPool.gameObject);
showingObjects.Clear ();
if (objectPool != null) {
Destroy (objectPool.gameObject);
objectPool = null;
}
}
protected virtual GameObject GetPoolObject(Transform parent)
protected virtual GameObject GetPoolObject (Transform parent)
{
if(objectPool == null) return null;
if (objectPool == null)
return null;
GameObject newObj = objectPool.GetInstance(parent);
if(newObj != null){
newObj.transform.SetParent(parent, false);
GameObject newObj = objectPool.GetInstance (parent);
if (newObj != null) {
newObj.transform.SetParent (parent, false);
return newObj;
}else{
} else {
return null;
}
}
protected virtual void Initialize(String name)
protected virtual void Initialize (String name)
{
GameObject obj = new GameObject(name);
GameObject obj = new GameObject (name);
overlayTransform = obj.transform;
overlayTransform.parent = gameObject.transform.parent;
if(_baseObject != null)
if (_baseObject != null)
SetBaseObject (_baseObject);
}
protected virtual void SetBaseObject (GameObject obj)
{
if (obj.GetComponent<TrackedMesh>() == null)
{
Debug.LogWarning("This gameObject is not TrackedMesh.");
if (obj.GetComponent<TrackedMesh> () == null) {
Debug.LogWarning ("This gameObject is not TrackedMesh.");
return;
}
if(objectPool != null){
Destroy(objectPool);
if (objectPool != null) {
Destroy (objectPool);
}
objectPool = overlayTransform.gameObject.AddComponent<ObjectPool>();
objectPool = overlayTransform.gameObject.AddComponent<ObjectPool> ();
objectPool.prefab = obj;
objectPool.maxCount = poolSize;
objectPool.prepareCount = (int)poolSize / 2;
objectPool.Interval = interval;
}
public virtual void UpdateOverlayTransform(Transform targetTransform)
public virtual void UpdateOverlayTransform (Transform targetTransform)
{
if (targetTransform == null)
{
if (targetTransform == null) {
this.targetTransform = null;
return;
}
@ -121,89 +117,83 @@ namespace FaceMaskExample
overlayTransform.localScale = targetTransform.localScale;
}
public virtual TrackedMesh GetObjectById(int id)
public virtual TrackedMesh GetObjectById (int id)
{
if (showingObjects.ContainsKey(id))
{
return showingObjects[id];
if (showingObjects.ContainsKey (id)) {
return showingObjects [id];
}
return null;
}
public virtual TrackedMesh CreateObject(int id, Texture2D tex = null)
public virtual TrackedMesh CreateObject (int id, Texture2D tex = null)
{
if (_baseObject == null) Debug.LogError("The baseObject does not exist.");
if (_baseObject == null)
Debug.LogError ("The baseObject does not exist.");
if (!showingObjects.ContainsKey(id)){
GameObject obj = GetPoolObject(overlayTransform);
if (obj == null) return null;
TrackedMesh tm = obj.GetComponent<TrackedMesh>();
if (tm != null)
{
if (!showingObjects.ContainsKey (id)) {
GameObject obj = GetPoolObject (overlayTransform);
if (obj == null)
return null;
TrackedMesh tm = obj.GetComponent<TrackedMesh> ();
if (tm != null) {
tm.id = id;
tm.transform.localPosition = Vector3.zero;
tm.transform.localRotation = new Quaternion();
tm.transform.localRotation = new Quaternion ();
tm.transform.localScale = Vector3.one;
if (tex != null)
{
Renderer tmRenderer = tm.transform.GetComponent<Renderer>();
if (tex != null) {
Renderer tmRenderer = tm.transform.GetComponent<Renderer> ();
tmRenderer.sharedMaterial.SetTexture ("_MainTex", tex);
}
showingObjects.Add(id, tm);
showingObjects.Add (id, tm);
}
return tm;
}
else{
} else {
return null;
}
}
public virtual void UpdateObject(int id, Vector3[] vertices, int[] triangles = null, Vector2[] uv = null, Vector2[] uv2 = null)
public virtual void UpdateObject (int id, Vector3[] vertices, int[] triangles = null, Vector2[] uv = null, Vector2[] uv2 = null)
{
if (showingObjects.ContainsKey(id)){
TrackedMesh tm = showingObjects[id];
if (showingObjects.ContainsKey (id)) {
TrackedMesh tm = showingObjects [id];
if(vertices.Length != tm.meshFilter.mesh.vertices.Length) Debug.LogError("The number of vertices does not match.");
if (vertices.Length != tm.meshFilter.mesh.vertices.Length)
Debug.LogError ("The number of vertices does not match.");
tm.meshFilter.mesh.vertices = vertices;
if (triangles != null)
{
if (triangles != null) {
tm.meshFilter.mesh.triangles = triangles;
}
if (uv != null)
{
if (uv != null) {
tm.meshFilter.mesh.uv = uv;
}
if (uv2 != null)
{
if (uv2 != null) {
tm.meshFilter.mesh.uv2 = uv2;
}
tm.meshFilter.mesh.RecalculateBounds();
tm.meshFilter.mesh.RecalculateNormals();
tm.meshFilter.mesh.RecalculateBounds ();
tm.meshFilter.mesh.RecalculateNormals ();
}
}
public virtual void DeleteObject(int id)
public virtual void DeleteObject (int id)
{
if (showingObjects.ContainsKey(id))
{
if(showingObjects[id] != null)
showingObjects[id].gameObject.SetActive(false);
showingObjects.Remove(id);
if (showingObjects.ContainsKey (id)) {
if (showingObjects [id] != null)
showingObjects [id].gameObject.SetActive (false);
showingObjects.Remove (id);
}
}
public virtual void Reset()
public virtual void Reset ()
{
foreach (int key in showingObjects.Keys)
{
if(showingObjects[key] != null)
showingObjects[key].gameObject.SetActive(false);
foreach (int key in showingObjects.Keys) {
if (showingObjects [key] != null)
showingObjects [key].gameObject.SetActive (false);
}
showingObjects.Clear();
showingObjects.Clear ();
}
}
}

Просмотреть файл

@ -1,6 +1,8 @@
using UnityEngine;
using System.Collections;
using OpenCVForUnity;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using OpenCVForUnity.UnityUtils;
namespace FaceMaskExample
{
@ -22,8 +24,8 @@ namespace FaceMaskExample
for (int i = 0; i < baseArea.Length; i++) {
baseAreaPoints [i] = new Point (baseArea [i].x * width, height - baseArea [i].y * height);
}
Imgproc.fillConvexPoly (baseAreaMaskMat, new MatOfPoint (baseAreaPoints), Scalar.all (255), Core.LINE_AA, 0);
// Imgproc.erode(baseAreaMaskMat, baseAreaMaskMat, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size (width * 0.01, height * 0.01)), new Point(-1, -1), 1, Core.BORDER_CONSTANT, new Scalar(0, 0, 0, 255));
Imgproc.fillConvexPoly (baseAreaMaskMat, new MatOfPoint (baseAreaPoints), Scalar.all (255), Imgproc.LINE_AA, 0);
// Imgproc.erode(baseAreaMaskMat, baseAreaMaskMat, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size (width * 0.01, height * 0.01)), new Point(-1, -1), 1, Core.BORDER_CONSTANT, new Scalar(0, 0, 0, 255));
Imgproc.blur (baseAreaMaskMat, baseAreaMaskMat, new Size (width * 0.03, height * 0.03));
@ -34,9 +36,9 @@ namespace FaceMaskExample
for (int i = 0; i < exclusionArea.Length; i++) {
points [i] = new Point (exclusionArea [i].x * width, height - exclusionArea [i].y * height);
}
Imgproc.fillConvexPoly (exclusionAreaMaskMat, new MatOfPoint (points), Scalar.all (255), Core.LINE_AA, 0);
Imgproc.fillConvexPoly (exclusionAreaMaskMat, new MatOfPoint (points), Scalar.all (255), Imgproc.LINE_AA, 0);
}
// Imgproc.dilate(exclusionAreaMaskMat, exclusionAreaMaskMat, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size (width * 0.002, height * 0.002)), new Point(-1, -1), 1, Core.BORDER_CONSTANT, new Scalar(0));
// Imgproc.dilate(exclusionAreaMaskMat, exclusionAreaMaskMat, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size (width * 0.002, height * 0.002)), new Point(-1, -1), 1, Core.BORDER_CONSTANT, new Scalar(0));
Imgproc.blur (exclusionAreaMaskMat, exclusionAreaMaskMat, new Size (width * 0.01, height * 0.01), new Point (-1, -1), Core.BORDER_CONSTANT);
@ -44,7 +46,7 @@ namespace FaceMaskExample
Core.bitwise_xor (baseAreaMaskMat, exclusionAreaMaskMat, maskMat);
Texture2D texture = new Texture2D ((int)width, (int)height, TextureFormat.RGBA32, false);
OpenCVForUnity.Utils.matToTexture2D (maskMat, texture);
Utils.matToTexture2D (maskMat, texture);
maskMat.Dispose ();
baseAreaMaskMat.Dispose ();

Просмотреть файл

@ -28,11 +28,11 @@ namespace FaceMaskExample
const float INNER_Y = 5f;
const float GUI_CONSOLE_HEIGHT = 50f;
public Vector2 offset = new Vector2(MARGIN_X, MARGIN_Y);
public Vector2 offset = new Vector2 (MARGIN_X, MARGIN_Y);
public bool boxVisible = true;
public float boxWidth = GUI_WIDTH;
public float boxHeight = GUI_HEIGHT;
public Vector2 padding = new Vector2(INNER_X, INNER_Y);
public Vector2 padding = new Vector2 (INNER_X, INNER_Y);
public float consoleHeight = GUI_CONSOLE_HEIGHT;
GUIStyle console_labelStyle;
@ -52,7 +52,8 @@ namespace FaceMaskExample
public string consoleText;
// Use this for initialization
void Start () {
void Start ()
{
console_labelStyle = new GUIStyle ();
console_labelStyle.fontSize = 32;
console_labelStyle.fontStyle = FontStyle.Normal;
@ -61,11 +62,12 @@ namespace FaceMaskExample
oldScrWidth = Screen.width;
oldScrHeight = Screen.height;
LocateGUI();
LocateGUI ();
}
// Update is called once per frame
void Update () {
void Update ()
{
tick++;
elapsed += Time.deltaTime;
if (elapsed >= 1f) {
@ -75,29 +77,30 @@ namespace FaceMaskExample
}
}
void OnGUI () {
void OnGUI ()
{
if (oldScrWidth != Screen.width || oldScrHeight != Screen.height) {
LocateGUI();
LocateGUI ();
}
oldScrWidth = Screen.width;
oldScrHeight = Screen.height;
if (boxVisible) {
GUI.Box(outer, "");
GUI.Box (outer, "");
}
GUILayout.BeginArea(inner);
GUILayout.BeginArea (inner);
{
GUILayout.BeginVertical();
GUILayout.Label("fps : " + fps.ToString("F1"));
GUILayout.BeginVertical ();
GUILayout.Label ("fps : " + fps.ToString ("F1"));
foreach (KeyValuePair<string, string> pair in outputDict) {
GUILayout.Label(pair.Key + " : " + pair.Value);
GUILayout.Label (pair.Key + " : " + pair.Value);
}
GUILayout.EndVertical();
GUILayout.EndVertical ();
}
GUILayout.EndArea ();
if (!string.IsNullOrEmpty(consoleText)) {
if (!string.IsNullOrEmpty (consoleText)) {
if (boxVisible) {
GUI.Box (console_outer, "");
}
@ -112,7 +115,8 @@ namespace FaceMaskExample
}
}
public void Add (string key, string value) {
public void Add (string key, string value)
{
if (outputDict.ContainsKey (key)) {
outputDict [key] = value;
} else {
@ -120,27 +124,31 @@ namespace FaceMaskExample
}
}
public void Remove (string key) {
public void Remove (string key)
{
outputDict.Remove (key);
}
public void Clear () {
public void Clear ()
{
outputDict.Clear ();
}
public void LocateGUI() {
x = GetAlignedX(alignment, boxWidth);
y = GetAlignedY(alignment, boxHeight);
outer = new Rect(x, y, boxWidth, boxHeight);
inner = new Rect(x + padding.x, y + padding.y, boxWidth, boxHeight);
console_x = GetAlignedX(Alignment.LeftBottom, Screen.width);
console_y = GetAlignedY(Alignment.LeftBottom, consoleHeight);
console_outer = new Rect(console_x, console_y, Screen.width - offset.x*2, consoleHeight);
console_inner = new Rect(console_x + padding.x, console_y + padding.y, Screen.width - offset.x*2 - padding.x, consoleHeight);
public void LocateGUI ()
{
x = GetAlignedX (alignment, boxWidth);
y = GetAlignedY (alignment, boxHeight);
outer = new Rect (x, y, boxWidth, boxHeight);
inner = new Rect (x + padding.x, y + padding.y, boxWidth, boxHeight);
console_x = GetAlignedX (Alignment.LeftBottom, Screen.width);
console_y = GetAlignedY (Alignment.LeftBottom, consoleHeight);
console_outer = new Rect (console_x, console_y, Screen.width - offset.x * 2, consoleHeight);
console_inner = new Rect (console_x + padding.x, console_y + padding.y, Screen.width - offset.x * 2 - padding.x, consoleHeight);
}
float GetAlignedX(Alignment anchor, float w) {
float GetAlignedX (Alignment anchor, float w)
{
switch (anchor) {
default:
case Alignment.LeftTop:
@ -153,7 +161,8 @@ namespace FaceMaskExample
}
}
float GetAlignedY(Alignment anchor, float h) {
float GetAlignedY (Alignment anchor, float h)
{
switch (anchor) {
default:
case Alignment.LeftTop:

Просмотреть файл

@ -2,16 +2,16 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using OpenCVForUnity;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.Calib3dModule;
namespace FaceMaskExample
{
/// <summary>
/// Frontal face checker. (Calculates from points of face landmark which was detected by using Dlib Face Landmark Detector)
/// v 1.0.0
/// v 1.0.1
/// </summary>
public class FrontalFaceChecker : IDisposable
public class FrontalFaceChecker
{
float imageWidth;
float imageHeight;
@ -38,7 +38,7 @@ namespace FaceMaskExample
imageHeight = height;
for (int i = 0; i < landmarkPoints.Length; i++) {
landmarkPoints[i] = new Point (0, 0);
landmarkPoints [i] = new Point (0, 0);
}
objectPoints = new MatOfPoint3f (
@ -49,7 +49,7 @@ namespace FaceMaskExample
new Point3 (26, 15, 83),//r mouse (Mouth breadth)
new Point3 (-79, 90, 0.0),//l ear (Bitragion breadth)
new Point3 (79, 90, 0.0)//r ear (Bitragion breadth)
);
);
imagePoints = new MatOfPoint2f ();
@ -78,25 +78,25 @@ namespace FaceMaskExample
public void Dispose ()
{
if(objectPoints != null && !objectPoints.IsDisposed)
if (objectPoints != null && !objectPoints.IsDisposed)
objectPoints.Dispose ();
if(imagePoints != null && !imagePoints.IsDisposed)
if (imagePoints != null && !imagePoints.IsDisposed)
imagePoints.Dispose ();
if(rvec != null && !rvec.IsDisposed)
if (rvec != null && !rvec.IsDisposed)
rvec.Dispose ();
if(tvec != null && !tvec.IsDisposed)
if (tvec != null && !tvec.IsDisposed)
tvec.Dispose ();
if(rotM != null && !rotM.IsDisposed)
if (rotM != null && !rotM.IsDisposed)
rotM.Dispose ();
if(camMatrix != null && !camMatrix.IsDisposed)
if (camMatrix != null && !camMatrix.IsDisposed)
camMatrix.Dispose ();
if(distCoeffs != null && !distCoeffs.IsDisposed)
if (distCoeffs != null && !distCoeffs.IsDisposed)
distCoeffs.Dispose ();
}
@ -160,15 +160,15 @@ namespace FaceMaskExample
float rotationY = (angles.y > 180) ? angles.y - 360 : angles.y;
float rotationZ = (tvec_z >= 0) ? (angles.z > 180) ? angles.z - 360 : angles.z : 180 - angles.z;
if(tvec_z < 0){
if (tvec_z < 0) {
rotationX = -rotationX;
rotationY = -rotationY;
rotationZ = -rotationZ;
}
return new Vector3(rotationX, rotationY, rotationZ);
return new Vector3 (rotationX, rotationY, rotationZ);
} else {
return new Vector3(0, 0, 0);
return new Vector3 (0, 0, 0);
}
}
@ -190,7 +190,7 @@ namespace FaceMaskExample
return 1.0f - rate;
}
/// <summary>
/// Extract rotation quaternion from transform matrix.
/// </summary>

Просмотреть файл

@ -1,10 +1,10 @@
using UnityEngine;
using System;
using System.Collections;
using System;
using System.Collections.Generic;
using OpenCVForUnity;
using UnityEngine;
using DlibFaceLandmarkDetector;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
namespace FaceMaskExample
{
@ -48,8 +48,8 @@ namespace FaceMaskExample
public static void DrawFaceRect (Mat imgMat, DlibFaceLandmarkDetector.FaceLandmarkDetector.RectDetection rect, Scalar color, int thickness)
{
UnityEngine.Rect _rect = rect.rect;
Imgproc.putText (imgMat, "detection_confidence : " + rect.detection_confidence, new Point (_rect.xMin, _rect.yMin - 20), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
Imgproc.putText (imgMat, "weight_index : " + rect.weight_index, new Point (_rect.xMin, _rect.yMin - 5), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
Imgproc.putText (imgMat, "detection_confidence : " + rect.detection_confidence, new Point (_rect.xMin, _rect.yMin - 20), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
Imgproc.putText (imgMat, "weight_index : " + rect.weight_index, new Point (_rect.xMin, _rect.yMin - 5), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
Imgproc.rectangle (imgMat, new Point (_rect.xMin, _rect.yMin), new Point (_rect.xMax, _rect.yMax), color, thickness);
}
@ -63,10 +63,10 @@ namespace FaceMaskExample
public static void DrawFaceRect (Mat imgMat, double[] rect, Scalar color, int thickness)
{
if (rect.Length > 4)
Imgproc.putText (imgMat, "detection_confidence : " + rect[4], new Point (rect[0], rect[1] - 20), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
Imgproc.putText (imgMat, "detection_confidence : " + rect [4], new Point (rect [0], rect [1] - 20), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
if (rect.Length > 5)
Imgproc.putText (imgMat, "weight_index : " + rect[5], new Point (rect[0], rect[1] - 5), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
Imgproc.rectangle (imgMat, new Point (rect[0], rect[1]), new Point (rect[0] + rect[2], rect[1] + rect[3]), color, thickness);
Imgproc.putText (imgMat, "weight_index : " + rect [5], new Point (rect [0], rect [1] - 5), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
Imgproc.rectangle (imgMat, new Point (rect [0], rect [1]), new Point (rect [0] + rect [2], rect [1] + rect [3]), color, thickness);
}
/// <summary>
@ -127,7 +127,7 @@ namespace FaceMaskExample
// Draw the index number of facelandmark points.
if (drawIndexNumbers) {
for (int i = 0; i < points.Count; ++i)
Imgproc.putText (imgMat, i.ToString (), new Point (points [i].x, points [i].y), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
Imgproc.putText (imgMat, i.ToString (), new Point (points [i].x, points [i].y), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
}
}
@ -189,7 +189,7 @@ namespace FaceMaskExample
// Draw the index number of facelandmark points.
if (drawIndexNumbers) {
for (int i = 0; i < points.Count; ++i)
Imgproc.putText (imgMat, i.ToString (), points [i], Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
Imgproc.putText (imgMat, i.ToString (), points [i], Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
}
}
@ -278,7 +278,7 @@ namespace FaceMaskExample
}
for (int i = 0; i < pts.Count; ++i) {
vecs.Add (new Vector2((float)pts[i].x, (float)pts[i].y));
vecs.Add (new Vector2 ((float)pts [i].x, (float)pts [i].y));
}
return vecs;
@ -324,7 +324,7 @@ namespace FaceMaskExample
}
for (int i = 0; i < vecs.Count; ++i) {
vecs [i] = new Vector2((float)arr [i * 2], (float)arr [i * 2 + 1]);
vecs [i] = new Vector2 ((float)arr [i * 2], (float)arr [i * 2 + 1]);
}
return vecs;

Просмотреть файл

@ -1,887 +0,0 @@
using OpenCVForUnity;
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Serialization;
namespace FaceMaskExample
{
/// <summary>
/// WebcamTexture to mat helper.
/// v 1.0.8
/// </summary>
public class WebCamTextureToMatHelper : MonoBehaviour
{
/// <summary>
/// Set the name of the camera device to use. (or device index number)
/// </summary>
[SerializeField, FormerlySerializedAs("requestedDeviceName"), TooltipAttribute ("Set the name of the device to use. (or device index number)")]
protected string _requestedDeviceName = null;
public virtual string requestedDeviceName {
get { return _requestedDeviceName; }
set {
_requestedDeviceName = value;
if (hasInitDone) {
Initialize ();
}
}
}
/// <summary>
/// Set the width of camera.
/// </summary>
[SerializeField, FormerlySerializedAs("requestedWidth"), TooltipAttribute ("Set the width of camera.")]
protected int _requestedWidth = 640;
public virtual int requestedWidth {
get { return _requestedWidth; }
set {
_requestedWidth = (int)Mathf.Clamp(value, 0f, float.MaxValue);
if (hasInitDone) {
Initialize ();
}
}
}
/// <summary>
/// Set the height of camera.
/// </summary>
[SerializeField, FormerlySerializedAs("requestedHeight"), TooltipAttribute ("Set the height of camera.")]
protected int _requestedHeight = 480;
public virtual int requestedHeight {
get { return _requestedHeight; }
set {
_requestedHeight = (int)Mathf.Clamp(value, 0f, float.MaxValue);
if (hasInitDone) {
Initialize ();
}
}
}
/// <summary>
/// Set whether to use the front facing camera.
/// </summary>
[SerializeField, FormerlySerializedAs("requestedIsFrontFacing"), TooltipAttribute ("Set whether to use the front facing camera.")]
protected bool _requestedIsFrontFacing = false;
public virtual bool requestedIsFrontFacing {
get { return _requestedIsFrontFacing; }
set {
_requestedIsFrontFacing = value;
if (hasInitDone) {
Initialize (_requestedIsFrontFacing, requestedFPS, rotate90Degree);
}
}
}
/// <summary>
/// Set the frame rate of camera.
/// </summary>
[SerializeField, FormerlySerializedAs("requestedFPS"), TooltipAttribute ("Set the frame rate of camera.")]
protected float _requestedFPS = 30f;
public virtual float requestedFPS {
get { return _requestedFPS; }
set {
_requestedFPS = Mathf.Clamp(value, -1f, float.MaxValue);
if (hasInitDone) {
bool isPlaying = IsPlaying ();
Stop ();
webCamTexture.requestedFPS = _requestedFPS;
if (isPlaying) Play ();
}
}
}
/// <summary>
/// Sets whether to rotate camera frame 90 degrees. (clockwise)
/// </summary>
[SerializeField, FormerlySerializedAs("rotate90Degree"), TooltipAttribute ("Sets whether to rotate camera frame 90 degrees. (clockwise)")]
protected bool _rotate90Degree = false;
public virtual bool rotate90Degree {
get { return _rotate90Degree; }
set {
_rotate90Degree = value;
if (hasInitDone) {
Initialize ();
}
}
}
/// <summary>
/// Determines if flips vertically.
/// </summary>
[SerializeField, FormerlySerializedAs("flipVertical"), TooltipAttribute ("Determines if flips vertically.")]
protected bool _flipVertical = false;
public virtual bool flipVertical {
get { return _flipVertical; }
set { _flipVertical = value; }
}
/// <summary>
/// Determines if flips horizontal.
/// </summary>
[SerializeField, FormerlySerializedAs("flipHorizontal"), TooltipAttribute ("Determines if flips horizontal.")]
protected bool _flipHorizontal = false;
public virtual bool flipHorizontal {
get { return _flipHorizontal; }
set { _flipHorizontal = value; }
}
/// <summary>
/// The number of frames before the initialization process times out.
/// </summary>
[SerializeField, FormerlySerializedAs("timeoutFrameCount"), TooltipAttribute ("The number of frames before the initialization process times out.")]
protected int _timeoutFrameCount = 300;
public virtual int timeoutFrameCount {
get { return _timeoutFrameCount; }
set { _timeoutFrameCount = (int)Mathf.Clamp(value, 0f, float.MaxValue); }
}
/// <summary>
/// UnityEvent that is triggered when this instance is initialized.
/// </summary>
public UnityEvent onInitialized;
/// <summary>
/// UnityEvent that is triggered when this instance is disposed.
/// </summary>
public UnityEvent onDisposed;
/// <summary>
/// UnityEvent that is triggered when this instance is error Occurred.
/// </summary>
public ErrorUnityEvent onErrorOccurred;
/// <summary>
/// The active WebcamTexture.
/// </summary>
protected WebCamTexture webCamTexture;
/// <summary>
/// The active WebcamDevice.
/// </summary>
protected WebCamDevice webCamDevice;
/// <summary>
/// The frame mat.
/// </summary>
protected Mat frameMat;
/// <summary>
/// The rotated frame mat
/// </summary>
protected Mat rotatedFrameMat;
/// <summary>
/// The buffer colors.
/// </summary>
protected Color32[] colors;
/// <summary>
/// Indicates whether this instance is waiting for initialization to complete.
/// </summary>
protected bool isInitWaiting = false;
/// <summary>
/// Indicates whether this instance has been initialized.
/// </summary>
protected bool hasInitDone = false;
/// <summary>
/// The initialization coroutine.
/// </summary>
protected IEnumerator initCoroutine;
/// <summary>
/// The orientation of the screen.
/// </summary>
protected ScreenOrientation screenOrientation;
/// <summary>
/// The width of the screen.
/// </summary>
protected int screenWidth;
/// <summary>
/// The height of the screen.
/// </summary>
protected int screenHeight;
[System.Serializable]
public enum ErrorCode :int
{
UNKNOWN = 0,
CAMERA_DEVICE_NOT_EXIST = 1,
TIMEOUT = 2,
}
[System.Serializable]
public class ErrorUnityEvent : UnityEngine.Events.UnityEvent<ErrorCode>
{
}
protected virtual void OnValidate()
{
_requestedWidth = (int)Mathf.Clamp(_requestedWidth, 0f, float.MaxValue);
_requestedHeight = (int)Mathf.Clamp(_requestedHeight, 0f, float.MaxValue);
_requestedFPS = Mathf.Clamp(_requestedFPS, -1f, float.MaxValue);
_timeoutFrameCount = (int)Mathf.Clamp(_timeoutFrameCount, 0f, float.MaxValue);
}
// Update is called once per frame
protected virtual void Update ()
{
if (hasInitDone) {
// Catch the orientation change of the screen and correct the mat image to the correct direction.
if (screenOrientation != Screen.orientation && (screenWidth != Screen.width || screenHeight != Screen.height)) {
if (onDisposed != null)
onDisposed.Invoke ();
if (frameMat != null) {
frameMat.Dispose ();
frameMat = null;
}
if (rotatedFrameMat != null) {
rotatedFrameMat.Dispose ();
rotatedFrameMat = null;
}
frameMat = new Mat (webCamTexture.height, webCamTexture.width, CvType.CV_8UC4);
screenOrientation = Screen.orientation;
screenWidth = Screen.width;
screenHeight = Screen.height;
bool isRotatedFrame = false;
#if !UNITY_EDITOR && !(UNITY_STANDALONE || UNITY_WEBGL)
if (screenOrientation == ScreenOrientation.Portrait || screenOrientation == ScreenOrientation.PortraitUpsideDown) {
if (!rotate90Degree)
isRotatedFrame = true;
} else if (rotate90Degree) {
isRotatedFrame = true;
}
#else
if (rotate90Degree)
isRotatedFrame = true;
#endif
if (isRotatedFrame)
rotatedFrameMat = new Mat (webCamTexture.width, webCamTexture.height, CvType.CV_8UC4);
if (onInitialized != null)
onInitialized.Invoke ();
} else {
screenWidth = Screen.width;
screenHeight = Screen.height;
}
}
}
/// <summary>
/// Raises the destroy event.
/// </summary>
protected virtual void OnDestroy ()
{
Dispose ();
}
/// <summary>
/// Initializes this instance.
/// </summary>
public virtual void Initialize ()
{
if (isInitWaiting)
{
CancelInitCoroutine ();
ReleaseResources ();
}
if (onInitialized == null)
onInitialized = new UnityEvent ();
if (onDisposed == null)
onDisposed = new UnityEvent ();
if (onErrorOccurred == null)
onErrorOccurred = new ErrorUnityEvent ();
initCoroutine = _Initialize ();
StartCoroutine (initCoroutine);
}
/// <summary>
/// Initializes this instance.
/// </summary>
/// <param name="requestedWidth">Requested width.</param>
/// <param name="requestedHeight">Requested height.</param>
public virtual void Initialize (int requestedWidth, int requestedHeight)
{
if (isInitWaiting)
{
CancelInitCoroutine ();
ReleaseResources ();
}
this._requestedWidth = requestedWidth;
this._requestedHeight = requestedHeight;
if (onInitialized == null)
onInitialized = new UnityEvent ();
if (onDisposed == null)
onDisposed = new UnityEvent ();
if (onErrorOccurred == null)
onErrorOccurred = new ErrorUnityEvent ();
initCoroutine = _Initialize ();
StartCoroutine (initCoroutine);
}
/// <summary>
/// Initializes this instance.
/// </summary>
/// <param name="requestedIsFrontFacing">If set to <c>true</c> requested to using the front camera.</param>
/// <param name="requestedFPS">Requested FPS.</param>
/// <param name="rotate90Degree">If set to <c>true</c> requested to rotate camera frame 90 degrees. (clockwise)</param>
public virtual void Initialize (bool requestedIsFrontFacing, float requestedFPS = 30f, bool rotate90Degree = false)
{
if (isInitWaiting)
{
CancelInitCoroutine ();
ReleaseResources ();
}
_requestedDeviceName = null;
this._requestedIsFrontFacing = requestedIsFrontFacing;
this._requestedFPS = requestedFPS;
this._rotate90Degree = rotate90Degree;
if (onInitialized == null)
onInitialized = new UnityEvent ();
if (onDisposed == null)
onDisposed = new UnityEvent ();
if (onErrorOccurred == null)
onErrorOccurred = new ErrorUnityEvent ();
initCoroutine = _Initialize ();
StartCoroutine (initCoroutine);
}
/// <summary>
/// Initializes this instance.
/// </summary>
/// <param name="deviceName">Device name.</param>
/// <param name="requestedWidth">Requested width.</param>
/// <param name="requestedHeight">Requested height.</param>
/// <param name="requestedIsFrontFacing">If set to <c>true</c> requested to using the front camera.</param>
/// <param name="requestedFPS">Requested FPS.</param>
/// <param name="rotate90Degree">If set to <c>true</c> requested to rotate camera frame 90 degrees. (clockwise)</param>
public virtual void Initialize (string deviceName, int requestedWidth, int requestedHeight, bool requestedIsFrontFacing = false, float requestedFPS = 30f, bool rotate90Degree = false)
{
if (isInitWaiting)
{
CancelInitCoroutine ();
ReleaseResources ();
}
this._requestedDeviceName = deviceName;
this._requestedWidth = requestedWidth;
this._requestedHeight = requestedHeight;
this._requestedIsFrontFacing = requestedIsFrontFacing;
this._requestedFPS = requestedFPS;
this._rotate90Degree = rotate90Degree;
if (onInitialized == null)
onInitialized = new UnityEvent ();
if (onDisposed == null)
onDisposed = new UnityEvent ();
if (onErrorOccurred == null)
onErrorOccurred = new ErrorUnityEvent ();
initCoroutine = _Initialize ();
StartCoroutine (initCoroutine);
}
/// <summary>
/// Initializes this instance by coroutine.
/// </summary>
protected virtual IEnumerator _Initialize ()
{
if (hasInitDone)
{
ReleaseResources ();
if (onDisposed != null)
onDisposed.Invoke ();
}
isInitWaiting = true;
// Creates the camera
if (!String.IsNullOrEmpty (requestedDeviceName)) {
int requestedDeviceIndex = -1;
if (Int32.TryParse (requestedDeviceName, out requestedDeviceIndex)) {
if (requestedDeviceIndex >= 0 && requestedDeviceIndex < WebCamTexture.devices.Length) {
webCamDevice = WebCamTexture.devices [requestedDeviceIndex];
if (requestedFPS < 0) {
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight);
} else {
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight, (int)requestedFPS);
}
}
} else {
for (int cameraIndex = 0; cameraIndex < WebCamTexture.devices.Length; cameraIndex++) {
if (WebCamTexture.devices [cameraIndex].name == requestedDeviceName) {
webCamDevice = WebCamTexture.devices [cameraIndex];
if (requestedFPS < 0) {
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight);
} else {
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight, (int)requestedFPS);
}
break;
}
}
}
if (webCamTexture == null)
Debug.Log ("Cannot find camera device " + requestedDeviceName + ".");
}
if (webCamTexture == null) {
// Checks how many and which cameras are available on the device
for (int cameraIndex = 0; cameraIndex < WebCamTexture.devices.Length; cameraIndex++) {
if (WebCamTexture.devices [cameraIndex].isFrontFacing == requestedIsFrontFacing) {
webCamDevice = WebCamTexture.devices [cameraIndex];
if (requestedFPS < 0) {
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight);
} else {
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight, (int)requestedFPS);
}
break;
}
}
}
if (webCamTexture == null) {
if (WebCamTexture.devices.Length > 0) {
webCamDevice = WebCamTexture.devices [0];
if (requestedFPS < 0) {
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight);
} else {
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight, (int)requestedFPS);
}
} else {
isInitWaiting = false;
if (onErrorOccurred != null)
onErrorOccurred.Invoke (ErrorCode.CAMERA_DEVICE_NOT_EXIST);
yield break;
}
}
// Starts the camera
webCamTexture.Play ();
int initFrameCount = 0;
bool isTimeout = false;
while (true) {
if (initFrameCount > timeoutFrameCount) {
isTimeout = true;
break;
}
// If you want to use webcamTexture.width and webcamTexture.height on iOS, you have to wait until webcamTexture.didUpdateThisFrame == 1, otherwise these two values will be equal to 16. (http://forum.unity3d.com/threads/webcamtexture-and-error-0x0502.123922/)
#if UNITY_IOS && !UNITY_EDITOR && (UNITY_4_6_3 || UNITY_4_6_4 || UNITY_5_0_0 || UNITY_5_0_1)
else if (webCamTexture.width > 16 && webCamTexture.height > 16) {
#else
else if (webCamTexture.didUpdateThisFrame) {
#if UNITY_IOS && !UNITY_EDITOR && UNITY_5_2
while (webCamTexture.width <= 16) {
if (initFrameCount > timeoutFrameCount) {
isTimeout = true;
break;
}else {
initFrameCount++;
}
webCamTexture.GetPixels32 ();
yield return new WaitForEndOfFrame ();
}
if (isTimeout) break;
#endif
#endif
Debug.Log ("WebCamTextureToMatHelper:: " + "devicename:" + webCamTexture.deviceName + " name:" + webCamTexture.name + " width:" + webCamTexture.width + " height:" + webCamTexture.height + " fps:" + webCamTexture.requestedFPS
+ " videoRotationAngle:" + webCamTexture.videoRotationAngle + " videoVerticallyMirrored:" + webCamTexture.videoVerticallyMirrored + " isFrongFacing:" + webCamDevice.isFrontFacing);
if (colors == null || colors.Length != webCamTexture.width * webCamTexture.height)
colors = new Color32[webCamTexture.width * webCamTexture.height];
frameMat = new Mat (webCamTexture.height, webCamTexture.width, CvType.CV_8UC4);
screenOrientation = Screen.orientation;
screenWidth = Screen.width;
screenHeight = Screen.height;
bool isRotatedFrame = false;
#if !UNITY_EDITOR && !(UNITY_STANDALONE || UNITY_WEBGL)
if (screenOrientation == ScreenOrientation.Portrait || screenOrientation == ScreenOrientation.PortraitUpsideDown) {
if (!rotate90Degree)
isRotatedFrame = true;
} else if (rotate90Degree) {
isRotatedFrame = true;
}
#else
if (rotate90Degree)
isRotatedFrame = true;
#endif
if (isRotatedFrame)
rotatedFrameMat = new Mat (webCamTexture.width, webCamTexture.height, CvType.CV_8UC4);
isInitWaiting = false;
hasInitDone = true;
initCoroutine = null;
if (onInitialized != null)
onInitialized.Invoke ();
break;
} else {
initFrameCount++;
yield return null;
}
}
if (isTimeout) {
webCamTexture.Stop ();
webCamTexture = null;
isInitWaiting = false;
initCoroutine = null;
if (onErrorOccurred != null)
onErrorOccurred.Invoke (ErrorCode.TIMEOUT);
}
}
/// <summary>
/// Indicates whether this instance has been initialized.
/// </summary>
/// <returns><c>true</c>, if this instance has been initialized, <c>false</c> otherwise.</returns>
public virtual bool IsInitialized ()
{
return hasInitDone;
}
/// <summary>
/// Starts the camera.
/// </summary>
public virtual void Play ()
{
if (hasInitDone)
webCamTexture.Play ();
}
/// <summary>
/// Pauses the active camera.
/// </summary>
public virtual void Pause ()
{
if (hasInitDone)
webCamTexture.Pause ();
}
/// <summary>
/// Stops the active camera.
/// </summary>
public virtual void Stop ()
{
if (hasInitDone)
webCamTexture.Stop ();
}
/// <summary>
/// Indicates whether the active camera is currently playing.
/// </summary>
/// <returns><c>true</c>, if the active camera is playing, <c>false</c> otherwise.</returns>
public virtual bool IsPlaying ()
{
return hasInitDone ? webCamTexture.isPlaying : false;
}
/// <summary>
/// Indicates whether the active camera device is currently front facng.
/// </summary>
/// <returns><c>true</c>, if the active camera device is front facng, <c>false</c> otherwise.</returns>
public virtual bool IsFrontFacing ()
{
return hasInitDone ? webCamDevice.isFrontFacing : false;
}
/// <summary>
/// Returns the active camera device name.
/// </summary>
/// <returns>The active camera device name.</returns>
public virtual string GetDeviceName ()
{
return hasInitDone ? webCamTexture.deviceName : "";
}
/// <summary>
/// Returns the active camera width.
/// </summary>
/// <returns>The active camera width.</returns>
public virtual int GetWidth ()
{
if (!hasInitDone)
return -1;
return (rotatedFrameMat != null) ? frameMat.height () : frameMat.width ();
}
/// <summary>
/// Returns the active camera height.
/// </summary>
/// <returns>The active camera height.</returns>
public virtual int GetHeight ()
{
if (!hasInitDone)
return -1;
return (rotatedFrameMat != null) ? frameMat.width () : frameMat.height ();
}
/// <summary>
/// Returns the active camera framerate.
/// </summary>
/// <returns>The active camera framerate.</returns>
public virtual float GetFPS ()
{
return hasInitDone ? webCamTexture.requestedFPS : -1f;
}
/// <summary>
/// Returns the active WebcamTexture.
/// </summary>
/// <returns>The active WebcamTexture.</returns>
public virtual WebCamTexture GetWebCamTexture ()
{
return hasInitDone ? webCamTexture : null;
}
/// <summary>
/// Returns the active WebcamDevice.
/// </summary>
/// <returns>The active WebcamDevice.</returns>
public virtual WebCamDevice GetWebCamDevice ()
{
return webCamDevice;
}
/// <summary>
/// Returns the camera to world matrix.
/// </summary>
/// <returns>The camera to world matrix.</returns>
public virtual Matrix4x4 GetCameraToWorldMatrix ()
{
return Camera.main.cameraToWorldMatrix;
}
/// <summary>
/// Returns the projection matrix matrix.
/// </summary>
/// <returns>The projection matrix.</returns>
public virtual Matrix4x4 GetProjectionMatrix ()
{
return Camera.main.projectionMatrix;
}
/// <summary>
/// Indicates whether the video buffer of the frame has been updated.
/// </summary>
/// <returns><c>true</c>, if the video buffer has been updated <c>false</c> otherwise.</returns>
public virtual bool DidUpdateThisFrame ()
{
if (!hasInitDone)
return false;
#if UNITY_IOS && !UNITY_EDITOR && (UNITY_4_6_3 || UNITY_4_6_4 || UNITY_5_0_0 || UNITY_5_0_1)
if (webCamTexture.width > 16 && webCamTexture.height > 16) {
return true;
} else {
return false;
}
#else
return webCamTexture.didUpdateThisFrame;
#endif
}
/// <summary>
/// Gets the mat of the current frame.
/// The Mat object's type is 'CV_8UC4' (RGBA).
/// </summary>
/// <returns>The mat of the current frame.</returns>
public virtual Mat GetMat ()
{
if (!hasInitDone || !webCamTexture.isPlaying) {
return (rotatedFrameMat != null) ? rotatedFrameMat : frameMat;
}
Utils.webCamTextureToMat (webCamTexture, frameMat, colors);
#if !UNITY_EDITOR && !(UNITY_STANDALONE || UNITY_WEBGL)
if (rotatedFrameMat != null) {
if (screenOrientation == ScreenOrientation.Portrait || screenOrientation == ScreenOrientation.PortraitUpsideDown) {
// (Orientation is Portrait, rotate90Degree is false)
if (webCamDevice.isFrontFacing){
FlipMat (frameMat, !flipHorizontal, !flipVertical);
}else{
FlipMat (frameMat, flipHorizontal, flipVertical);
}
} else {
// (Orientation is Landscape, rotate90Degrees=true)
FlipMat (frameMat, flipVertical, flipHorizontal);
}
Core.rotate (frameMat, rotatedFrameMat, Core.ROTATE_90_CLOCKWISE);
return rotatedFrameMat;
} else {
if (screenOrientation == ScreenOrientation.Portrait || screenOrientation == ScreenOrientation.PortraitUpsideDown) {
// (Orientation is Portrait, rotate90Degree is ture)
if (webCamDevice.isFrontFacing){
FlipMat (frameMat, flipHorizontal, flipVertical);
}else{
FlipMat (frameMat, !flipHorizontal, !flipVertical);
}
} else {
// (Orientation is Landscape, rotate90Degree is false)
FlipMat (frameMat, flipVertical, flipHorizontal);
}
return frameMat;
}
#else
FlipMat (frameMat, flipVertical, flipHorizontal);
if (rotatedFrameMat != null) {
Core.rotate (frameMat, rotatedFrameMat, Core.ROTATE_90_CLOCKWISE);
return rotatedFrameMat;
} else {
return frameMat;
}
#endif
}
/// <summary>
/// Flips the mat.
/// </summary>
/// <param name="mat">Mat.</param>
protected virtual void FlipMat (Mat mat, bool flipVertical, bool flipHorizontal)
{
int flipCode = int.MinValue;
if (webCamDevice.isFrontFacing) {
if (webCamTexture.videoRotationAngle == 0) {
flipCode = 1;
} else if (webCamTexture.videoRotationAngle == 90) {
flipCode = 1;
}
if (webCamTexture.videoRotationAngle == 180) {
flipCode = 0;
} else if (webCamTexture.videoRotationAngle == 270) {
flipCode = 0;
}
} else {
if (webCamTexture.videoRotationAngle == 180) {
flipCode = -1;
} else if (webCamTexture.videoRotationAngle == 270) {
flipCode = -1;
}
}
if (flipVertical) {
if (flipCode == int.MinValue) {
flipCode = 0;
} else if (flipCode == 0) {
flipCode = int.MinValue;
} else if (flipCode == 1) {
flipCode = -1;
} else if (flipCode == -1) {
flipCode = 1;
}
}
if (flipHorizontal) {
if (flipCode == int.MinValue) {
flipCode = 1;
} else if (flipCode == 0) {
flipCode = -1;
} else if (flipCode == 1) {
flipCode = int.MinValue;
} else if (flipCode == -1) {
flipCode = 0;
}
}
if (flipCode > int.MinValue) {
Core.flip (mat, mat, flipCode);
}
}
/// <summary>
/// Gets the buffer colors.
/// </summary>
/// <returns>The buffer colors.</returns>
public virtual Color32[] GetBufferColors ()
{
return colors;
}
/// <summary>
/// Cancel Init Coroutine.
/// </summary>
protected virtual void CancelInitCoroutine ()
{
if (initCoroutine != null) {
StopCoroutine (initCoroutine);
((IDisposable)initCoroutine).Dispose ();
initCoroutine = null;
}
}
/// <summary>
/// To release the resources.
/// </summary>
protected virtual void ReleaseResources ()
{
isInitWaiting = false;
hasInitDone = false;
if (webCamTexture != null) {
webCamTexture.Stop ();
WebCamTexture.Destroy (webCamTexture);
webCamTexture = null;
}
if (frameMat != null) {
frameMat.Dispose ();
frameMat = null;
}
if (rotatedFrameMat != null) {
rotatedFrameMat.Dispose ();
rotatedFrameMat = null;
}
}
/// <summary>
/// Releases all resource used by the <see cref="WebCamTextureToMatHelper"/> object.
/// </summary>
/// <remarks>Call <see cref="Dispose"/> when you are finished using the <see cref="WebCamTextureToMatHelper"/>. The
/// <see cref="Dispose"/> method leaves the <see cref="WebCamTextureToMatHelper"/> in an unusable state. After
/// calling <see cref="Dispose"/>, you must release all references to the <see cref="WebCamTextureToMatHelper"/> so
/// the garbage collector can reclaim the memory that the <see cref="WebCamTextureToMatHelper"/> was occupying.</remarks>
public virtual void Dispose ()
{
if (colors != null)
colors = null;
if (isInitWaiting)
{
CancelInitCoroutine ();
ReleaseResources ();
}
else if (hasInitDone)
{
ReleaseResources ();
if (onDisposed != null)
onDisposed.Invoke ();
}
}
}
}

Просмотреть файл

@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: bafc15da02fe850489635791dda2bbdf
timeCreated: 1481920838
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,14 +1,11 @@
using UnityEngine;
using System.Collections;
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
using UnityEngine.SceneManagement;
#endif
using System.Collections;
namespace FaceMaskExample
{
/// <summary>
/// Show license.
/// Show License
/// </summary>
public class ShowLicense : MonoBehaviour
{
@ -26,11 +23,7 @@ namespace FaceMaskExample
public void OnBackButtonClick ()
{
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
SceneManager.LoadScene ("FaceMaskExample");
#else
Application.LoadLevel ("FaceMaskExample");
#endif
}
}
}

Просмотреть файл

@ -5,12 +5,12 @@ using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using DlibFaceLandmarkDetector;
using OpenCVForUnity;
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
using UnityEngine.SceneManagement;
#endif
using DlibFaceLandmarkDetector;
using OpenCVForUnity.ObjdetectModule;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using Rect = OpenCVForUnity.CoreModule.Rect;
namespace FaceMaskExample
{
@ -112,19 +112,18 @@ namespace FaceMaskExample
string sp_human_face_68_dat_filepath;
#if UNITY_WEBGL && !UNITY_EDITOR
Stack<IEnumerator> coroutines = new Stack<IEnumerator> ();
IEnumerator getFilePath_Coroutine;
#endif
// Use this for initialization
void Start ()
{
#if UNITY_WEBGL && !UNITY_EDITOR
var getFilePath_Coroutine = GetFilePath ();
coroutines.Push (getFilePath_Coroutine);
getFilePath_Coroutine = GetFilePath ();
StartCoroutine (getFilePath_Coroutine);
#else
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.Utils.getFilePath ("sp_human_face_68.dat");
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.UnityUtils.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePath ("sp_human_face_68.dat");
Run ();
#endif
}
@ -132,19 +131,17 @@ namespace FaceMaskExample
#if UNITY_WEBGL && !UNITY_EDITOR
private IEnumerator GetFilePath ()
{
var getFilePathAsync_0_Coroutine = OpenCVForUnity.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
var getFilePathAsync_0_Coroutine = OpenCVForUnity.UnityUtils.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
haarcascade_frontalface_alt_xml_filepath = result;
});
coroutines.Push (getFilePathAsync_0_Coroutine);
yield return StartCoroutine (getFilePathAsync_0_Coroutine);
yield return getFilePathAsync_0_Coroutine;
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
sp_human_face_68_dat_filepath = result;
});
coroutines.Push (getFilePathAsync_1_Coroutine);
yield return StartCoroutine (getFilePathAsync_1_Coroutine);
yield return getFilePathAsync_1_Coroutine;
coroutines.Clear ();
getFilePath_Coroutine = null;
Run ();
}
@ -185,7 +182,7 @@ namespace FaceMaskExample
Mat rgbaMat = new Mat (imgTexture.height, imgTexture.width, CvType.CV_8UC4);
OpenCVForUnity.Utils.texture2DToMat (imgTexture, rgbaMat);
OpenCVForUnity.UnityUtils.Utils.texture2DToMat (imgTexture, rgbaMat);
Debug.Log ("rgbaMat ToString " + rgbaMat.ToString ());
if (faceLandmarkDetector == null)
@ -195,13 +192,13 @@ namespace FaceMaskExample
FrontalFaceChecker frontalFaceChecker = new FrontalFaceChecker (width, height);
// detect faces.
List<OpenCVForUnity.Rect> detectResult = new List<OpenCVForUnity.Rect> ();
List<Rect> detectResult = new List<Rect> ();
if (useDlibFaceDetecter) {
OpenCVForUnityUtils.SetImage (faceLandmarkDetector, rgbaMat);
List<UnityEngine.Rect> result = faceLandmarkDetector.Detect ();
foreach (var unityRect in result) {
detectResult.Add (new OpenCVForUnity.Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
detectResult.Add (new Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
}
} else {
if (cascade == null)
@ -216,13 +213,13 @@ namespace FaceMaskExample
MatOfRect faces = new MatOfRect ();
Imgproc.equalizeHist (gray, gray);
cascade.detectMultiScale (gray, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new OpenCVForUnity.Size (gray.cols () * 0.05, gray.cols () * 0.05), new Size ());
cascade.detectMultiScale (gray, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size (gray.cols () * 0.05, gray.cols () * 0.05), new Size ());
//Debug.Log ("faces " + faces.dump ());
detectResult = faces.toList ();
// adjust to Dilb's result.
foreach (OpenCVForUnity.Rect r in detectResult) {
// corrects the deviation of a detection result between OpenCV and Dlib.
foreach (Rect r in detectResult) {
r.y += (int)(r.height * 0.1f);
}
@ -296,12 +293,12 @@ namespace FaceMaskExample
// draw face rects.
if (displayFaceRects) {
int ann = face_nums[0];
int ann = face_nums [0];
UnityEngine.Rect rect_ann = new UnityEngine.Rect (detectResult [ann].x, detectResult [ann].y, detectResult [ann].width, detectResult [ann].height);
OpenCVForUnityUtils.DrawFaceRect (rgbaMat, rect_ann, new Scalar (255, 255, 0, 255), 2);
int bob = 0;
for (int i = 1; i < face_nums.Length; i ++) {
for (int i = 1; i < face_nums.Length; i++) {
bob = face_nums [i];
UnityEngine.Rect rect_bob = new UnityEngine.Rect (detectResult [bob].x, detectResult [bob].y, detectResult [bob].width, detectResult [bob].height);
OpenCVForUnityUtils.DrawFaceRect (rgbaMat, rect_bob, new Scalar (255, 0, 0, 255), 2);
@ -317,7 +314,7 @@ namespace FaceMaskExample
Texture2D texture = new Texture2D (rgbaMat.cols (), rgbaMat.rows (), TextureFormat.RGBA32, false);
OpenCVForUnity.Utils.matToTexture2D (rgbaMat, texture);
OpenCVForUnity.UnityUtils.Utils.matToTexture2D (rgbaMat, texture);
gameObject.transform.GetComponent<Renderer> ().material.mainTexture = texture;
frontalFaceChecker.Dispose ();
@ -339,9 +336,9 @@ namespace FaceMaskExample
cascade.Dispose ();
#if UNITY_WEBGL && !UNITY_EDITOR
foreach (var coroutine in coroutines) {
StopCoroutine (coroutine);
((IDisposable)coroutine).Dispose ();
if (getFilePath_Coroutine != null) {
StopCoroutine (getFilePath_Coroutine);
((IDisposable)getFilePath_Coroutine).Dispose ();
}
#endif
}
@ -351,11 +348,7 @@ namespace FaceMaskExample
/// </summary>
public void OnBackButtonClick ()
{
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
SceneManager.LoadScene ("FaceMaskExample");
#else
Application.LoadLevel ("FaceMaskExample");
#endif
}
/// <summary>
@ -411,7 +404,7 @@ namespace FaceMaskExample
if (imgTexture != null)
Run ();
}
/// <summary>
/// Raises the display face rects toggle value changed event.
/// </summary>

Просмотреть файл

@ -2563,7 +2563,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
interval: 1
poolSize: 10
_baseObject: {fileID: 1138294731141240, guid: 8b9701cb9064eeb44b641983696a9e94,
_baseObject: {fileID: 1150371196015818, guid: 8b9701cb9064eeb44b641983696a9e94,
type: 2}
--- !u!1 &2138936149
GameObject:

Просмотреть файл

@ -4,13 +4,15 @@ using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using DlibFaceLandmarkDetector;
using OpenCVForUnity;
using OpenCVForUnity.RectangleTrack;
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
using UnityEngine.SceneManagement;
#endif
using DlibFaceLandmarkDetector;
using OpenCVForUnity.RectangleTrack;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ObjdetectModule;
using OpenCVForUnity.VideoioModule;
using OpenCVForUnity.ImgprocModule;
using VideoCapture = OpenCVForUnity.VideoioModule.VideoCapture;
using Rect = OpenCVForUnity.CoreModule.Rect;
namespace FaceMaskExample
{
@ -221,7 +223,7 @@ namespace FaceMaskExample
string couple_avi_filepath;
#if UNITY_WEBGL && !UNITY_EDITOR
Stack<IEnumerator> coroutines = new Stack<IEnumerator> ();
IEnumerator getFilePath_Coroutine;
#endif
// Use this for initialization
@ -230,13 +232,12 @@ namespace FaceMaskExample
capture = new VideoCapture ();
#if UNITY_WEBGL && !UNITY_EDITOR
var getFilePath_Coroutine = GetFilePath ();
coroutines.Push (getFilePath_Coroutine);
getFilePath_Coroutine = GetFilePath ();
StartCoroutine (getFilePath_Coroutine);
#else
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.Utils.getFilePath ("sp_human_face_68.dat");
couple_avi_filepath = OpenCVForUnity.Utils.getFilePath ("dance.avi");
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.UnityUtils.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePath ("sp_human_face_68.dat");
couple_avi_filepath = OpenCVForUnity.UnityUtils.Utils.getFilePath ("dance.avi");
Run ();
#endif
}
@ -244,25 +245,22 @@ namespace FaceMaskExample
#if UNITY_WEBGL && !UNITY_EDITOR
private IEnumerator GetFilePath ()
{
var getFilePathAsync_0_Coroutine = OpenCVForUnity.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
var getFilePathAsync_0_Coroutine = OpenCVForUnity.UnityUtils.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
haarcascade_frontalface_alt_xml_filepath = result;
});
coroutines.Push (getFilePathAsync_0_Coroutine);
yield return StartCoroutine (getFilePathAsync_0_Coroutine);
yield return getFilePathAsync_0_Coroutine;
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
sp_human_face_68_dat_filepath = result;
});
coroutines.Push (getFilePathAsync_1_Coroutine);
yield return StartCoroutine (getFilePathAsync_1_Coroutine);
yield return getFilePathAsync_1_Coroutine;
var getFilePathAsync_2_Coroutine = OpenCVForUnity.Utils.getFilePathAsync ("dance.avi", (result) => {
var getFilePathAsync_2_Coroutine = OpenCVForUnity.UnityUtils.Utils.getFilePathAsync ("dance.avi", (result) => {
couple_avi_filepath = result;
});
coroutines.Push (getFilePathAsync_2_Coroutine);
yield return StartCoroutine (getFilePathAsync_2_Coroutine);
yield return getFilePathAsync_2_Coroutine;
coroutines.Clear ();
getFilePath_Coroutine = null;
Run ();
}
@ -272,13 +270,13 @@ namespace FaceMaskExample
{
meshOverlay = this.GetComponent<TrackedMeshOverlay> ();
shader_FadeID = Shader.PropertyToID("_Fade");
shader_ColorCorrectionID = Shader.PropertyToID("_ColorCorrection");
shader_LUTTexID = Shader.PropertyToID("_LUTTex");
shader_FadeID = Shader.PropertyToID ("_Fade");
shader_ColorCorrectionID = Shader.PropertyToID ("_ColorCorrection");
shader_LUTTexID = Shader.PropertyToID ("_LUTTex");
rectangleTracker = new RectangleTracker ();
frontalFaceChecker = new FrontalFaceChecker((float)frameWidth, (float)frameHeight);
frontalFaceChecker = new FrontalFaceChecker ((float)frameWidth, (float)frameHeight);
faceLandmarkDetector = new FaceLandmarkDetector (sp_human_face_68_dat_filepath);
@ -299,7 +297,6 @@ namespace FaceMaskExample
Debug.Log ("CAP_PROP_FORMAT: " + capture.get (Videoio.CAP_PROP_FORMAT));
Debug.Log ("CV_CAP_PROP_PREVIEW_FORMAT: " + capture.get (Videoio.CV_CAP_PROP_PREVIEW_FORMAT));
Debug.Log ("CAP_PROP_POS_MSEC: " + capture.get (Videoio.CAP_PROP_POS_MSEC));
Debug.Log ("CAP_PROP_POS_FRAMES: " + capture.get (Videoio.CAP_PROP_POS_FRAMES));
Debug.Log ("CAP_PROP_POS_AVI_RATIO: " + capture.get (Videoio.CAP_PROP_POS_AVI_RATIO));
@ -356,13 +353,13 @@ namespace FaceMaskExample
// detect faces.
List<OpenCVForUnity.Rect> detectResult = new List<OpenCVForUnity.Rect> ();
List<Rect> detectResult = new List<Rect> ();
if (useDlibFaceDetecter) {
OpenCVForUnityUtils.SetImage (faceLandmarkDetector, rgbMat);
List<UnityEngine.Rect> result = faceLandmarkDetector.Detect ();
foreach (var unityRect in result) {
detectResult.Add (new OpenCVForUnity.Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
detectResult.Add (new Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
}
} else {
// convert image to greyscale.
@ -372,12 +369,12 @@ namespace FaceMaskExample
using (MatOfRect faces = new MatOfRect ()) {
Imgproc.equalizeHist (grayMat, equalizeHistMat);
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new OpenCVForUnity.Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
detectResult = faces.toList ();
// adjust to Dilb's result.
foreach (OpenCVForUnity.Rect r in detectResult) {
// corrects the deviation of a detection result between OpenCV and Dlib.
foreach (Rect r in detectResult) {
r.y += (int)(r.height * 0.1f);
}
}
@ -391,11 +388,11 @@ namespace FaceMaskExample
// create noise filter.
foreach (var openCVRect in trackedRects) {
if (openCVRect.state == TrackedState.NEW) {
if (!lowPassFilterDict.ContainsKey(openCVRect.id))
lowPassFilterDict.Add (openCVRect.id, new LowPassPointsFilter((int)faceLandmarkDetector.GetShapePredictorNumParts()));
if (!opticalFlowFilterDict.ContainsKey(openCVRect.id))
opticalFlowFilterDict.Add (openCVRect.id, new OFPointsFilter((int)faceLandmarkDetector.GetShapePredictorNumParts()));
}else if (openCVRect.state == TrackedState.DELETED){
if (!lowPassFilterDict.ContainsKey (openCVRect.id))
lowPassFilterDict.Add (openCVRect.id, new LowPassPointsFilter ((int)faceLandmarkDetector.GetShapePredictorNumParts ()));
if (!opticalFlowFilterDict.ContainsKey (openCVRect.id))
opticalFlowFilterDict.Add (openCVRect.id, new OFPointsFilter ((int)faceLandmarkDetector.GetShapePredictorNumParts ()));
} else if (openCVRect.state == TrackedState.DELETED) {
if (lowPassFilterDict.ContainsKey (openCVRect.id)) {
lowPassFilterDict [openCVRect.id].Dispose ();
lowPassFilterDict.Remove (openCVRect.id);
@ -411,7 +408,7 @@ namespace FaceMaskExample
foreach (var openCVRect in trackedRects) {
if (openCVRect.state == TrackedState.NEW) {
faceMaskColorCorrector.CreateLUTTex (openCVRect.id);
}else if (openCVRect.state == TrackedState.DELETED) {
} else if (openCVRect.state == TrackedState.DELETED) {
faceMaskColorCorrector.DeleteLUTTex (openCVRect.id);
}
}
@ -496,8 +493,8 @@ namespace FaceMaskExample
for (int i = 0; i < trackedRects.Count; i++) {
UnityEngine.Rect rect = new UnityEngine.Rect (trackedRects [i].x, trackedRects [i].y, trackedRects [i].width, trackedRects [i].height);
OpenCVForUnityUtils.DrawFaceRect (rgbMat, rect, new Scalar (255, 255, 0, 255), 2);
//Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceAngles (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
//Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceRate (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
// Imgproc.putText (rgbMat, " " + frontalFaceChecker.GetFrontalFaceAngles (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
// Imgproc.putText (rgbMat, " " + frontalFaceChecker.GetFrontalFaceRate (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
}
}
@ -532,12 +529,12 @@ namespace FaceMaskExample
Imgproc.warpAffine (faceMaskMat, rgbMat, trans, rgbMat.size (), Imgproc.INTER_LINEAR, Core.BORDER_TRANSPARENT, new Scalar (0));
if (displayFaceRects || displayDebugFacePointsToggle)
OpenCVForUnity.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
OpenCVForUnity.UnityUtils.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
}
// Imgproc.putText (rgbMat, "W:" + rgbMat.width () + " H:" + rgbMat.height () + " SO:" + Screen.orientation, new Point (5, rgbMat.rows () - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255), 1, Imgproc.LINE_AA, false);
// Imgproc.putText (rgbMat, "W:" + rgbMat.width () + " H:" + rgbMat.height () + " SO:" + Screen.orientation, new Point (5, rgbMat.rows () - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255), 1, Imgproc.LINE_AA, false);
OpenCVForUnity.Utils.fastMatToTexture2D (rgbMat, texture);
OpenCVForUnity.UnityUtils.Utils.fastMatToTexture2D (rgbMat, texture);
}
}
@ -557,23 +554,23 @@ namespace FaceMaskExample
Vector3[] vertices = tm.meshFilter.mesh.vertices;
if (vertices.Length == landmarkPoints.Count) {
for (int j = 0; j < vertices.Length; j++) {
vertices [j].x = landmarkPoints[j].x / imageWidth - 0.5f;
vertices [j].y = 0.5f - landmarkPoints[j].y / imageHeight;
vertices [j].x = landmarkPoints [j].x / imageWidth - 0.5f;
vertices [j].y = 0.5f - landmarkPoints [j].y / imageHeight;
}
}
Vector2[] uv = tm.meshFilter.mesh.uv;
if (uv.Length == landmarkPointsInMaskImage.Count) {
for (int jj = 0; jj < uv.Length; jj++) {
uv [jj].x = landmarkPointsInMaskImage[jj].x / maskImageWidth;
uv [jj].y = (maskImageHeight - landmarkPointsInMaskImage[jj].y) / maskImageHeight;
uv [jj].x = landmarkPointsInMaskImage [jj].x / maskImageWidth;
uv [jj].y = (maskImageHeight - landmarkPointsInMaskImage [jj].y) / maskImageHeight;
}
}
meshOverlay.UpdateObject (tr.id, vertices, null, uv);
if (tr.numFramesNotDetected > 3) {
tm.sharedMaterial.SetFloat (shader_FadeID, 1f);
}else if (tr.numFramesNotDetected > 0 && tr.numFramesNotDetected <= 3) {
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f + (0.7f/4f) * tr.numFramesNotDetected);
} else if (tr.numFramesNotDetected > 0 && tr.numFramesNotDetected <= 3) {
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f + (0.7f / 4f) * tr.numFramesNotDetected);
} else {
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f);
}
@ -592,7 +589,7 @@ namespace FaceMaskExample
private void CorrectFaceMaskColor (int id, Mat src, Mat dst, List<Vector2> src_landmarkPoints, List<Vector2> dst_landmarkPoints)
{
Texture2D LUTTex = faceMaskColorCorrector.UpdateLUTTex(id, src, dst, src_landmarkPoints, dst_landmarkPoints);
Texture2D LUTTex = faceMaskColorCorrector.UpdateLUTTex (id, src, dst, src_landmarkPoints, dst_landmarkPoints);
TrackedMesh tm = meshOverlay.GetObjectById (id);
tm.sharedMaterial.SetTexture (shader_LUTTexID, LUTTex);
}
@ -631,9 +628,9 @@ namespace FaceMaskExample
frontalFaceChecker.Dispose ();
#if UNITY_WEBGL && !UNITY_EDITOR
foreach (var coroutine in coroutines) {
StopCoroutine (coroutine);
((IDisposable)coroutine).Dispose ();
if (getFilePath_Coroutine != null) {
StopCoroutine (getFilePath_Coroutine);
((IDisposable)getFilePath_Coroutine).Dispose ();
}
#endif
}
@ -643,11 +640,7 @@ namespace FaceMaskExample
/// </summary>
public void OnBackButtonClick ()
{
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
SceneManager.LoadScene ("FaceMaskExample");
#else
Application.LoadLevel ("FaceMaskExample");
#endif
}
/// <summary>
@ -703,7 +696,7 @@ namespace FaceMaskExample
filterNonFrontalFaces = false;
}
}
/// <summary>
/// Raises the display face rects toggle value changed event.
/// </summary>
@ -738,7 +731,7 @@ namespace FaceMaskExample
if (faceMaskDatas.Count == 0)
return;
FaceMaskData maskData = faceMaskDatas[faceMaskDataIndex];
FaceMaskData maskData = faceMaskDatas [faceMaskDataIndex];
faceMaskDataIndex = (faceMaskDataIndex < faceMaskDatas.Count - 1) ? faceMaskDataIndex + 1 : 0;
if (maskData == null) {
@ -758,20 +751,20 @@ namespace FaceMaskExample
faceMaskTexture = maskData.image;
faceMaskMat = new Mat (faceMaskTexture.height, faceMaskTexture.width, CvType.CV_8UC3);
OpenCVForUnity.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
OpenCVForUnity.UnityUtils.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
if(maskData.isDynamicMode){
if (maskData.isDynamicMode) {
faceRectInMask = DetectFace (faceMaskMat);
faceLandmarkPointsInMask = DetectFaceLandmarkPoints (faceMaskMat, faceRectInMask);
maskData.faceRect = faceRectInMask;
maskData.landmarkPoints = faceLandmarkPointsInMask;
}else{
} else {
faceRectInMask = maskData.faceRect;
faceLandmarkPointsInMask = maskData.landmarkPoints;
}
if (faceRectInMask.width == 0 && faceRectInMask.height == 0){
if (faceRectInMask.width == 0 && faceRectInMask.height == 0) {
RemoveFaceMask ();
Debug.LogError ("A face could not be detected from the input image.");
}
@ -797,7 +790,7 @@ namespace FaceMaskExample
}
*/
}
/// <summary>
/// Raises the remove face mask button click event.
/// </summary>
@ -817,7 +810,7 @@ namespace FaceMaskExample
rectangleTracker.Reset ();
meshOverlay.Reset ();
}
private UnityEngine.Rect DetectFace (Mat mat)
{
if (useDlibFaceDetecter) {
@ -834,12 +827,12 @@ namespace FaceMaskExample
Imgproc.cvtColor (mat, grayMat, Imgproc.COLOR_RGB2GRAY);
Imgproc.equalizeHist (grayMat, equalizeHistMat);
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new OpenCVForUnity.Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
List<OpenCVForUnity.Rect> faceList = faces.toList ();
List<Rect> faceList = faces.toList ();
if (faceList.Count >= 1) {
UnityEngine.Rect r = new UnityEngine.Rect (faceList [0].x, faceList [0].y, faceList [0].width, faceList [0].height);
// adjust to Dilb's result.
// corrects the deviation of a detection result between OpenCV and Dlib.
r.y += (int)(r.height * 0.1f);
return r;
}
@ -847,7 +840,7 @@ namespace FaceMaskExample
}
return new UnityEngine.Rect ();
}
private List<Vector2> DetectFaceLandmarkPoints (Mat mat, UnityEngine.Rect rect)
{
OpenCVForUnityUtils.SetImage (faceLandmarkDetector, mat);

Просмотреть файл

@ -38,7 +38,7 @@ RenderSettings:
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.37311918, g: 0.3807398, b: 0.35872716, a: 1}
m_IndirectSpecularColor: {r: 0.37311947, g: 0.38074005, b: 0.35872722, a: 1}
--- !u!157 &4
LightmapSettings:
m_ObjectHideFlags: 0
@ -2732,7 +2732,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
interval: 1
poolSize: 10
_baseObject: {fileID: 1138294731141240, guid: 8b9701cb9064eeb44b641983696a9e94,
_baseObject: {fileID: 1150371196015818, guid: 8b9701cb9064eeb44b641983696a9e94,
type: 2}
--- !u!114 &1425214148
MonoBehaviour:

Просмотреть файл

@ -4,13 +4,14 @@ using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using DlibFaceLandmarkDetector;
using OpenCVForUnity;
using OpenCVForUnity.RectangleTrack;
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
using UnityEngine.SceneManagement;
#endif
using DlibFaceLandmarkDetector;
using OpenCVForUnity.RectangleTrack;
using OpenCVForUnity.UnityUtils.Helper;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ObjdetectModule;
using OpenCVForUnity.ImgprocModule;
using Rect = OpenCVForUnity.CoreModule.Rect;
namespace FaceMaskExample
{
@ -37,7 +38,7 @@ namespace FaceMaskExample
/// </summary>
public bool extendForehead = true;
[Space(15)]
[Space (15)]
[HeaderAttribute ("FaceMaskData")]
@ -224,12 +225,8 @@ namespace FaceMaskExample
/// </summary>
FpsMonitor fpsMonitor;
#if UNITY_ANDROID && !UNITY_EDITOR
float rearCameraRequestedFPS;
#endif
#if UNITY_WEBGL && !UNITY_EDITOR
Stack<IEnumerator> coroutines = new Stack<IEnumerator> ();
IEnumerator getFilePath_Coroutine;
#endif
// Use this for initialization
@ -240,12 +237,11 @@ namespace FaceMaskExample
webCamTextureToMatHelper = gameObject.GetComponent<WebCamTextureToMatHelper> ();
#if UNITY_WEBGL && !UNITY_EDITOR
var getFilePath_Coroutine = GetFilePath ();
coroutines.Push (getFilePath_Coroutine);
getFilePath_Coroutine = GetFilePath ();
StartCoroutine (getFilePath_Coroutine);
#else
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.Utils.getFilePath ("sp_human_face_68.dat");
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.UnityUtils.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePath ("sp_human_face_68.dat");
Run ();
#endif
}
@ -253,19 +249,17 @@ namespace FaceMaskExample
#if UNITY_WEBGL && !UNITY_EDITOR
private IEnumerator GetFilePath ()
{
var getFilePathAsync_0_Coroutine = OpenCVForUnity.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
var getFilePathAsync_0_Coroutine = OpenCVForUnity.UnityUtils.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
haarcascade_frontalface_alt_xml_filepath = result;
});
coroutines.Push (getFilePathAsync_0_Coroutine);
yield return StartCoroutine (getFilePathAsync_0_Coroutine);
yield return getFilePathAsync_0_Coroutine;
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
sp_human_face_68_dat_filepath = result;
});
coroutines.Push (getFilePathAsync_1_Coroutine);
yield return StartCoroutine (getFilePathAsync_1_Coroutine);
yield return getFilePathAsync_1_Coroutine;
coroutines.Clear ();
getFilePath_Coroutine = null;
Run ();
}
@ -276,7 +270,7 @@ namespace FaceMaskExample
meshOverlay = this.GetComponent<TrackedMeshOverlay> ();
// Customize face mask.
GameObject newBaseObject = Instantiate(meshOverlay.baseObject);
GameObject newBaseObject = Instantiate (meshOverlay.baseObject);
newBaseObject.name = "CustomFaceMaskTrackedMesh";
TrackedMesh tm = newBaseObject.GetComponent<TrackedMesh> ();
@ -292,9 +286,9 @@ namespace FaceMaskExample
meshOverlay.baseObject = newBaseObject;
shader_FadeID = Shader.PropertyToID("_Fade");
shader_ColorCorrectionID = Shader.PropertyToID("_ColorCorrection");
shader_LUTTexID = Shader.PropertyToID("_LUTTex");
shader_FadeID = Shader.PropertyToID ("_Fade");
shader_ColorCorrectionID = Shader.PropertyToID ("_ColorCorrection");
shader_LUTTexID = Shader.PropertyToID ("_LUTTex");
rectangleTracker = new RectangleTracker ();
@ -306,19 +300,10 @@ namespace FaceMaskExample
faceMaskColorCorrector = new FaceMaskColorCorrector ();
#if UNITY_ANDROID && !UNITY_EDITOR
// Set the requestedFPS parameter to avoid the problem of the WebCamTexture image becoming low light on some Android devices. (Pixel, pixel 2)
// https://forum.unity.com/threads/android-webcamtexture-in-low-light-only-some-models.520656/
// https://forum.unity.com/threads/released-opencv-for-unity.277080/page-33#post-3445178
rearCameraRequestedFPS = webCamTextureToMatHelper.requestedFPS;
if (webCamTextureToMatHelper.requestedIsFrontFacing) {
webCamTextureToMatHelper.requestedFPS = 15;
webCamTextureToMatHelper.Initialize ();
} else {
webCamTextureToMatHelper.Initialize ();
}
#else
webCamTextureToMatHelper.Initialize ();
// Avoids the front camera low light issue that occurs in only some Android devices (e.g. Google Pixel, Pixel2).
webCamTextureToMatHelper.avoidAndroidFrontCameraLowLightIssue = true;
#endif
webCamTextureToMatHelper.Initialize ();
displayFaceRectsToggle.isOn = displayFaceRects;
useDlibFaceDetecterToggle.isOn = useDlibFaceDetecter;
@ -343,10 +328,10 @@ namespace FaceMaskExample
gameObject.transform.localScale = new Vector3 (webCamTextureMat.cols (), webCamTextureMat.rows (), 1);
Debug.Log ("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation);
if (fpsMonitor != null){
fpsMonitor.Add ("width", webCamTextureMat.width ().ToString());
fpsMonitor.Add ("height", webCamTextureMat.height ().ToString());
fpsMonitor.Add ("orientation", Screen.orientation.ToString());
if (fpsMonitor != null) {
fpsMonitor.Add ("width", webCamTextureMat.width ().ToString ());
fpsMonitor.Add ("height", webCamTextureMat.height ().ToString ());
fpsMonitor.Add ("orientation", Screen.orientation.ToString ());
}
@ -386,7 +371,7 @@ namespace FaceMaskExample
grayMat.Dispose ();
if (texture != null) {
Texture2D.Destroy(texture);
Texture2D.Destroy (texture);
texture = null;
}
@ -411,7 +396,8 @@ namespace FaceMaskExample
/// Raises the web cam texture to mat helper error occurred event.
/// </summary>
/// <param name="errorCode">Error code.</param>
public void OnWebCamTextureToMatHelperErrorOccurred(WebCamTextureToMatHelper.ErrorCode errorCode){
public void OnWebCamTextureToMatHelperErrorOccurred (WebCamTextureToMatHelper.ErrorCode errorCode)
{
Debug.Log ("OnWebCamTextureToMatHelperErrorOccurred " + errorCode);
}
@ -423,13 +409,13 @@ namespace FaceMaskExample
Mat rgbaMat = webCamTextureToMatHelper.GetMat ();
// detect faces.
List<OpenCVForUnity.Rect> detectResult = new List<OpenCVForUnity.Rect> ();
List<Rect> detectResult = new List<Rect> ();
if (useDlibFaceDetecter) {
OpenCVForUnityUtils.SetImage (faceLandmarkDetector, rgbaMat);
List<UnityEngine.Rect> result = faceLandmarkDetector.Detect ();
foreach (var unityRect in result) {
detectResult.Add (new OpenCVForUnity.Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
detectResult.Add (new Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
}
} else {
// convert image to greyscale.
@ -439,13 +425,13 @@ namespace FaceMaskExample
using (MatOfRect faces = new MatOfRect ()) {
Imgproc.equalizeHist (grayMat, equalizeHistMat);
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new OpenCVForUnity.Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
detectResult = faces.toList ();
}
// adjust to Dilb's result.
foreach (OpenCVForUnity.Rect r in detectResult) {
// corrects the deviation of a detection result between OpenCV and Dlib.
foreach (Rect r in detectResult) {
r.y += (int)(r.height * 0.1f);
}
}
@ -458,11 +444,11 @@ namespace FaceMaskExample
// create noise filter.
foreach (var openCVRect in trackedRects) {
if (openCVRect.state == TrackedState.NEW) {
if (!lowPassFilterDict.ContainsKey(openCVRect.id))
lowPassFilterDict.Add (openCVRect.id, new LowPassPointsFilter((int)faceLandmarkDetector.GetShapePredictorNumParts()));
if (!opticalFlowFilterDict.ContainsKey(openCVRect.id))
opticalFlowFilterDict.Add (openCVRect.id, new OFPointsFilter((int)faceLandmarkDetector.GetShapePredictorNumParts()));
}else if (openCVRect.state == TrackedState.DELETED){
if (!lowPassFilterDict.ContainsKey (openCVRect.id))
lowPassFilterDict.Add (openCVRect.id, new LowPassPointsFilter ((int)faceLandmarkDetector.GetShapePredictorNumParts ()));
if (!opticalFlowFilterDict.ContainsKey (openCVRect.id))
opticalFlowFilterDict.Add (openCVRect.id, new OFPointsFilter ((int)faceLandmarkDetector.GetShapePredictorNumParts ()));
} else if (openCVRect.state == TrackedState.DELETED) {
if (lowPassFilterDict.ContainsKey (openCVRect.id)) {
lowPassFilterDict [openCVRect.id].Dispose ();
lowPassFilterDict.Remove (openCVRect.id);
@ -478,7 +464,7 @@ namespace FaceMaskExample
foreach (var openCVRect in trackedRects) {
if (openCVRect.state == TrackedState.NEW) {
faceMaskColorCorrector.CreateLUTTex (openCVRect.id);
}else if (openCVRect.state == TrackedState.DELETED) {
} else if (openCVRect.state == TrackedState.DELETED) {
faceMaskColorCorrector.DeleteLUTTex (openCVRect.id);
}
}
@ -500,8 +486,8 @@ namespace FaceMaskExample
}
}
if (extendForehead){
AddForeheadPoints(points);
if (extendForehead) {
AddForeheadPoints (points);
}
landmarkPoints.Add (points);
@ -566,8 +552,8 @@ namespace FaceMaskExample
for (int i = 0; i < trackedRects.Count; i++) {
UnityEngine.Rect rect = new UnityEngine.Rect (trackedRects [i].x, trackedRects [i].y, trackedRects [i].width, trackedRects [i].height);
OpenCVForUnityUtils.DrawFaceRect (rgbaMat, rect, new Scalar (255, 255, 0, 255), 2);
//Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceAngles (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
//Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceRate (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
// Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceAngles (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
// Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceRate (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
}
}
@ -603,12 +589,12 @@ namespace FaceMaskExample
Imgproc.warpAffine (faceMaskMat, rgbaMat, trans, rgbaMat.size (), Imgproc.INTER_LINEAR, Core.BORDER_TRANSPARENT, new Scalar (0));
if (displayFaceRects || displayDebugFacePointsToggle)
OpenCVForUnity.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
OpenCVForUnity.UnityUtils.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
}
// Imgproc.putText (rgbaMat, "W:" + rgbaMat.width () + " H:" + rgbaMat.height () + " SO:" + Screen.orientation, new Point (5, rgbaMat.rows () - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
// Imgproc.putText (rgbaMat, "W:" + rgbaMat.width () + " H:" + rgbaMat.height () + " SO:" + Screen.orientation, new Point (5, rgbaMat.rows () - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
OpenCVForUnity.Utils.fastMatToTexture2D (rgbaMat, texture);
OpenCVForUnity.UnityUtils.Utils.fastMatToTexture2D (rgbaMat, texture);
}
}
@ -628,23 +614,23 @@ namespace FaceMaskExample
Vector3[] vertices = tm.meshFilter.mesh.vertices;
if (vertices.Length == landmarkPoints.Count) {
for (int j = 0; j < vertices.Length; j++) {
vertices [j].x = landmarkPoints[j].x / imageWidth - 0.5f;
vertices [j].y = 0.5f - landmarkPoints[j].y / imageHeight;
vertices [j].x = landmarkPoints [j].x / imageWidth - 0.5f;
vertices [j].y = 0.5f - landmarkPoints [j].y / imageHeight;
}
}
Vector2[] uv = tm.meshFilter.mesh.uv;
if (uv.Length == landmarkPointsInMaskImage.Count) {
for (int jj = 0; jj < uv.Length; jj++) {
uv [jj].x = landmarkPointsInMaskImage[jj].x / maskImageWidth;
uv [jj].y = (maskImageHeight - landmarkPointsInMaskImage[jj].y) / maskImageHeight;
uv [jj].x = landmarkPointsInMaskImage [jj].x / maskImageWidth;
uv [jj].y = (maskImageHeight - landmarkPointsInMaskImage [jj].y) / maskImageHeight;
}
}
meshOverlay.UpdateObject (tr.id, vertices, null, uv);
if (tr.numFramesNotDetected > 3) {
tm.sharedMaterial.SetFloat (shader_FadeID, 1f);
}else if (tr.numFramesNotDetected > 0 && tr.numFramesNotDetected <= 3) {
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f + (0.7f/4f) * tr.numFramesNotDetected);
} else if (tr.numFramesNotDetected > 0 && tr.numFramesNotDetected <= 3) {
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f + (0.7f / 4f) * tr.numFramesNotDetected);
} else {
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f);
}
@ -663,7 +649,7 @@ namespace FaceMaskExample
private void CorrectFaceMaskColor (int id, Mat src, Mat dst, List<Vector2> src_landmarkPoints, List<Vector2> dst_landmarkPoints)
{
Texture2D LUTTex = faceMaskColorCorrector.UpdateLUTTex(id, src, dst, src_landmarkPoints, dst_landmarkPoints);
Texture2D LUTTex = faceMaskColorCorrector.UpdateLUTTex (id, src, dst, src_landmarkPoints, dst_landmarkPoints);
TrackedMesh tm = meshOverlay.GetObjectById (id);
tm.sharedMaterial.SetTexture (shader_LUTTexID, LUTTex);
}
@ -697,9 +683,9 @@ namespace FaceMaskExample
faceMaskColorCorrector.Dispose ();
#if UNITY_WEBGL && !UNITY_EDITOR
foreach (var coroutine in coroutines) {
StopCoroutine (coroutine);
((IDisposable)coroutine).Dispose ();
if (getFilePath_Coroutine != null) {
StopCoroutine (getFilePath_Coroutine);
((IDisposable)getFilePath_Coroutine).Dispose ();
}
#endif
}
@ -709,11 +695,7 @@ namespace FaceMaskExample
/// </summary>
public void OnBackButtonClick ()
{
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
SceneManager.LoadScene ("FaceMaskExample");
#else
Application.LoadLevel ("FaceMaskExample");
#endif
}
/// <summary>
@ -737,16 +719,7 @@ namespace FaceMaskExample
/// </summary>
public void OnChangeCameraButtonClick ()
{
#if UNITY_ANDROID && !UNITY_EDITOR
if (!webCamTextureToMatHelper.IsFrontFacing ()) {
rearCameraRequestedFPS = webCamTextureToMatHelper.requestedFPS;
webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), 15, webCamTextureToMatHelper.rotate90Degree);
} else {
webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), rearCameraRequestedFPS, webCamTextureToMatHelper.rotate90Degree);
}
#else
webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.IsFrontFacing ();
#endif
webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.IsFrontFacing ();
}
/// <summary>
@ -802,7 +775,7 @@ namespace FaceMaskExample
filterNonFrontalFaces = false;
}
}
/// <summary>
/// Raises the display face rects toggle value changed event.
/// </summary>
@ -837,7 +810,7 @@ namespace FaceMaskExample
if (faceMaskDatas.Count == 0)
return;
FaceMaskData maskData = faceMaskDatas[faceMaskDataIndex];
FaceMaskData maskData = faceMaskDatas [faceMaskDataIndex];
faceMaskDataIndex = (faceMaskDataIndex < faceMaskDatas.Count - 1) ? faceMaskDataIndex + 1 : 0;
if (maskData == null) {
@ -857,26 +830,26 @@ namespace FaceMaskExample
faceMaskTexture = maskData.image;
faceMaskMat = new Mat (faceMaskTexture.height, faceMaskTexture.width, CvType.CV_8UC4);
OpenCVForUnity.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
OpenCVForUnity.UnityUtils.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
if(maskData.isDynamicMode){
if (maskData.isDynamicMode) {
faceRectInMask = DetectFace (faceMaskMat);
faceLandmarkPointsInMask = DetectFaceLandmarkPoints (faceMaskMat, faceRectInMask);
maskData.faceRect = faceRectInMask;
maskData.landmarkPoints = faceLandmarkPointsInMask;
}else{
} else {
faceRectInMask = maskData.faceRect;
faceLandmarkPointsInMask = maskData.landmarkPoints;
}
if (extendForehead) {
List<Vector2> newLandmarkPointsInMask = new List<Vector2> (faceLandmarkPointsInMask);
AddForeheadPoints(newLandmarkPointsInMask);
AddForeheadPoints (newLandmarkPointsInMask);
faceLandmarkPointsInMask = newLandmarkPointsInMask;
}
if (faceRectInMask.width == 0 && faceRectInMask.height == 0){
if (faceRectInMask.width == 0 && faceRectInMask.height == 0) {
RemoveFaceMask ();
Debug.LogError ("A face could not be detected from the input image.");
}
@ -897,34 +870,34 @@ namespace FaceMaskExample
Mat rgbaMat = webCamTextureToMatHelper.GetMat ();
faceRectInMask = DetectFace (rgbaMat);
if (faceRectInMask.width == 0 && faceRectInMask.height == 0){
if (faceRectInMask.width == 0 && faceRectInMask.height == 0) {
Debug.Log ("A face could not be detected from the input image.");
return;
}
OpenCVForUnity.Rect rect = new OpenCVForUnity.Rect((int)faceRectInMask.x, (int)faceRectInMask.y, (int)faceRectInMask.width, (int)faceRectInMask.height);
rect.inflate(rect.x/5, rect.y/5);
rect = rect.intersect(new OpenCVForUnity.Rect(0,0,rgbaMat.width(),rgbaMat.height()));
Rect rect = new Rect ((int)faceRectInMask.x, (int)faceRectInMask.y, (int)faceRectInMask.width, (int)faceRectInMask.height);
rect.inflate (rect.x / 5, rect.y / 5);
rect = rect.intersect (new Rect (0, 0, rgbaMat.width (), rgbaMat.height ()));
faceMaskTexture = new Texture2D (rect.width, rect.height, TextureFormat.RGBA32, false);
faceMaskMat = new Mat(rgbaMat, rect).clone ();
OpenCVForUnity.Utils.matToTexture2D(faceMaskMat, faceMaskTexture);
faceMaskMat = new Mat (rgbaMat, rect).clone ();
OpenCVForUnity.UnityUtils.Utils.matToTexture2D (faceMaskMat, faceMaskTexture);
Debug.Log ("faceMaskMat ToString " + faceMaskMat.ToString ());
faceRectInMask = DetectFace (faceMaskMat);
faceLandmarkPointsInMask = DetectFaceLandmarkPoints (faceMaskMat, faceRectInMask);
if (extendForehead) {
AddForeheadPoints(faceLandmarkPointsInMask);
AddForeheadPoints (faceLandmarkPointsInMask);
}
if (faceRectInMask.width == 0 && faceRectInMask.height == 0){
if (faceRectInMask.width == 0 && faceRectInMask.height == 0) {
RemoveFaceMask ();
Debug.Log ("A face could not be detected from the input image.");
}
}
}
/// <summary>
/// Raises the remove face mask button click event.
/// </summary>
@ -944,7 +917,7 @@ namespace FaceMaskExample
rectangleTracker.Reset ();
meshOverlay.Reset ();
}
private UnityEngine.Rect DetectFace (Mat mat)
{
if (useDlibFaceDetecter) {
@ -961,12 +934,12 @@ namespace FaceMaskExample
Imgproc.cvtColor (mat, grayMat, Imgproc.COLOR_RGBA2GRAY);
Imgproc.equalizeHist (grayMat, equalizeHistMat);
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new OpenCVForUnity.Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
List<OpenCVForUnity.Rect> faceList = faces.toList ();
List<Rect> faceList = faces.toList ();
if (faceList.Count >= 1) {
UnityEngine.Rect r = new UnityEngine.Rect (faceList [0].x, faceList [0].y, faceList [0].width, faceList [0].height);
// adjust to Dilb's result.
// corrects the deviation of a detection result between OpenCV and Dlib.
r.y += (int)(r.height * 0.1f);
return r;
}
@ -983,41 +956,40 @@ namespace FaceMaskExample
return points;
}
private void ExtendForehead(Mesh mesh)
private void ExtendForehead (Mesh mesh)
{
if (mesh.vertices.Length != 68)
throw new ArgumentException ("Invalid face mask mesh", "mesh");
List<Vector2> verticesList = new List<Vector2> (mesh.vertices.Length);
foreach (Vector3 v in mesh.vertices) {
verticesList.Add(new Vector2(v.x, v.y));
verticesList.Add (new Vector2 (v.x, v.y));
}
AddForeheadPoints (verticesList);
Vector3[] vertices = new Vector3[verticesList.Count];
for (int i = 0; i < vertices.Length; i++) {
vertices[i] = new Vector3(verticesList[i].x, verticesList[i].y);
vertices [i] = new Vector3 (verticesList [i].x, verticesList [i].y);
}
mesh.vertices = vertices;
int[] foreheadTriangles = new int[13 * 3]
{
68,16,26,
68,26,25,
69,68,25,
69,25,24,
69,24,23,
70,69,23,
int[] foreheadTriangles = new int[13 * 3] {
68, 16, 26,
68, 26, 25,
69, 68, 25,
69, 25, 24,
69, 24, 23,
70, 69, 23,
70,23,20,
70, 23, 20,
71,70,20,
71,20,19,
71,19,18,
72,71,18,
72,18,17,
72,17,0
71, 70, 20,
71, 20, 19,
71, 19, 18,
72, 71, 18,
72, 18, 17,
72, 17, 0
};
int[] triangles = new int[mesh.triangles.Length + foreheadTriangles.Length];
mesh.triangles.CopyTo (triangles, 0);
@ -1026,8 +998,8 @@ namespace FaceMaskExample
Vector2[] uv = new Vector2[mesh.uv.Length];
for (int j = 0; j < uv.Length; j++) {
uv [j].x = vertices[j].x + 0.5f;
uv [j].y = vertices[j].y + 0.5f;
uv [j].x = vertices [j].x + 0.5f;
uv [j].y = vertices [j].y + 0.5f;
}
mesh.uv = uv;
mesh.uv2 = (Vector2[])uv.Clone ();
@ -1035,19 +1007,19 @@ namespace FaceMaskExample
mesh.RecalculateNormals ();
}
private void AddForeheadPoints(List<Vector2> points)
private void AddForeheadPoints (List<Vector2> points)
{
if (points.Count != 68)
throw new ArgumentException ("Invalid face landmark points", "points");
Vector2 noseLength = new Vector2(points[27].x - points[30].x, points[27].y - points[30].y);
Vector2 glabellaPoint = new Vector2((points[19].x + points[24].x)/2f, (points[19].y + points[24].y)/2f);
Vector2 noseLength = new Vector2 (points [27].x - points [30].x, points [27].y - points [30].y);
Vector2 glabellaPoint = new Vector2 ((points [19].x + points [24].x) / 2f, (points [19].y + points [24].y) / 2f);
points.Add (new Vector2(points[26].x + noseLength.x*0.8f, points[26].y + noseLength.y*0.8f));
points.Add (new Vector2(points[24].x + noseLength.x, points[24].y + noseLength.y));
points.Add (new Vector2(glabellaPoint.x + noseLength.x*1.1f, glabellaPoint.y + noseLength.y*1.1f));
points.Add (new Vector2(points[19].x + noseLength.x, points[19].y + noseLength.y));
points.Add (new Vector2(points[17].x + noseLength.x*0.8f, points[17].y + noseLength.y*0.8f));
points.Add (new Vector2 (points [26].x + noseLength.x * 0.8f, points [26].y + noseLength.y * 0.8f));
points.Add (new Vector2 (points [24].x + noseLength.x, points [24].y + noseLength.y));
points.Add (new Vector2 (glabellaPoint.x + noseLength.x * 1.1f, glabellaPoint.y + noseLength.y * 1.1f));
points.Add (new Vector2 (points [19].x + noseLength.x, points [19].y + noseLength.y));
points.Add (new Vector2 (points [17].x + noseLength.x * 0.8f, points [17].y + noseLength.y * 0.8f));
}
private static void DrawFaceLandmark (Mat imgMat, List<Vector2> points, Scalar color, int thickness)
@ -1086,109 +1058,113 @@ namespace FaceMaskExample
for (int i = 69; i <= 72; ++i)
Imgproc.line (imgMat, new Point (points [i].x, points [i].y), new Point (points [i - 1].x, points [i - 1].y), new Scalar (0, 255, 0, 255), thickness);
} else {
OpenCVForUnityUtils.DrawFaceLandmark(imgMat, points, color, thickness);
OpenCVForUnityUtils.DrawFaceLandmark (imgMat, points, color, thickness);
}
}
private Texture2D CreateFaceMaskAlphaMaskTexture(float width, float height, Vector2[] uv, bool makeBothEyesTransparent = true, bool makeMouthTransparent = true)
private Texture2D CreateFaceMaskAlphaMaskTexture (float width, float height, Vector2[] uv, bool makeBothEyesTransparent = true, bool makeMouthTransparent = true)
{
if (uv.Length != 68 && uv.Length != 73)
throw new ArgumentException ("Invalid face landmark points", "uv");
Vector2[] facialContourUVPoints = new Vector2[0];
if(uv.Length == 68){
facialContourUVPoints = new Vector2[]{
uv[0],
uv[1],
uv[2],
uv[3],
uv[4],
uv[5],
uv[6],
uv[7],
uv[8],
uv[9],
uv[10],
uv[11],
uv[12],
uv[13],
uv[14],
uv[15],
uv[16],
uv[26],
uv[25],
uv[24],
uv[23],
uv[20],
uv[19],
uv[18],
uv[17]
if (uv.Length == 68) {
facialContourUVPoints = new Vector2[] {
uv [0],
uv [1],
uv [2],
uv [3],
uv [4],
uv [5],
uv [6],
uv [7],
uv [8],
uv [9],
uv [10],
uv [11],
uv [12],
uv [13],
uv [14],
uv [15],
uv [16],
uv [26],
uv [25],
uv [24],
uv [23],
uv [20],
uv [19],
uv [18],
uv [17]
};
}else if (uv.Length == 73){ // If landmark points of forehead exists.
facialContourUVPoints = new Vector2[]{
uv[0],
uv[1],
uv[2],
uv[3],
uv[4],
uv[5],
uv[6],
uv[7],
uv[8],
uv[9],
uv[10],
uv[11],
uv[12],
uv[13],
uv[14],
uv[15],
uv[16],
uv[68],
uv[69],
uv[70],
uv[71],
uv[72]
} else if (uv.Length == 73) { // If landmark points of forehead exists.
facialContourUVPoints = new Vector2[] {
uv [0],
uv [1],
uv [2],
uv [3],
uv [4],
uv [5],
uv [6],
uv [7],
uv [8],
uv [9],
uv [10],
uv [11],
uv [12],
uv [13],
uv [14],
uv [15],
uv [16],
uv [68],
uv [69],
uv [70],
uv [71],
uv [72]
};
}
Vector2[] rightEyeContourUVPoints = new Vector2[]{
uv[36],
uv[37],
uv[38],
uv[39],
uv[40],
uv[41]
Vector2[] rightEyeContourUVPoints = new Vector2[] {
uv [36],
uv [37],
uv [38],
uv [39],
uv [40],
uv [41]
};
Vector2[] leftEyeContourUVPoints = new Vector2[]{
uv[42],
uv[43],
uv[44],
uv[45],
uv[46],
uv[47]
Vector2[] leftEyeContourUVPoints = new Vector2[] {
uv [42],
uv [43],
uv [44],
uv [45],
uv [46],
uv [47]
};
Vector2[] mouthContourUVPoints = new Vector2[]{
uv[60],
uv[61],
uv[62],
uv[63],
uv[64],
uv[65],
uv[66],
uv[67]
Vector2[] mouthContourUVPoints = new Vector2[] {
uv [60],
uv [61],
uv [62],
uv [63],
uv [64],
uv [65],
uv [66],
uv [67]
};
Vector2[][] exclusionAreas;
if (makeBothEyesTransparent == true && makeMouthTransparent == false) {
exclusionAreas = new Vector2[][]{rightEyeContourUVPoints, leftEyeContourUVPoints};
exclusionAreas = new Vector2[][]{ rightEyeContourUVPoints, leftEyeContourUVPoints };
} else if (makeBothEyesTransparent == false && makeMouthTransparent == true) {
exclusionAreas = new Vector2[][]{mouthContourUVPoints};
exclusionAreas = new Vector2[][]{ mouthContourUVPoints };
} else if (makeBothEyesTransparent == true && makeMouthTransparent == true) {
exclusionAreas = new Vector2[][]{rightEyeContourUVPoints, leftEyeContourUVPoints, mouthContourUVPoints};
exclusionAreas = new Vector2[][] {
rightEyeContourUVPoints,
leftEyeContourUVPoints,
mouthContourUVPoints
};
} else {
exclusionAreas = new Vector2[][]{};
exclusionAreas = new Vector2[][]{ };
}
return AlphaMaskTextureCreater.CreateAlphaMaskTexture (width, height, facialContourUVPoints, exclusionAreas);

Просмотреть файл

@ -3094,7 +3094,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
interval: 1
poolSize: 10
_baseObject: {fileID: 1138294731141240, guid: 8b9701cb9064eeb44b641983696a9e94,
_baseObject: {fileID: 1150371196015818, guid: 8b9701cb9064eeb44b641983696a9e94,
type: 2}
--- !u!114 &1362053830
MonoBehaviour:
@ -3104,7 +3104,7 @@ MonoBehaviour:
m_GameObject: {fileID: 1362053823}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bafc15da02fe850489635791dda2bbdf, type: 3}
m_Script: {fileID: 11500000, guid: df35b0c19ca97734e87299a664cea35f, type: 3}
m_Name:
m_EditorClassIdentifier:
_requestedDeviceName:
@ -3162,8 +3162,9 @@ MonoBehaviour:
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
m_TypeName: FaceMaskExample.WebCamTextureToMatHelper+ErrorUnityEvent, Assembly-CSharp,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
m_TypeName: OpenCVForUnity.UnityUtils.Helper.WebCamTextureToMatHelper+ErrorUnityEvent,
Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
avoidAndroidFrontCameraLowLightIssue: 0
--- !u!114 &1362053831
MonoBehaviour:
m_ObjectHideFlags: 0

Просмотреть файл

@ -4,13 +4,14 @@ using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using DlibFaceLandmarkDetector;
using OpenCVForUnity;
using OpenCVForUnity.RectangleTrack;
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
using UnityEngine.SceneManagement;
#endif
using DlibFaceLandmarkDetector;
using OpenCVForUnity.RectangleTrack;
using OpenCVForUnity.UnityUtils.Helper;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ObjdetectModule;
using OpenCVForUnity.ImgprocModule;
using Rect = OpenCVForUnity.CoreModule.Rect;
namespace FaceMaskExample
{
@ -205,12 +206,8 @@ namespace FaceMaskExample
/// </summary>
FpsMonitor fpsMonitor;
#if UNITY_ANDROID && !UNITY_EDITOR
float rearCameraRequestedFPS;
#endif
#if UNITY_WEBGL && !UNITY_EDITOR
Stack<IEnumerator> coroutines = new Stack<IEnumerator> ();
IEnumerator getFilePath_Coroutine;
#endif
// Use this for initialization
@ -221,12 +218,11 @@ namespace FaceMaskExample
webCamTextureToMatHelper = gameObject.GetComponent<WebCamTextureToMatHelper> ();
#if UNITY_WEBGL && !UNITY_EDITOR
var getFilePath_Coroutine = GetFilePath ();
coroutines.Push (getFilePath_Coroutine);
getFilePath_Coroutine = GetFilePath ();
StartCoroutine (getFilePath_Coroutine);
#else
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.Utils.getFilePath ("sp_human_face_68.dat");
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.UnityUtils.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePath ("sp_human_face_68.dat");
Run ();
#endif
}
@ -234,19 +230,17 @@ namespace FaceMaskExample
#if UNITY_WEBGL && !UNITY_EDITOR
private IEnumerator GetFilePath ()
{
var getFilePathAsync_0_Coroutine = OpenCVForUnity.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
var getFilePathAsync_0_Coroutine = OpenCVForUnity.UnityUtils.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
haarcascade_frontalface_alt_xml_filepath = result;
});
coroutines.Push (getFilePathAsync_0_Coroutine);
yield return StartCoroutine (getFilePathAsync_0_Coroutine);
yield return getFilePathAsync_0_Coroutine;
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
sp_human_face_68_dat_filepath = result;
});
coroutines.Push (getFilePathAsync_1_Coroutine);
yield return StartCoroutine (getFilePathAsync_1_Coroutine);
yield return getFilePathAsync_1_Coroutine;
coroutines.Clear ();
getFilePath_Coroutine = null;
Run ();
}
@ -256,9 +250,9 @@ namespace FaceMaskExample
{
meshOverlay = this.GetComponent<TrackedMeshOverlay> ();
shader_FadeID = Shader.PropertyToID("_Fade");
shader_ColorCorrectionID = Shader.PropertyToID("_ColorCorrection");
shader_LUTTexID = Shader.PropertyToID("_LUTTex");
shader_FadeID = Shader.PropertyToID ("_Fade");
shader_ColorCorrectionID = Shader.PropertyToID ("_ColorCorrection");
shader_LUTTexID = Shader.PropertyToID ("_LUTTex");
rectangleTracker = new RectangleTracker ();
@ -270,19 +264,10 @@ namespace FaceMaskExample
faceMaskColorCorrector = new FaceMaskColorCorrector ();
#if UNITY_ANDROID && !UNITY_EDITOR
// Set the requestedFPS parameter to avoid the problem of the WebCamTexture image becoming low light on some Android devices. (Pixel, pixel 2)
// https://forum.unity.com/threads/android-webcamtexture-in-low-light-only-some-models.520656/
// https://forum.unity.com/threads/released-opencv-for-unity.277080/page-33#post-3445178
rearCameraRequestedFPS = webCamTextureToMatHelper.requestedFPS;
if (webCamTextureToMatHelper.requestedIsFrontFacing) {
webCamTextureToMatHelper.requestedFPS = 15;
webCamTextureToMatHelper.Initialize ();
} else {
webCamTextureToMatHelper.Initialize ();
}
#else
webCamTextureToMatHelper.Initialize ();
// Avoids the front camera low light issue that occurs in only some Android devices (e.g. Google Pixel, Pixel2).
webCamTextureToMatHelper.avoidAndroidFrontCameraLowLightIssue = true;
#endif
webCamTextureToMatHelper.Initialize ();
displayFaceRectsToggle.isOn = displayFaceRects;
useDlibFaceDetecterToggle.isOn = useDlibFaceDetecter;
@ -307,10 +292,10 @@ namespace FaceMaskExample
gameObject.transform.localScale = new Vector3 (webCamTextureMat.cols (), webCamTextureMat.rows (), 1);
Debug.Log ("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation);
if (fpsMonitor != null){
fpsMonitor.Add ("width", webCamTextureMat.width ().ToString());
fpsMonitor.Add ("height", webCamTextureMat.height ().ToString());
fpsMonitor.Add ("orientation", Screen.orientation.ToString());
if (fpsMonitor != null) {
fpsMonitor.Add ("width", webCamTextureMat.width ().ToString ());
fpsMonitor.Add ("height", webCamTextureMat.height ().ToString ());
fpsMonitor.Add ("orientation", Screen.orientation.ToString ());
}
@ -350,7 +335,7 @@ namespace FaceMaskExample
grayMat.Dispose ();
if (texture != null) {
Texture2D.Destroy(texture);
Texture2D.Destroy (texture);
texture = null;
}
@ -375,7 +360,8 @@ namespace FaceMaskExample
/// Raises the web cam texture to mat helper error occurred event.
/// </summary>
/// <param name="errorCode">Error code.</param>
public void OnWebCamTextureToMatHelperErrorOccurred(WebCamTextureToMatHelper.ErrorCode errorCode){
public void OnWebCamTextureToMatHelperErrorOccurred (WebCamTextureToMatHelper.ErrorCode errorCode)
{
Debug.Log ("OnWebCamTextureToMatHelperErrorOccurred " + errorCode);
}
@ -388,13 +374,13 @@ namespace FaceMaskExample
Mat rgbaMat = webCamTextureToMatHelper.GetMat ();
// detect faces.
List<OpenCVForUnity.Rect> detectResult = new List<OpenCVForUnity.Rect> ();
List<Rect> detectResult = new List<Rect> ();
if (useDlibFaceDetecter) {
OpenCVForUnityUtils.SetImage (faceLandmarkDetector, rgbaMat);
List<UnityEngine.Rect> result = faceLandmarkDetector.Detect ();
foreach (var unityRect in result) {
detectResult.Add (new OpenCVForUnity.Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
detectResult.Add (new Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
}
} else {
// convert image to greyscale.
@ -404,13 +390,13 @@ namespace FaceMaskExample
using (MatOfRect faces = new MatOfRect ()) {
Imgproc.equalizeHist (grayMat, equalizeHistMat);
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new OpenCVForUnity.Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
detectResult = faces.toList ();
}
// adjust to Dilb's result.
foreach (OpenCVForUnity.Rect r in detectResult) {
// corrects the deviation of a detection result between OpenCV and Dlib.
foreach (Rect r in detectResult) {
r.y += (int)(r.height * 0.1f);
}
}
@ -424,11 +410,11 @@ namespace FaceMaskExample
// create noise filter.
foreach (var openCVRect in trackedRects) {
if (openCVRect.state == TrackedState.NEW) {
if (!lowPassFilterDict.ContainsKey(openCVRect.id))
lowPassFilterDict.Add (openCVRect.id, new LowPassPointsFilter((int)faceLandmarkDetector.GetShapePredictorNumParts()));
if (!opticalFlowFilterDict.ContainsKey(openCVRect.id))
opticalFlowFilterDict.Add (openCVRect.id, new OFPointsFilter((int)faceLandmarkDetector.GetShapePredictorNumParts()));
}else if (openCVRect.state == TrackedState.DELETED){
if (!lowPassFilterDict.ContainsKey (openCVRect.id))
lowPassFilterDict.Add (openCVRect.id, new LowPassPointsFilter ((int)faceLandmarkDetector.GetShapePredictorNumParts ()));
if (!opticalFlowFilterDict.ContainsKey (openCVRect.id))
opticalFlowFilterDict.Add (openCVRect.id, new OFPointsFilter ((int)faceLandmarkDetector.GetShapePredictorNumParts ()));
} else if (openCVRect.state == TrackedState.DELETED) {
if (lowPassFilterDict.ContainsKey (openCVRect.id)) {
lowPassFilterDict [openCVRect.id].Dispose ();
lowPassFilterDict.Remove (openCVRect.id);
@ -444,7 +430,7 @@ namespace FaceMaskExample
foreach (var openCVRect in trackedRects) {
if (openCVRect.state == TrackedState.NEW) {
faceMaskColorCorrector.CreateLUTTex (openCVRect.id);
}else if (openCVRect.state == TrackedState.DELETED) {
} else if (openCVRect.state == TrackedState.DELETED) {
faceMaskColorCorrector.DeleteLUTTex (openCVRect.id);
}
}
@ -528,8 +514,8 @@ namespace FaceMaskExample
for (int i = 0; i < trackedRects.Count; i++) {
UnityEngine.Rect rect = new UnityEngine.Rect (trackedRects [i].x, trackedRects [i].y, trackedRects [i].width, trackedRects [i].height);
OpenCVForUnityUtils.DrawFaceRect (rgbaMat, rect, new Scalar (255, 255, 0, 255), 2);
//Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceAngles (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
//Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceRate (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
// Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceAngles (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
// Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceRate (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
}
}
@ -565,12 +551,12 @@ namespace FaceMaskExample
Imgproc.warpAffine (faceMaskMat, rgbaMat, trans, rgbaMat.size (), Imgproc.INTER_LINEAR, Core.BORDER_TRANSPARENT, new Scalar (0));
if (displayFaceRects || displayDebugFacePointsToggle)
OpenCVForUnity.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
OpenCVForUnity.UnityUtils.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
}
// Imgproc.putText (rgbaMat, "W:" + rgbaMat.width () + " H:" + rgbaMat.height () + " SO:" + Screen.orientation, new Point (5, rgbaMat.rows () - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
// Imgproc.putText (rgbaMat, "W:" + rgbaMat.width () + " H:" + rgbaMat.height () + " SO:" + Screen.orientation, new Point (5, rgbaMat.rows () - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
OpenCVForUnity.Utils.fastMatToTexture2D (rgbaMat, texture);
OpenCVForUnity.UnityUtils.Utils.fastMatToTexture2D (rgbaMat, texture);
}
}
@ -590,23 +576,23 @@ namespace FaceMaskExample
Vector3[] vertices = tm.meshFilter.mesh.vertices;
if (vertices.Length == landmarkPoints.Count) {
for (int j = 0; j < vertices.Length; j++) {
vertices [j].x = landmarkPoints[j].x / imageWidth - 0.5f;
vertices [j].y = 0.5f - landmarkPoints[j].y / imageHeight;
vertices [j].x = landmarkPoints [j].x / imageWidth - 0.5f;
vertices [j].y = 0.5f - landmarkPoints [j].y / imageHeight;
}
}
Vector2[] uv = tm.meshFilter.mesh.uv;
if (uv.Length == landmarkPointsInMaskImage.Count) {
for (int jj = 0; jj < uv.Length; jj++) {
uv [jj].x = landmarkPointsInMaskImage[jj].x / maskImageWidth;
uv [jj].y = (maskImageHeight - landmarkPointsInMaskImage[jj].y) / maskImageHeight;
uv [jj].x = landmarkPointsInMaskImage [jj].x / maskImageWidth;
uv [jj].y = (maskImageHeight - landmarkPointsInMaskImage [jj].y) / maskImageHeight;
}
}
meshOverlay.UpdateObject (tr.id, vertices, null, uv);
if (tr.numFramesNotDetected > 3) {
tm.sharedMaterial.SetFloat (shader_FadeID, 1f);
}else if (tr.numFramesNotDetected > 0 && tr.numFramesNotDetected <= 3) {
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f + (0.7f/4f) * tr.numFramesNotDetected);
} else if (tr.numFramesNotDetected > 0 && tr.numFramesNotDetected <= 3) {
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f + (0.7f / 4f) * tr.numFramesNotDetected);
} else {
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f);
}
@ -625,7 +611,7 @@ namespace FaceMaskExample
private void CorrectFaceMaskColor (int id, Mat src, Mat dst, List<Vector2> src_landmarkPoints, List<Vector2> dst_landmarkPoints)
{
Texture2D LUTTex = faceMaskColorCorrector.UpdateLUTTex(id, src, dst, src_landmarkPoints, dst_landmarkPoints);
Texture2D LUTTex = faceMaskColorCorrector.UpdateLUTTex (id, src, dst, src_landmarkPoints, dst_landmarkPoints);
TrackedMesh tm = meshOverlay.GetObjectById (id);
tm.sharedMaterial.SetTexture (shader_LUTTexID, LUTTex);
}
@ -659,9 +645,9 @@ namespace FaceMaskExample
faceMaskColorCorrector.Dispose ();
#if UNITY_WEBGL && !UNITY_EDITOR
foreach (var coroutine in coroutines) {
StopCoroutine (coroutine);
((IDisposable)coroutine).Dispose ();
if (getFilePath_Coroutine != null) {
StopCoroutine (getFilePath_Coroutine);
((IDisposable)getFilePath_Coroutine).Dispose ();
}
#endif
}
@ -671,11 +657,7 @@ namespace FaceMaskExample
/// </summary>
public void OnBackButtonClick ()
{
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
SceneManager.LoadScene ("FaceMaskExample");
#else
Application.LoadLevel ("FaceMaskExample");
#endif
}
/// <summary>
@ -699,16 +681,7 @@ namespace FaceMaskExample
/// </summary>
public void OnChangeCameraButtonClick ()
{
#if UNITY_ANDROID && !UNITY_EDITOR
if (!webCamTextureToMatHelper.IsFrontFacing ()) {
rearCameraRequestedFPS = webCamTextureToMatHelper.requestedFPS;
webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), 15, webCamTextureToMatHelper.rotate90Degree);
} else {
webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), rearCameraRequestedFPS, webCamTextureToMatHelper.rotate90Degree);
}
#else
webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.IsFrontFacing ();
#endif
webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.IsFrontFacing ();
}
/// <summary>
@ -764,7 +737,7 @@ namespace FaceMaskExample
filterNonFrontalFaces = false;
}
}
/// <summary>
/// Raises the display face rects toggle value changed event.
/// </summary>
@ -799,7 +772,7 @@ namespace FaceMaskExample
if (faceMaskDatas.Count == 0)
return;
FaceMaskData maskData = faceMaskDatas[faceMaskDataIndex];
FaceMaskData maskData = faceMaskDatas [faceMaskDataIndex];
faceMaskDataIndex = (faceMaskDataIndex < faceMaskDatas.Count - 1) ? faceMaskDataIndex + 1 : 0;
if (maskData == null) {
@ -819,20 +792,20 @@ namespace FaceMaskExample
faceMaskTexture = maskData.image;
faceMaskMat = new Mat (faceMaskTexture.height, faceMaskTexture.width, CvType.CV_8UC4);
OpenCVForUnity.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
OpenCVForUnity.UnityUtils.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
if(maskData.isDynamicMode){
if (maskData.isDynamicMode) {
faceRectInMask = DetectFace (faceMaskMat);
faceLandmarkPointsInMask = DetectFaceLandmarkPoints (faceMaskMat, faceRectInMask);
maskData.faceRect = faceRectInMask;
maskData.landmarkPoints = faceLandmarkPointsInMask;
}else{
} else {
faceRectInMask = maskData.faceRect;
faceLandmarkPointsInMask = maskData.landmarkPoints;
}
if (faceRectInMask.width == 0 && faceRectInMask.height == 0){
if (faceRectInMask.width == 0 && faceRectInMask.height == 0) {
RemoveFaceMask ();
Debug.LogError ("A face could not be detected from the input image.");
}
@ -853,30 +826,30 @@ namespace FaceMaskExample
Mat rgbaMat = webCamTextureToMatHelper.GetMat ();
faceRectInMask = DetectFace (rgbaMat);
if (faceRectInMask.width == 0 && faceRectInMask.height == 0){
if (faceRectInMask.width == 0 && faceRectInMask.height == 0) {
Debug.Log ("A face could not be detected from the input image.");
return;
}
OpenCVForUnity.Rect rect = new OpenCVForUnity.Rect((int)faceRectInMask.x, (int)faceRectInMask.y, (int)faceRectInMask.width, (int)faceRectInMask.height);
rect.inflate(rect.x/5, rect.y/5);
rect = rect.intersect(new OpenCVForUnity.Rect(0,0,rgbaMat.width(),rgbaMat.height()));
Rect rect = new Rect ((int)faceRectInMask.x, (int)faceRectInMask.y, (int)faceRectInMask.width, (int)faceRectInMask.height);
rect.inflate (rect.x / 5, rect.y / 5);
rect = rect.intersect (new Rect (0, 0, rgbaMat.width (), rgbaMat.height ()));
faceMaskTexture = new Texture2D (rect.width, rect.height, TextureFormat.RGBA32, false);
faceMaskMat = new Mat(rgbaMat, rect).clone ();
OpenCVForUnity.Utils.matToTexture2D(faceMaskMat, faceMaskTexture);
faceMaskMat = new Mat (rgbaMat, rect).clone ();
OpenCVForUnity.UnityUtils.Utils.matToTexture2D (faceMaskMat, faceMaskTexture);
Debug.Log ("faceMaskMat ToString " + faceMaskMat.ToString ());
faceRectInMask = DetectFace (faceMaskMat);
faceLandmarkPointsInMask = DetectFaceLandmarkPoints (faceMaskMat, faceRectInMask);
if (faceRectInMask.width == 0 && faceRectInMask.height == 0){
if (faceRectInMask.width == 0 && faceRectInMask.height == 0) {
RemoveFaceMask ();
Debug.Log ("A face could not be detected from the input image.");
}
}
}
/// <summary>
/// Raises the remove face mask button click event.
/// </summary>
@ -896,7 +869,7 @@ namespace FaceMaskExample
rectangleTracker.Reset ();
meshOverlay.Reset ();
}
private UnityEngine.Rect DetectFace (Mat mat)
{
if (useDlibFaceDetecter) {
@ -913,12 +886,12 @@ namespace FaceMaskExample
Imgproc.cvtColor (mat, grayMat, Imgproc.COLOR_RGBA2GRAY);
Imgproc.equalizeHist (grayMat, equalizeHistMat);
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new OpenCVForUnity.Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
List<OpenCVForUnity.Rect> faceList = faces.toList ();
List<Rect> faceList = faces.toList ();
if (faceList.Count >= 1) {
UnityEngine.Rect r = new UnityEngine.Rect (faceList [0].x, faceList [0].y, faceList [0].width, faceList [0].height);
// adjust to Dilb's result.
// corrects the deviation of a detection result between OpenCV and Dlib.
r.y += (int)(r.height * 0.1f);
return r;
}

Просмотреть файл

@ -3032,7 +3032,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
interval: 1
poolSize: 10
_baseObject: {fileID: 1138294731141240, guid: 8b9701cb9064eeb44b641983696a9e94,
_baseObject: {fileID: 1150371196015818, guid: 8b9701cb9064eeb44b641983696a9e94,
type: 2}
--- !u!114 &1362053830
MonoBehaviour:
@ -3042,7 +3042,7 @@ MonoBehaviour:
m_GameObject: {fileID: 1362053823}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bafc15da02fe850489635791dda2bbdf, type: 3}
m_Script: {fileID: 11500000, guid: df35b0c19ca97734e87299a664cea35f, type: 3}
m_Name:
m_EditorClassIdentifier:
_requestedDeviceName:
@ -3100,8 +3100,9 @@ MonoBehaviour:
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
m_TypeName: FaceMaskExample.WebCamTextureToMatHelper+ErrorUnityEvent, Assembly-CSharp,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
m_TypeName: OpenCVForUnity.UnityUtils.Helper.WebCamTextureToMatHelper+ErrorUnityEvent,
Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
avoidAndroidFrontCameraLowLightIssue: 0
--- !u!114 &1362053831
MonoBehaviour:
m_ObjectHideFlags: 0

Просмотреть файл

@ -3,7 +3,12 @@ FaceMask Example
Overview
-----
<https://www.assetstore.unity3d.com/#!/content/79999>
[https://assetstore.unity.com/packages/templates/tutorials/facemask-example-79999](https://assetstore.unity.com/packages/templates/tutorials/facemask-example-79999?aid=1011l4ehR)
Environment
-----
[OpenCVForUnity](https://assetstore.unity.com/packages/tools/integration/opencv-for-unity-21088?aid=1011l4ehR)
[DlibFaceLandmarkDetector](https://assetstore.unity.com/packages/tools/integration/dlib-facelandmark-detector-64314?aid=1011l4ehR)
Demo Video
-----