This commit is contained in:
EnoxSoftware 2020-12-30 02:34:31 +09:00
Родитель 33d73abe73
Коммит 5f4576a907
37 изменённых файлов: 5495 добавлений и 3484 удалений

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

@ -1,10 +1,9 @@
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace FaceMaskExample
{
[CustomEditor (typeof(FaceMaskData))]
[CustomEditor(typeof(FaceMaskData))]
public class FaceMaskDataEditor : Editor
{
SerializedProperty image;
@ -16,176 +15,191 @@ 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));
Rect imageRect = GUILayoutUtility.GetLastRect ();
GUI.DrawTexture (imageRect, tex);
if (tex != null)
{
GUILayout.Box(GUIContent.none, GUILayout.Width(tex.width), GUILayout.Height(tex.height));
Rect imageRect = GUILayoutUtility.GetLastRect();
GUI.DrawTexture(imageRect, tex);
if (!isDynamicMode.boolValue) {
if (!isDynamicMode.boolValue)
{
// Draw face rect.
DrawFaceRect (imageRect, faceRect.rectValue, Color.red);
DrawFaceRect(imageRect, faceRect.rectValue, Color.red);
// Draw landmark points.
DrawFaceLandmark (imageRect, landmarkPoints, Color.green, Color.blue);
DrawFaceLandmark(imageRect, landmarkPoints, Color.green, Color.blue);
// Update mouse cursor.
for (int i = 0; i < landmarkPoints.arraySize; i++) {
Vector2 pt = landmarkPoints.GetArrayElementAtIndex (i).vector2Value;
for (int i = 0; i < landmarkPoints.arraySize; i++)
{
Vector2 pt = landmarkPoints.GetArrayElementAtIndex(i).vector2Value;
pt.x += imageRect.x;
pt.y += imageRect.y;
Rect r = new Rect (pt.x - 4, pt.y - 4, 8, 8);
EditorGUIUtility.AddCursorRect (r, MouseCursor.MoveArrow);
Rect r = new Rect(pt.x - 4, pt.y - 4, 8, 8);
EditorGUIUtility.AddCursorRect(r, MouseCursor.MoveArrow);
}
// Mouse event.
if (Event.current.type == EventType.MouseDown) {
Rect mousePosRect = new Rect (Event.current.mousePosition.x - 4, Event.current.mousePosition.y - 4, 8, 8);
int id = GetPointID (imageRect, landmarkPoints, mousePosRect);
if (id >= 0) {
if (Event.current.type == EventType.MouseDown)
{
Rect mousePosRect = new Rect(Event.current.mousePosition.x - 4, Event.current.mousePosition.y - 4, 8, 8);
int id = GetPointID(imageRect, landmarkPoints, mousePosRect);
if (id >= 0)
{
isDrag = true;
currentPointID = id;
}
Repaint ();
Repaint();
}
if (Event.current.type == EventType.MouseDrag) {
if (isDrag && currentPointID >= 0) {
Vector2 newPt = new Vector2 (Event.current.mousePosition.x - imageRect.x, Event.current.mousePosition.y - imageRect.y);
newPt.x = Mathf.Clamp (newPt.x, 0, tex.width);
newPt.y = Mathf.Clamp (newPt.y, 0, tex.height);
landmarkPoints.GetArrayElementAtIndex (currentPointID).vector2Value = newPt;
if (Event.current.type == EventType.MouseDrag)
{
if (isDrag && currentPointID >= 0)
{
Vector2 newPt = new Vector2(Event.current.mousePosition.x - imageRect.x, Event.current.mousePosition.y - imageRect.y);
newPt.x = Mathf.Clamp(newPt.x, 0, tex.width);
newPt.y = Mathf.Clamp(newPt.y, 0, tex.height);
landmarkPoints.GetArrayElementAtIndex(currentPointID).vector2Value = newPt;
if (!imageRect.Contains (Event.current.mousePosition)) {
if (!imageRect.Contains(Event.current.mousePosition))
{
isDrag = false;
currentPointID = -1;
}
}
Repaint ();
Repaint();
}
if (Event.current.type == EventType.MouseUp) {
if (isDrag && currentPointID >= 0) {
Vector2 newPt = new Vector2 (Event.current.mousePosition.x - imageRect.x, Event.current.mousePosition.y - imageRect.y);
newPt.x = Mathf.Clamp (newPt.x, 0, tex.width);
newPt.y = Mathf.Clamp (newPt.y, 0, tex.height);
landmarkPoints.GetArrayElementAtIndex (currentPointID).vector2Value = newPt;
if (Event.current.type == EventType.MouseUp)
{
if (isDrag && currentPointID >= 0)
{
Vector2 newPt = new Vector2(Event.current.mousePosition.x - imageRect.x, Event.current.mousePosition.y - imageRect.y);
newPt.x = Mathf.Clamp(newPt.x, 0, tex.width);
newPt.y = Mathf.Clamp(newPt.y, 0, tex.height);
landmarkPoints.GetArrayElementAtIndex(currentPointID).vector2Value = newPt;
}
isDrag = false;
currentPointID = -1;
Repaint ();
Repaint();
}
if (currentPointID > -1 && currentPointID < landmarkPoints.arraySize) {
Vector2 pt = landmarkPoints.GetArrayElementAtIndex (currentPointID).vector2Value;
if (currentPointID > -1 && currentPointID < landmarkPoints.arraySize)
{
Vector2 pt = landmarkPoints.GetArrayElementAtIndex(currentPointID).vector2Value;
pt.x += imageRect.x;
pt.y += imageRect.y;
Handles.color = Color.yellow;
Handles.DrawSolidDisc (pt, Vector3.forward, 3f);
Handles.DrawSolidDisc(pt, Vector3.forward, 3f);
}
}
}
// 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)
private void DrawFaceRect(Rect imageRect, Rect faceRect, Color color)
{
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)
private void DrawFaceLandmark(Rect imageRect, SerializedProperty landmarkPoints, Color lineColor, Color pointColor)
{
if (landmarkPoints.isArray && landmarkPoints.arraySize == 68) {
if (landmarkPoints.isArray && landmarkPoints.arraySize == 68)
{
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;
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);
Handles.DrawSolidDisc(pt, Vector3.forward, 2f);
}
}
}
private void DrawLine (Rect imageRect, Vector2 pt1, Vector2 pt2)
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;
Handles.DrawLine (pt1, pt2);
Handles.DrawLine(pt1, pt2);
}
private int GetPointID (Rect imageRect, SerializedProperty landmarkPoints, Rect rect)
private int GetPointID(Rect imageRect, SerializedProperty landmarkPoints, Rect rect)
{
if (landmarkPoints.isArray && landmarkPoints.arraySize == 68) {
for (int i = 0; i < landmarkPoints.arraySize; i++) {
Vector2 pt = landmarkPoints.GetArrayElementAtIndex (i).vector2Value;
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))
if (rect.Contains(pt))
return i;
}

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

@ -1,11 +1,8 @@
#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 UnityEditor;
using UnityEngine;
namespace FaceMaskExample
{
@ -14,23 +11,23 @@ namespace FaceMaskExample
/// <summary>
/// Create face mask tracked mesh prefab.
/// </summary>
[MenuItem ("Tools/Face Mask Example/Create Face Mask Prefab")]
private static void CreateFaceMaskPrefab ()
[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 ();
meshFilter.mesh = new Mesh();
Mesh mesh = meshFilter.sharedMesh;
mesh.name = "DlibFaceLandmark68Mesh";
// Mesh_vertices
Vector3[] vertices = new Vector3[68] {
new Vector3 (117, 250),
@ -116,13 +113,14 @@ namespace FaceMaskExample
new Vector3 (242, 383)
};
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;
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;
}
mesh.vertices = vertices2;
// Mesh_triangles
int[] triangles = new int[327] {
// Around the right eye 21
@ -219,7 +217,7 @@ namespace FaceMaskExample
34, 35, 52,
33, 34, 52,
33, 52, 51,
48, 49, 60,
48, 60, 59,
49, 50, 61,
@ -250,25 +248,26 @@ namespace FaceMaskExample
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;
for (int j = 0; j < uv.Length; j++)
{
uv[j].x = vertices[j].x / width;
uv[j].y = (height - vertices[j].y) / height;
}
mesh.uv = uv;
mesh.uv2 = (Vector2[])uv.Clone ();
mesh.uv2 = (Vector2[])uv.Clone();
mesh.RecalculateNormals ();
mesh.RecalculateNormals();
// Add Collider Component.
MeshCollider meshCollider = newObj.AddComponent<MeshCollider> ();
meshCollider.sharedMesh = CreatePrimitiveQuadMesh ();
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[] {
@ -330,78 +329,99 @@ namespace FaceMaskExample
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);
AssetDatabase.ImportAsset (alphaMaskTexturePath, ImportAssetOptions.ForceUpdate);
AssetDatabase.SaveAssets ();
if (CreateWithoutFolder(basePath))
{
File.WriteAllBytes(alphaMaskTexturePath, pngData);
AssetDatabase.ImportAsset(alphaMaskTexturePath, ImportAssetOptions.ForceUpdate);
AssetDatabase.SaveAssets();
Debug.Log("Create asset \"" + basePath + "FaceMaskAlphaMask.png\"");
}
TextureImporter importer = TextureImporter.GetAtPath (alphaMaskTexturePath) as TextureImporter;
TextureImporter importer = TextureImporter.GetAtPath(alphaMaskTexturePath) as TextureImporter;
importer.textureType = TextureImporterType.Default;
importer.mipmapEnabled = false;
importer.wrapMode = TextureWrapMode.Clamp;
importer.maxTextureSize = 1024;
// importer.textureFormat = TextureImporterFormat.RGBA16;
EditorUtility.SetDirty (importer);
AssetDatabase.ImportAsset (alphaMaskTexturePath, ImportAssetOptions.ForceUpdate);
AssetDatabase.SaveAssets ();
//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;
material.SetTexture ("_MaskTex", alphaMaskTexture);
GameObject.DestroyImmediate(alphaMaskTexture);
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)) {
AssetDatabase.CreateAsset (material, basePath + "FaceMaskMaterial.mat");
AssetDatabase.CreateAsset (mesh, basePath + "DlibFaceLandmark68Mesh.asset");
AssetDatabase.SaveAssets ();
if (CreateWithoutFolder(basePath))
{
AssetDatabase.CreateAsset(material, basePath + "FaceMaskMaterial.mat");
AssetDatabase.CreateAsset(mesh, basePath + "DlibFaceLandmark68Mesh.asset");
AssetDatabase.SaveAssets();
UnityEngine.Object prefab = AssetDatabase.LoadAssetAtPath (basePath + "FaceMaskTrackedMesh.prefab", typeof(UnityEngine.Object));
if (prefab == null) {
UnityEditor.PrefabUtility.CreatePrefab (basePath + "FaceMaskTrackedMesh.prefab", newObj);
} else {
UnityEditor.PrefabUtility.ReplacePrefab (newObj, prefab);
string prefab_path = basePath + "FaceMaskTrackedMesh.prefab";
#if UNITY_2018_3_OR_NEWER
PrefabUtility.SaveAsPrefabAsset(newObj, prefab_path);
#else
UnityEngine.Object prefab = AssetDatabase.LoadAssetAtPath(prefab_path, typeof(UnityEngine.Object));
if (prefab == null)
{
PrefabUtility.CreatePrefab(prefab_path, newObj);
}
AssetDatabase.SaveAssets ();
else
{
PrefabUtility.ReplacePrefab(newObj, prefab);
}
#endif
AssetDatabase.SaveAssets();
Debug.Log("Create asset \"" + basePath + "FaceMaskMaterial.mat\"");
Debug.Log("Create asset \"" + basePath + "DlibFaceLandmark68Mesh.asset\"");
Debug.Log("Create asset \"" + basePath + "FaceMaskTrackedMesh.prefab\"");
}
GameObject.DestroyImmediate (newObj);
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)
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 (Directory.Exists(checkFolder + "/") != true)
{
AssetDatabase.CreateFolder(baseFolder, folder);
}
checkFolder += "/";
}

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

@ -1,8 +1,7 @@
using System.Collections;
using OpenCVForUnity.CoreModule;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using OpenCVForUnity.CoreModule;
namespace FaceMaskExample
{
@ -17,79 +16,79 @@ namespace FaceMaskExample
static float verticalNormalizedPosition = 1f;
// Use this for initialization
void Start ()
void Start()
{
exampleTitle.text = "FaceMask Example " + Application.version;
versionInfo.text = Core.NATIVE_LIBRARY_NAME + " " + OpenCVForUnity.UnityUtils.Utils.getVersion () + " (" + Core.VERSION + ")";
versionInfo.text += " / " + "dlibfacelandmarkdetector" + " " + DlibFaceLandmarkDetector.UnityUtils.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 += " / ";
#if UNITY_EDITOR
#if UNITY_EDITOR
versionInfo.text += "Editor";
#elif UNITY_STANDALONE_WIN
#elif UNITY_STANDALONE_WIN
versionInfo.text += "Windows";
#elif UNITY_STANDALONE_OSX
#elif UNITY_STANDALONE_OSX
versionInfo.text += "Mac OSX";
#elif UNITY_STANDALONE_LINUX
#elif UNITY_STANDALONE_LINUX
versionInfo.text += "Linux";
#elif UNITY_ANDROID
#elif UNITY_ANDROID
versionInfo.text += "Android";
#elif UNITY_IOS
#elif UNITY_IOS
versionInfo.text += "iOS";
#elif UNITY_WSA
#elif UNITY_WSA
versionInfo.text += "WSA";
#elif UNITY_WEBGL
#elif UNITY_WEBGL
versionInfo.text += "WebGL";
#endif
#endif
versionInfo.text += " ";
#if ENABLE_MONO
#if ENABLE_MONO
versionInfo.text += "Mono";
#elif ENABLE_IL2CPP
#elif ENABLE_IL2CPP
versionInfo.text += "IL2CPP";
#elif ENABLE_DOTNET
#elif ENABLE_DOTNET
versionInfo.text += ".NET";
#endif
#endif
scrollRect.verticalNormalizedPosition = verticalNormalizedPosition;
}
// Update is called once per frame
void Update ()
void Update()
{
}
public void OnScrollRectValueChanged ()
public void OnScrollRectValueChanged()
{
verticalNormalizedPosition = scrollRect.verticalNormalizedPosition;
}
public void OnShowLicenseButtonClick ()
public void OnShowLicenseButtonClick()
{
SceneManager.LoadScene ("ShowLicense");
SceneManager.LoadScene("ShowLicense");
}
public void OnTexture2DFaceMaskExampleButtonClick ()
public void OnTexture2DFaceMaskExampleButtonClick()
{
SceneManager.LoadScene ("Texture2DFaceMaskExample");
SceneManager.LoadScene("Texture2DFaceMaskExample");
}
public void OnVideoCaptureFaceMaskExampleButtonClick ()
public void OnVideoCaptureFaceMaskExampleButtonClick()
{
SceneManager.LoadScene ("VideoCaptureFaceMaskExample");
SceneManager.LoadScene("VideoCaptureFaceMaskExample");
}
public void OnWebCamTextureFaceMaskExampleButtonClick ()
public void OnWebCamTextureFaceMaskExampleButtonClick()
{
SceneManager.LoadScene ("WebCamTextureFaceMaskExample");
SceneManager.LoadScene("WebCamTextureFaceMaskExample");
}
public void OnWebCamTextureFaceMaskAdditionalExampleButtonClick ()
public void OnWebCamTextureFaceMaskAdditionalExampleButtonClick()
{
SceneManager.LoadScene ("WebCamTextureFaceMaskAdditionalExample");
SceneManager.LoadScene("WebCamTextureFaceMaskAdditionalExample");
}
}
}

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -1,8 +1,7 @@
fileFormatVersion: 2
guid: 67f7db10ac869ee479d4495c3d7af34d
timeCreated: 1563459566
licenseType: Free
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 4300000
userData:
assetBundleName:

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

@ -1,10 +1,9 @@
fileFormatVersion: 2
guid: 470faf94133e4a741bb9abe37e1dfb1f
timeCreated: 1563459565
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
@ -12,6 +11,8 @@ TextureImporter:
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
@ -20,6 +21,8 @@ TextureImporter:
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
@ -27,10 +30,13 @@ TextureImporter:
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapMode: 1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
@ -39,30 +45,44 @@ TextureImporter:
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 1024
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

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

@ -4,8 +4,9 @@
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: FaceMaskMaterial
m_Shader: {fileID: 4800000, guid: 007b092c44f554a4698c59144e1a2b7f, type: 3}
m_ShaderKeywords:

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

@ -1,8 +1,7 @@
fileFormatVersion: 2
guid: 61fa2fcb482ca224e991e0be29d75304
timeCreated: 1563459565
licenseType: Free
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:

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

@ -1,22 +1,12 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1615476950310458}
m_IsPrefabParent: 1
--- !u!1 &1615476950310458
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4924589846472214}
- component: {fileID: 33685472964065464}
@ -32,9 +22,10 @@ GameObject:
m_IsActive: 1
--- !u!4 &4924589846472214
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1615476950310458}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
@ -43,18 +34,44 @@ Transform:
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &33685472964065464
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1615476950310458}
m_Mesh: {fileID: 4300000, guid: 67f7db10ac869ee479d4495c3d7af34d, type: 2}
--- !u!64 &64284030821688990
MeshCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1615476950310458}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 3
m_Convex: 0
m_CookingOptions: 14
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &23560507476807706
MeshRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1615476950310458}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 61fa2fcb482ca224e991e0be29d75304, type: 2}
m_StaticBatchInfo:
@ -67,6 +84,7 @@ MeshRenderer:
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
@ -75,32 +93,12 @@ MeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!33 &33685472964065464
MeshFilter:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1615476950310458}
m_Mesh: {fileID: 4300000, guid: 67f7db10ac869ee479d4495c3d7af34d, type: 2}
--- !u!64 &64284030821688990
MeshCollider:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1615476950310458}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Convex: 0
m_InflateMesh: 0
m_SkinWidth: 0.01
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
--- !u!114 &114170669961178786
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1615476950310458}
m_Enabled: 1
m_EditorHideFlags: 0

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

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

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

@ -1,8 +1,8 @@
using System;
using OpenCVForUnity.CoreModule;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using OpenCVForUnity.CoreModule;
using Rect = OpenCVForUnity.CoreModule.Rect;
namespace OpenCVForUnity.RectangleTrack
@ -10,22 +10,26 @@ 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.3
/// v 1.0.4
/// </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;
}
@ -34,44 +38,53 @@ namespace OpenCVForUnity.RectangleTrack
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> ();
private List<float> _weightsPositionsSmoothing = new List<float>();
public List<float> weightsSizesSmoothing {
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> ();
private List<float> _weightsSizesSmoothing = new List<float>();
public RectangleTracker (TrackerParameters trackerParamerers = null)
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
@ -81,66 +94,76 @@ 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;
@ -149,82 +172,101 @@ namespace OpenCVForUnity.RectangleTrack
//if (numpositions > 0) UnityEngine.Debug.LogError("numpositions > 0 is false");
//OpenCVRect prevRect = curObject.lastPositions[numpositions - 1];
Rect prevRect = correctionRects [i];
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");
}
}
@ -232,187 +274,225 @@ 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 ();
/*
if (r.area() == 0)
{
Debug.Log("DetectionBasedTracker::process: ERROR: ATTENTION: strange algorithm's behavior: trackedObjects[i].rect() is empty");
continue;
}
*/
Rect r = _trackedObjects[i].lastPositions[n - 1].clone();
//if (r.area() == 0)
//{
// Debug.Log("DetectionBasedTracker::process: ERROR: ATTENTION: strange algorithm's behavior: trackedObjects[i].rect() is empty");
// continue;
//}
//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,
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)
public Rect[] CreateRawRects()
{
return new Point (r.x + (r.width / 2), r.y + (r.height / 2));
Rect[] rectsWhereRegions = new Rect[_trackedObjects.Count];
int count = _trackedObjects.Count;
for (int i = 0; i < count; i++)
{
rectsWhereRegions[i] = _trackedObjects[i].position;
}
return rectsWhereRegions;
}
private Rect GetSmoothingRect (int i)
private Point CenterRect(Rect r)
{
return new Point(r.x + (r.width / 2), r.y + (r.height / 2));
}
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)
{
int r1 = (int)(a.width / 2.0f);
int r2 = (int)(b.width / 2.0f);
int px1 = a.x + r1;
int py1 = a.y + r1;
int px2 = b.x + r2;
int py2 = b.y + r2;
if ((px2 - px1) * (px2 - px1) + (py2 - py1) * (py2 - py1) <= (r1 + r2) * (r1 + r2) * coeffRectangleOverlap)
return true;
else
return false;
}
*/
private bool IsCollideByRectangle (Rect a, Rect b, float coeffRectangleOverlap)
//private bool IsCollideByCircle(Rect a, Rect b, float coeffRectangleOverlap)
//{
// int r1 = (int)(a.width / 2.0f);
// int r2 = (int)(b.width / 2.0f);
// int px1 = a.x + r1;
// int py1 = a.y + r1;
// int px2 = b.x + r2;
// int py2 = b.y + r2;
// if ((px2 - px1) * (px2 - px1) + (py2 - py1) * (py2 - py1) <= (r1 + r2) * (r1 + r2) * coeffRectangleOverlap)
// return true;
// else
// return false;
//}
private bool IsCollideByRectangle(Rect a, Rect b, float coeffRectangleOverlap)
{
int mw = (int)(a.width * coeffRectangleOverlap);
int mh = (int)(a.height * coeffRectangleOverlap);
@ -434,9 +514,9 @@ namespace OpenCVForUnity.RectangleTrack
return false;
}
public void Dispose ()
public void Dispose()
{
Reset ();
Reset();
}
}
}

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

@ -22,27 +22,28 @@ namespace OpenCVForUnity.RectangleTrack
public int id;
public TrackedState state;
public 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 (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;

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

@ -9,8 +9,8 @@ namespace OpenCVForUnity.RectangleTrack
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;

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

@ -12,13 +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,9 +1,8 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using System;
using System.Collections.Generic;
using UnityEngine;
using Rect = OpenCVForUnity.CoreModule.Rect;
namespace FaceMaskExample
@ -17,159 +16,172 @@ namespace FaceMaskExample
Point[] src_facialContourPoints;
Point[] dst_facialContourPoints;
public FaceMaskColorCorrector ()
public FaceMaskColorCorrector()
{
LUTTexDict = new Dictionary<int, Texture2D> ();
LUTTexDict = new Dictionary<int, Texture2D>();
src_facialContourPoints = new Point[9];
for (int i = 0; i < src_facialContourPoints.Length; i++) {
src_facialContourPoints [i] = new Point ();
for (int i = 0; i < src_facialContourPoints.Length; i++)
{
src_facialContourPoints[i] = new Point();
}
dst_facialContourPoints = new Point[9];
for (int i = 0; i < dst_facialContourPoints.Length; i++) {
dst_facialContourPoints [i] = new Point ();
for (int i = 0; i < dst_facialContourPoints.Length; i++)
{
dst_facialContourPoints[i] = new Point();
}
}
public virtual void CreateLUTTex (int id)
public virtual void CreateLUTTex(int id)
{
if (!LUTTexDict.ContainsKey (id))
LUTTexDict.Add (id, new Texture2D (256, 1, TextureFormat.RGB24, false));
if (!LUTTexDict.ContainsKey(id))
LUTTexDict.Add(id, new Texture2D(256, 1, TextureFormat.RGB24, false));
}
public virtual Texture2D UpdateLUTTex (int id, Mat src, Mat dst, List<Vector2> src_landmarkPoints, List<Vector2> dst_landmarkPoints)
public virtual Texture2D UpdateLUTTex(int id, Mat src, Mat dst, List<Vector2> src_landmarkPoints, List<Vector2> dst_landmarkPoints)
{
if (src_mask != null && (src.width () != src_mask.width () || src.height () != src_mask.height ())) {
src_mask.Dispose ();
if (src_mask != null && (src.width() != src_mask.width() || src.height() != src_mask.height()))
{
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 ();
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);
GetFacialContourPoints(src_landmarkPoints, src_facialContourPoints);
GetFacialContourPoints(dst_landmarkPoints, dst_facialContourPoints);
// Get facial contour rect.
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 ()));
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);
Mat src_mask_ROI = new Mat (src_mask, src_facialContourRect);
Mat dst_mask_ROI = new Mat (dst_mask, dst_facialContourRect);
Mat src_ROI = new Mat(src, src_facialContourRect);
Mat dst_ROI = new Mat(dst, dst_facialContourRect);
Mat src_mask_ROI = new Mat(src_mask, src_facialContourRect);
Mat dst_mask_ROI = new Mat(dst_mask, dst_facialContourRect);
GetPointsInFrame (src_mask_ROI, src_facialContourPoints, src_facialContourPoints);
GetPointsInFrame (dst_mask_ROI, dst_facialContourPoints, dst_facialContourPoints);
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];
} else {
LUTTex = new Texture2D (256, 1, TextureFormat.RGB24, false);
LUTTexDict.Add (id, LUTTex);
if (LUTTexDict.ContainsKey(id))
{
LUTTex = LUTTexDict[id];
}
else
{
LUTTex = new Texture2D(256, 1, TextureFormat.RGB24, false);
LUTTexDict.Add(id, LUTTex);
}
FaceMaskShaderUtils.CalculateLUT (src_ROI, dst_ROI, src_mask_ROI, dst_mask_ROI, LUTTex);
FaceMaskShaderUtils.CalculateLUT(src_ROI, dst_ROI, src_mask_ROI, dst_mask_ROI, LUTTex);
return LUTTex;
}
public virtual void DeleteLUTTex (int id)
public virtual void DeleteLUTTex(int id)
{
if (LUTTexDict.ContainsKey (id)) {
Texture2D.Destroy (LUTTexDict [id]);
LUTTexDict.Remove (id);
if (LUTTexDict.ContainsKey(id))
{
Texture2D.Destroy(LUTTexDict[id]);
LUTTexDict.Remove(id);
}
}
public virtual Texture2D GetLUTTex (int id)
public virtual Texture2D GetLUTTex(int id)
{
if (LUTTexDict.ContainsKey (id)) {
return LUTTexDict [id];
if (LUTTexDict.ContainsKey(id))
{
return LUTTexDict[id];
}
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++) {
dst_points [i].x = points [i].x - ofs.x;
dst_points [i].y = points [i].y - ofs.y;
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;
}
}
public virtual void Reset ()
public virtual void Reset()
{
foreach (var key in LUTTexDict.Keys) {
Texture2D.Destroy (LUTTexDict [key]);
foreach (var key in LUTTexDict.Keys)
{
Texture2D.Destroy(LUTTexDict[key]);
}
LUTTexDict.Clear ();
LUTTexDict.Clear();
}
public virtual void Dispose ()
public virtual void Dispose()
{
if (src_mask != null) {
src_mask.Dispose ();
if (src_mask != null)
{
src_mask.Dispose();
src_mask = null;
}
if (dst_mask != null) {
dst_mask.Dispose ();
if (dst_mask != null)
{
dst_mask.Dispose();
dst_mask = null;
}
Reset ();
Reset();
}
}
}

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

@ -1,55 +1,56 @@
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Collections;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.UnityUtils;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.UtilsModule;
using System;
using UnityEngine;
namespace FaceMaskExample
{
public class FaceMaskShaderUtils
{
// 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)
public static void CalculateLUT(Mat src, Mat dst, Mat src_mask, Mat dst_mask, Texture2D LUTTex)
{
if (src.channels () < 3)
throw new ArgumentException ("src.channels() < 3");
if (src.channels() < 3)
throw new ArgumentException("src.channels() < 3");
if (dst.channels () < 3)
throw new ArgumentException ("dst.channels() < 3");
if (dst.channels() < 3)
throw new ArgumentException("dst.channels() < 3");
if (src_mask.channels () != 1)
throw new ArgumentException ("src_mask.channels() != 1");
if (src_mask.channels() != 1)
throw new ArgumentException("src_mask.channels() != 1");
if (dst_mask.channels () != 1)
throw new ArgumentException ("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 ())
throw new ArgumentException ("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 ())
throw new ArgumentException ("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.");
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];
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];
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];
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];
for (int i = 0; i < dst_cdf.Length; i++)
{
dst_cdf[i] = new double[256];
}
double[] src_histMax = new double[3];
@ -57,61 +58,69 @@ 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 ()];
MatUtils.copyFromMat<byte> (src_mask, src_mask_byte);
if (src_mask != null)
{
src_mask_byte = new byte[src_mask.total() * src_mask.channels()];
MatUtils.copyFromMat<byte>(src_mask, src_mask_byte);
}
if (dst_mask != null) {
dst_mask_byte = new byte[dst_mask.total () * dst_mask.channels ()];
MatUtils.copyFromMat<byte> (dst_mask, dst_mask_byte);
if (dst_mask != null)
{
dst_mask_byte = new byte[dst_mask.total() * dst_mask.channels()];
MatUtils.copyFromMat<byte>(dst_mask, dst_mask_byte);
}
byte[] src_byte = new byte[src.total () * src.channels ()];
MatUtils.copyFromMat<byte> (src, src_byte);
byte[] dst_byte = new byte[dst.total () * dst.channels ()];
MatUtils.copyFromMat<byte> (dst, dst_byte);
byte[] src_byte = new byte[src.total() * src.channels()];
MatUtils.copyFromMat<byte>(src, src_byte);
byte[] dst_byte = new byte[dst.total() * dst.channels()];
MatUtils.copyFromMat<byte>(dst, dst_byte);
int pixel_i = 0;
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) {
byte c = src_byte [pixel_i];
src_hist [0] [c]++;
if (src_hist [0] [c] > src_histMax [0])
src_histMax [0] = src_hist [0] [c];
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)
{
byte c = src_byte[pixel_i];
src_hist[0][c]++;
if (src_hist[0][c] > src_histMax[0])
src_histMax[0] = src_hist[0][c];
c = src_byte [pixel_i + 1];
src_hist [1] [c]++;
if (src_hist [1] [c] > src_histMax [1])
src_histMax [1] = src_hist [1] [c];
c = src_byte[pixel_i + 1];
src_hist[1][c]++;
if (src_hist[1][c] > src_histMax[1])
src_histMax[1] = src_hist[1][c];
c = src_byte [pixel_i + 2];
src_hist [2] [c]++;
if (src_hist [2] [c] > src_histMax [2])
src_histMax [2] = src_hist [2] [c];
c = src_byte[pixel_i + 2];
src_hist[2][c]++;
if (src_hist[2][c] > src_histMax[2])
src_histMax[2] = src_hist[2][c];
}
// Advance to next pixel
pixel_i += channels;
}
} else {
for (int i = 0; i < total; i++) {
byte c = src_byte [pixel_i];
src_hist [0] [c]++;
if (src_hist [0] [c] > src_histMax [0])
src_histMax [0] = src_hist [0] [c];
}
else
{
for (int i = 0; i < total; i++)
{
byte c = src_byte[pixel_i];
src_hist[0][c]++;
if (src_hist[0][c] > src_histMax[0])
src_histMax[0] = src_hist[0][c];
c = src_byte [pixel_i + 1];
src_hist [1] [c]++;
if (src_hist [1] [c] > src_histMax [1])
src_histMax [1] = src_hist [1] [c];
c = src_byte[pixel_i + 1];
src_hist[1][c]++;
if (src_hist[1][c] > src_histMax[1])
src_histMax[1] = src_hist[1][c];
c = src_byte [pixel_i + 2];
src_hist [2] [c]++;
if (src_hist [2] [c] > src_histMax [2])
src_histMax [2] = src_hist [2] [c];
c = src_byte[pixel_i + 2];
src_hist[2][c]++;
if (src_hist[2][c] > src_histMax[2])
src_histMax[2] = src_hist[2][c];
// Advance to next pixel
pixel_i += channels;
@ -119,45 +128,51 @@ namespace FaceMaskExample
}
pixel_i = 0;
channels = dst.channels ();
total = (int)dst.total ();
if (dst_mask_byte != null) {
for (int i = 0; i < total; i++) {
if (dst_mask_byte [i] != 0) {
byte c = dst_byte [pixel_i];
dst_hist [0] [c]++;
if (dst_hist [0] [c] > dst_histMax [0])
dst_histMax [0] = dst_hist [0] [c];
channels = dst.channels();
total = (int)dst.total();
if (dst_mask_byte != null)
{
for (int i = 0; i < total; i++)
{
if (dst_mask_byte[i] != 0)
{
byte c = dst_byte[pixel_i];
dst_hist[0][c]++;
if (dst_hist[0][c] > dst_histMax[0])
dst_histMax[0] = dst_hist[0][c];
c = dst_byte [pixel_i + 1];
dst_hist [1] [c]++;
if (dst_hist [1] [c] > dst_histMax [1])
dst_histMax [1] = dst_hist [1] [c];
c = dst_byte[pixel_i + 1];
dst_hist[1][c]++;
if (dst_hist[1][c] > dst_histMax[1])
dst_histMax[1] = dst_hist[1][c];
c = dst_byte [pixel_i + 2];
dst_hist [2] [c]++;
if (dst_hist [2] [c] > dst_histMax [2])
dst_histMax [2] = dst_hist [2] [c];
c = dst_byte[pixel_i + 2];
dst_hist[2][c]++;
if (dst_hist[2][c] > dst_histMax[2])
dst_histMax[2] = dst_hist[2][c];
}
// Advance to next pixel
pixel_i += channels;
}
} else {
for (int i = 0; i < total; i++) {
byte c = dst_byte [pixel_i];
dst_hist [0] [c]++;
if (dst_hist [0] [c] > dst_histMax [0])
dst_histMax [0] = dst_hist [0] [c];
}
else
{
for (int i = 0; i < total; i++)
{
byte c = dst_byte[pixel_i];
dst_hist[0][c]++;
if (dst_hist[0][c] > dst_histMax[0])
dst_histMax[0] = dst_hist[0][c];
c = dst_byte [pixel_i + 1];
dst_hist [1] [c]++;
if (dst_hist [1] [c] > dst_histMax [1])
dst_histMax [1] = dst_hist [1] [c];
c = dst_byte[pixel_i + 1];
dst_hist[1][c]++;
if (dst_hist[1][c] > dst_histMax[1])
dst_histMax[1] = dst_hist[1][c];
c = dst_byte [pixel_i + 2];
dst_hist [2] [c]++;
if (dst_hist [2] [c] > dst_histMax [2])
dst_histMax [2] = dst_hist [2] [c];
c = dst_byte[pixel_i + 2];
dst_hist[2][c]++;
if (dst_hist[2][c] > dst_histMax[2])
dst_histMax[2] = dst_hist[2][c];
// Advance to next pixel
pixel_i += channels;
@ -165,55 +180,62 @@ 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];
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];
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
const double HISTMATCH_EPSILON = 0.000001f;
for (int i = 0; i < 3; i++) {
for (int i = 0; i < 3; i++)
{
int last = 0;
for (int j = 0; j < 256; j++) {
double F1j = src_cdf [i] [j];
for (int j = 0; j < 256; j++)
{
double F1j = src_cdf[i][j];
for (int k = last; k < 256; k++) {
double F2k = dst_cdf [i] [k];
if (Math.Abs (F2k - F1j) < HISTMATCH_EPSILON || F2k > F1j) {
LUT [(j * 3) + i] = (byte)k;
for (int k = last; k < 256; k++)
{
double F2k = dst_cdf[i][k];
if (Math.Abs(F2k - F1j) < HISTMATCH_EPSILON || F2k > F1j)
{
LUT[(j * 3) + i] = (byte)k;
last = k;
break;
}
@ -221,8 +243,8 @@ namespace FaceMaskExample
}
}
LUTTex.LoadRawTextureData (LUT);
LUTTex.Apply (false);
LUTTex.LoadRawTextureData(LUT);
LUTTex.Apply(false);
}
}
}

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

@ -1,13 +1,13 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
public class FaceMaskData : MonoBehaviour
{
[SerializeField]
private Texture2D _image;
public Texture2D image {
public Texture2D image
{
get { return this._image; }
set { this._image = value; }
}
@ -15,25 +15,26 @@ public class FaceMaskData : MonoBehaviour
/// <summary>
/// Determines if to use dynamically detected points.
/// </summary>
[TooltipAttribute ("Determines if to use dynamically detected points.")]
[TooltipAttribute("Determines if to use dynamically detected points.")]
public bool isDynamicMode = true;
/// <summary>
/// Determines if to enable color correction.
/// </summary>
[TooltipAttribute ("Determines if to enable color correction.")]
[TooltipAttribute("Determines if to enable color correction.")]
public bool enableColorCorrection = true;
[SerializeField]
private Rect _faceRect = new Rect (78, 95, 151, 150);
private Rect _faceRect = new Rect(78, 95, 151, 150);
public Rect faceRect {
public Rect faceRect
{
get { return this._faceRect; }
set { this._faceRect = value; }
}
[SerializeField]
private List<Vector2> _landmarkPoints = new List<Vector2> () {
private List<Vector2> _landmarkPoints = new List<Vector2>() {
new Vector2 (84, 148),
new Vector2 (84, 167),
new Vector2 (86, 187),
@ -104,7 +105,8 @@ public class FaceMaskData : MonoBehaviour
new Vector2 (144, 218)
};
public List<Vector2> landmarkPoints {
public List<Vector2> landmarkPoints
{
get { return this._landmarkPoints; }
set { this._landmarkPoints = value; }
}

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

@ -1,14 +1,14 @@
using System;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using System;
using System.Collections.Generic;
using UnityEngine;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
namespace FaceMaskExample
{
/// <summary>
/// Low Pass Points Filter.
/// v 1.0.2
/// v 1.0.4
/// </summary>
public class LowPassPointsFilter : PointsFilterBase
{
@ -18,11 +18,12 @@ namespace FaceMaskExample
List<Vector2> lastPoints;
public LowPassPointsFilter (int numberOfElements) : base (numberOfElements)
{
lastPoints = new List<Vector2> ();
for (int i = 0; i < numberOfElements; i++) {
lastPoints.Add (new Vector2 ());
public LowPassPointsFilter(int numberOfElements) : base(numberOfElements)
{
lastPoints = new List<Vector2>();
for (int i = 0; i < numberOfElements; i++)
{
lastPoints.Add(new Vector2());
}
}
@ -34,51 +35,68 @@ namespace FaceMaskExample
/// <param name="dstPoints">Output points.</param>
/// <param name="drawDebugPoints">if true, draws debug points.</param>
/// <returns>Output points.</returns>
public override List<Vector2> Process (Mat img, List<Vector2> srcPoints, List<Vector2> dstPoints = null, bool drawDebugPoints = false)
public override List<Vector2> Process(Mat img, List<Vector2> srcPoints, List<Vector2> dstPoints = null, bool drawDebugPoints = false)
{
if (srcPoints != null && srcPoints.Count != numberOfElements) {
throw new ArgumentException ("The number of elements is different.");
if (srcPoints != null && srcPoints.Count != numberOfElements)
{
throw new ArgumentException("The number of elements is different.");
}
if (srcPoints != null) {
if (dstPoints == null) {
dstPoints = new List<Vector2> ();
if (srcPoints != null)
{
if (dstPoints == null)
{
dstPoints = new List<Vector2>();
}
if (dstPoints != null && dstPoints.Count != numberOfElements) {
dstPoints.Clear ();
for (int i = 0; i < numberOfElements; i++) {
dstPoints.Add (new Vector2 ());
if (dstPoints != null && dstPoints.Count != numberOfElements)
{
dstPoints.Clear();
for (int i = 0; i < numberOfElements; i++)
{
dstPoints.Add(new Vector2());
}
}
if (flag) {
for (int i = 0; i < numberOfElements; i++) {
double diff = Math.Sqrt (Math.Pow (srcPoints [i].x - lastPoints [i].x, 2.0) + Math.Pow (srcPoints [i].y - lastPoints [i].y, 2.0));
if (diff > diffLawPass) {
lastPoints [i] = srcPoints [i];
if (flag)
{
for (int i = 0; i < numberOfElements; i++)
{
double diff = Math.Sqrt(Math.Pow(srcPoints[i].x - lastPoints[i].x, 2.0) + Math.Pow(srcPoints[i].y - lastPoints[i].y, 2.0));
if (diff > diffLawPass)
{
lastPoints[i] = srcPoints[i];
if (drawDebugPoints)
Imgproc.circle (img, new Point (srcPoints [i].x, srcPoints [i].y), 1, new Scalar (0, 255, 0, 255), -1);
} else {
if (drawDebugPoints)
Imgproc.circle (img, new Point (lastPoints [i].x, lastPoints [i].y), 1, new Scalar (255, 0, 0, 255), -1);
Imgproc.circle(img, new Point(srcPoints[i].x, srcPoints[i].y), 1, new Scalar(0, 255, 0, 255), -1);
}
dstPoints [i] = lastPoints [i];
else
{
if (drawDebugPoints)
Imgproc.circle(img, new Point(lastPoints[i].x, lastPoints[i].y), 1, new Scalar(255, 0, 0, 255), -1);
}
dstPoints[i] = lastPoints[i];
}
} else {
for (int i = 0; i < numberOfElements; i++) {
lastPoints [i] = srcPoints [i];
dstPoints [i] = srcPoints [i];
}
else
{
for (int i = 0; i < numberOfElements; i++)
{
lastPoints[i] = srcPoints[i];
dstPoints[i] = srcPoints[i];
}
if (drawDebugPoints) {
for (int i = 0; i < numberOfElements; i++) {
Imgproc.circle (img, new Point (srcPoints [i].x, srcPoints [i].y), 1, new Scalar (0, 0, 255, 255), -1);
if (drawDebugPoints)
{
for (int i = 0; i < numberOfElements; i++)
{
Imgproc.circle(img, new Point(srcPoints[i].x, srcPoints[i].y), 1, new Scalar(0, 0, 255, 255), -1);
}
}
flag = true;
}
return dstPoints;
} else {
}
else
{
return dstPoints == null ? srcPoints : dstPoints;
}
}
@ -86,21 +104,22 @@ namespace FaceMaskExample
/// <summary>
/// Resets filter.
/// </summary>
public override void Reset ()
public override void Reset()
{
flag = false;
for (int i = 0; i < lastPoints.Count; i++) {
lastPoints [i] = new Vector2 ();
for (int i = 0; i < lastPoints.Count; i++)
{
lastPoints[i] = new Vector2();
}
}
/// <summary>
/// To release the resources for the initialized method.
/// </summary>
public override void Dispose ()
public override void Dispose()
{
if (lastPoints != null)
lastPoints.Clear ();
lastPoints.Clear();
}
}
}

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

@ -1,15 +1,15 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using OpenCVForUnity.VideoModule;
using System;
using System.Collections.Generic;
using UnityEngine;
namespace FaceMaskExample
{
/// <summary>
/// Optical Flow Points Filter.
/// v 1.0.3
/// v 1.0.4
/// </summary>
public class OFPointsFilter : PointsFilterBase
{
@ -28,13 +28,13 @@ namespace FaceMaskExample
MatOfByte status;
MatOfFloat err;
public OFPointsFilter (int numberOfElements) : base (numberOfElements)
{
public OFPointsFilter(int numberOfElements) : base(numberOfElements)
{
diffDlib = diffDlib * (double)numberOfElements / 68.0;
prevTrackPtsMat = new MatOfPoint ();
prevTrackPtsMat = new MatOfPoint();
// Initialize Optical Flow
InitializeOpticalFlow ();
InitializeOpticalFlow();
}
/// <summary>
@ -45,106 +45,140 @@ namespace FaceMaskExample
/// <param name="dstPoints">Output points.</param>
/// <param name="drawDebugPoints">if true, draws debug points.</param>
/// <returns>Output points.</returns>
public override List<Vector2> Process (Mat img, List<Vector2> srcPoints, List<Vector2> dstPoints = null, bool drawDebugPoints = false)
public override List<Vector2> Process(Mat img, List<Vector2> srcPoints, List<Vector2> dstPoints = null, bool drawDebugPoints = false)
{
if (srcPoints != null && srcPoints.Count != numberOfElements) {
throw new ArgumentException ("The number of elements is different.");
if (srcPoints != null && srcPoints.Count != numberOfElements)
{
throw new ArgumentException("The number of elements is different.");
}
if (srcPoints == null) {
if (srcPoints == null)
{
return dstPoints == null ? srcPoints : dstPoints;
}
if (!flag) {
if (img.channels () == 4) {
Imgproc.cvtColor (img, prevgray, Imgproc.COLOR_RGBA2GRAY);
} else if (img.channels () == 3) {
Imgproc.cvtColor (img, prevgray, Imgproc.COLOR_RGB2GRAY);
} else {
if (prevgray.total () == 0) {
prevgray = img.clone ();
} else {
img.copyTo (prevgray);
if (!flag)
{
if (img.channels() == 4)
{
Imgproc.cvtColor(img, prevgray, Imgproc.COLOR_RGBA2GRAY);
}
else if (img.channels() == 3)
{
Imgproc.cvtColor(img, prevgray, Imgproc.COLOR_RGB2GRAY);
}
else
{
if (prevgray.total() == 0)
{
prevgray = img.clone();
}
else
{
img.copyTo(prevgray);
}
}
for (int i = 0; i < numberOfElements; i++) {
prevTrackPts [i] = new Point (srcPoints [i].x, srcPoints [i].y);
for (int i = 0; i < numberOfElements; i++)
{
prevTrackPts[i] = new Point(srcPoints[i].x, srcPoints[i].y);
}
flag = true;
}
if (srcPoints != null) {
if (srcPoints != null)
{
if (dstPoints == null) {
dstPoints = new List<Vector2> ();
if (dstPoints == null)
{
dstPoints = new List<Vector2>();
}
if (dstPoints != null && dstPoints.Count != numberOfElements) {
dstPoints.Clear ();
for (int i = 0; i < numberOfElements; i++) {
dstPoints.Add (new Vector2 ());
if (dstPoints != null && dstPoints.Count != numberOfElements)
{
dstPoints.Clear();
for (int i = 0; i < numberOfElements; i++)
{
dstPoints.Add(new Vector2());
}
}
if (img.channels () == 4) {
Imgproc.cvtColor (img, gray, Imgproc.COLOR_RGBA2GRAY);
} else if (img.channels () == 3) {
Imgproc.cvtColor (img, gray, Imgproc.COLOR_RGB2GRAY);
} else {
if (gray.total () == 0) {
gray = img.clone ();
} else {
img.copyTo (gray);
if (img.channels() == 4)
{
Imgproc.cvtColor(img, gray, Imgproc.COLOR_RGBA2GRAY);
}
else if (img.channels() == 3)
{
Imgproc.cvtColor(img, gray, Imgproc.COLOR_RGB2GRAY);
}
else
{
if (gray.total() == 0)
{
gray = img.clone();
}
else
{
img.copyTo(gray);
}
}
if (prevgray.total () > 0) {
mOP2fPrevTrackPts.fromList (prevTrackPts);
mOP2fNextTrackPts.fromList (nextTrackPts);
Video.calcOpticalFlowPyrLK (prevgray, gray, mOP2fPrevTrackPts, mOP2fNextTrackPts, status, err);
prevTrackPts = mOP2fPrevTrackPts.toList ();
nextTrackPts = mOP2fNextTrackPts.toList ();
if (prevgray.total() > 0)
{
mOP2fPrevTrackPts.fromList(prevTrackPts);
mOP2fNextTrackPts.fromList(nextTrackPts);
Video.calcOpticalFlowPyrLK(prevgray, gray, mOP2fPrevTrackPts, mOP2fNextTrackPts, status, err);
prevTrackPts = mOP2fPrevTrackPts.toList();
nextTrackPts = mOP2fNextTrackPts.toList();
// clac diffDlib
prevTrackPtsMat.fromList (prevTrackPts);
OpenCVForUnity.CoreModule.Rect rect = Imgproc.boundingRect (prevTrackPtsMat);
double diffDlib = this.diffDlib * rect.area () / 40000.0 * diffCheckSensitivity;
prevTrackPtsMat.fromList(prevTrackPts);
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
double diff = calDistanceDiff (prevTrackPts, nextTrackPts);
double diff = calDistanceDiff(prevTrackPts, nextTrackPts);
if (drawDebugPoints)
Debug.Log ("variance:" + diff);
if (diff > diffDlib) {
for (int i = 0; i < numberOfElements; i++) {
nextTrackPts [i].x = srcPoints [i].x;
nextTrackPts [i].y = srcPoints [i].y;
Debug.Log("variance:" + diff);
if (diff > diffDlib)
{
for (int i = 0; i < numberOfElements; i++)
{
nextTrackPts[i].x = srcPoints[i].x;
nextTrackPts[i].y = srcPoints[i].y;
dstPoints [i] = srcPoints [i];
dstPoints[i] = srcPoints[i];
}
if (drawDebugPoints) {
Debug.Log ("DLIB");
for (int i = 0; i < numberOfElements; i++) {
Imgproc.circle (img, new Point (srcPoints [i].x, srcPoints [i].y), 2, new Scalar (255, 0, 0, 255), -1);
if (drawDebugPoints)
{
Debug.Log("DLIB");
for (int i = 0; i < numberOfElements; i++)
{
Imgproc.circle(img, new Point(srcPoints[i].x, srcPoints[i].y), 2, new Scalar(255, 0, 0, 255), -1);
}
}
} else {
}
else
{
// In this case, use Optical Flow
for (int i = 0; i < numberOfElements; i++) {
dstPoints [i] = new Vector2 ((float)nextTrackPts [i].x, (float)nextTrackPts [i].y);
for (int i = 0; i < numberOfElements; i++)
{
dstPoints[i] = new Vector2((float)nextTrackPts[i].x, (float)nextTrackPts[i].y);
}
if (drawDebugPoints) {
Debug.Log ("Optical Flow");
for (int i = 0; i < numberOfElements; i++) {
Imgproc.circle (img, nextTrackPts [i], 2, new Scalar (0, 0, 255, 255), -1);
if (drawDebugPoints)
{
Debug.Log("Optical Flow");
for (int i = 0; i < numberOfElements; i++)
{
Imgproc.circle(img, nextTrackPts[i], 2, new Scalar(0, 0, 255, 255), -1);
}
}
}
}
Swap (ref prevTrackPts, ref nextTrackPts);
Swap (ref prevgray, ref gray);
Swap(ref prevTrackPts, ref nextTrackPts);
Swap(ref prevgray, ref gray);
}
return dstPoints;
}
@ -152,77 +186,83 @@ namespace FaceMaskExample
/// <summary>
/// Resets filter.
/// </summary>
public override void Reset ()
public override void Reset()
{
flag = false;
// Reset Optical Flow
for (int i = 0; i < numberOfElements; i++) {
prevTrackPts [i].x = 0.0;
prevTrackPts [i].y = 0.0;
for (int i = 0; i < numberOfElements; i++)
{
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;
for (int i = 0; i < numberOfElements; i++)
{
nextTrackPts[i].x = 0.0;
nextTrackPts[i].y = 0.0;
}
if (prevgray != null) {
prevgray.Dispose ();
prevgray = new Mat ();
if (prevgray != null)
{
prevgray.Dispose();
prevgray = new Mat();
}
if (gray != null) {
gray.Dispose ();
gray = new Mat ();
if (gray != null)
{
gray.Dispose();
gray = new Mat();
}
}
/// <summary>
/// To release the resources for the initialized method.
/// </summary>
public override void Dispose ()
public override void Dispose()
{
DisposeOpticalFlow ();
DisposeOpticalFlow();
if (prevTrackPtsMat != null)
prevTrackPtsMat.Dispose ();
prevTrackPtsMat.Dispose();
}
protected virtual void InitializeOpticalFlow ()
protected virtual void InitializeOpticalFlow()
{
prevTrackPts = new List<Point> ();
for (int i = 0; i < numberOfElements; i++) {
prevTrackPts.Add (new Point (0, 0));
prevTrackPts = new List<Point>();
for (int i = 0; i < numberOfElements; i++)
{
prevTrackPts.Add(new Point(0, 0));
}
nextTrackPts = new List<Point> ();
for (int i = 0; i < numberOfElements; i++) {
nextTrackPts.Add (new Point (0, 0));
nextTrackPts = new List<Point>();
for (int i = 0; i < numberOfElements; i++)
{
nextTrackPts.Add(new Point(0, 0));
}
prevgray = new Mat ();
gray = new Mat ();
mOP2fPrevTrackPts = new MatOfPoint2f ();
mOP2fNextTrackPts = new MatOfPoint2f ();
status = new MatOfByte ();
err = new MatOfFloat ();
prevgray = new Mat();
gray = new Mat();
mOP2fPrevTrackPts = new MatOfPoint2f();
mOP2fNextTrackPts = new MatOfPoint2f();
status = new MatOfByte();
err = new MatOfFloat();
}
protected virtual void DisposeOpticalFlow ()
protected virtual void DisposeOpticalFlow()
{
if (prevTrackPts != null)
prevTrackPts.Clear ();
prevTrackPts.Clear();
if (nextTrackPts != null)
nextTrackPts.Clear ();
nextTrackPts.Clear();
if (prevgray != null)
prevgray.Dispose ();
prevgray.Dispose();
if (gray != null)
gray.Dispose ();
gray.Dispose();
if (mOP2fPrevTrackPts != null)
mOP2fPrevTrackPts.Dispose ();
mOP2fPrevTrackPts.Dispose();
if (mOP2fNextTrackPts != null)
mOP2fNextTrackPts.Dispose ();
mOP2fNextTrackPts.Dispose();
if (status != null)
status.Dispose ();
status.Dispose();
if (err != null)
err.Dispose ();
err.Dispose();
}
}
}

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

@ -1,19 +1,19 @@
using System;
using OpenCVForUnity.CoreModule;
using System;
using System.Collections.Generic;
using UnityEngine;
using OpenCVForUnity.CoreModule;
namespace FaceMaskExample
{
/// <summary>
/// Points Filter Base.
/// v 1.0.1
/// v 1.0.4
/// </summary>
public abstract class PointsFilterBase
{
protected int numberOfElements;
public PointsFilterBase (int numberOfElements)
public PointsFilterBase(int numberOfElements)
{
this.numberOfElements = numberOfElements;
}
@ -26,40 +26,43 @@ namespace FaceMaskExample
/// <param name="dstPoints">Output points.</param>
/// <param name="drawDebugPoints">if true, draws debug points.</param>
/// <returns>Output points.</returns>
public abstract List<Vector2> Process (Mat img, List<Vector2> srcPoints, List<Vector2> dstPoints = null, bool drawDebugPoints = false);
public abstract List<Vector2> Process(Mat img, List<Vector2> srcPoints, List<Vector2> dstPoints = null, bool drawDebugPoints = false);
/// <summary>
/// Resets filter.
/// </summary>
public abstract void Reset ();
public abstract void Reset();
/// <summary>
/// To release the resources for the initialized method.
/// </summary>
public abstract void Dispose ();
public abstract void Dispose();
// This function is to calculate the variance
protected virtual double calDistanceDiff (List<Point> curPoints, List<Point> lastPoints)
protected virtual double calDistanceDiff(IList<Point> curPoints, IList<Point> lastPoints)
{
double variance = 0.0;
double sum = 0.0;
List<double> diffs = new List<double> ();
if (curPoints.Count == lastPoints.Count) {
for (int i = 0; i < curPoints.Count; i++) {
double diff = Math.Sqrt (Math.Pow (curPoints [i].x - lastPoints [i].x, 2.0) + Math.Pow (curPoints [i].y - lastPoints [i].y, 2.0));
List<double> diffs = new List<double>();
if (curPoints.Count == lastPoints.Count)
{
for (int i = 0; i < curPoints.Count; i++)
{
double diff = Math.Sqrt(Math.Pow(curPoints[i].x - lastPoints[i].x, 2.0) + Math.Pow(curPoints[i].y - lastPoints[i].y, 2.0));
sum += diff;
diffs.Add (diff);
diffs.Add(diff);
}
double mean = sum / diffs.Count;
for (int i = 0; i < curPoints.Count; i++) {
variance += Math.Pow (diffs [i] - mean, 2);
for (int i = 0; i < curPoints.Count; i++)
{
variance += Math.Pow(diffs[i] - mean, 2);
}
return variance / diffs.Count;
}
return variance;
}
protected virtual void Swap<T> (ref T a, ref T b)
protected virtual void Swap<T>(ref T a, ref T b)
{
var t = a;
a = b;

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

@ -13,114 +13,132 @@ 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 ();
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--;
}
}
}
}
public void DestroyAllObjects ()
public void DestroyAllObjects()
{
foreach (var obj in pooledObjectList) {
Destroy (obj);
foreach (var obj in pooledObjectList)
{
Destroy(obj);
}
pooledObjectList.Clear ();
pooledObjectList.Clear();
}
}
}

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

@ -3,62 +3,71 @@ 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 ()
void OnDestroy()
{
if (_meshFilter != null && _meshFilter.mesh != null) {
DestroyImmediate (_meshFilter.mesh);
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);
}
}
}

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

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using OpenCVForUnity.RectangleTrack;
namespace FaceMaskExample
{
@ -13,24 +12,31 @@ namespace FaceMaskExample
[SerializeField]
protected GameObject _baseObject;
public GameObject baseObject {
get {
public GameObject baseObject
{
get
{
return _baseObject;
}
set {
set
{
_baseObject = value;
SetBaseObject (_baseObject);
SetBaseObject(_baseObject);
}
}
public float width {
get {
public float width
{
get
{
return targetWidth;
}
}
public float height {
get {
public float height
{
get
{
return targetHeight;
}
}
@ -40,75 +46,82 @@ 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;
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)
SetBaseObject (_baseObject);
SetBaseObject(_baseObject);
}
protected virtual void SetBaseObject (GameObject obj)
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;
}
targetWidth = targetTransform.localScale.x;
targetHeight = targetTransform.localScale.y;
this.targetTransform = targetTransform;
@ -117,83 +130,95 @@ 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.");
Debug.LogError("The baseObject does not exist.");
if (!showingObjects.ContainsKey (id)) {
GameObject obj = GetPoolObject (overlayTransform);
if (!showingObjects.ContainsKey(id))
{
GameObject obj = GetPoolObject(overlayTransform);
if (obj == null)
return null;
TrackedMesh tm = obj.GetComponent<TrackedMesh> ();
if (tm != 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> ();
tmRenderer.sharedMaterial.SetTexture ("_MainTex", tex);
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.");
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,8 +1,7 @@
using UnityEngine;
using System.Collections;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using OpenCVForUnity.UnityUtils;
using UnityEngine;
namespace FaceMaskExample
{
@ -16,42 +15,45 @@ namespace FaceMaskExample
/// <param name="height">The texture height.</param>
/// <param name="baseArea">The base area.(An array of points in UV coordinate system)</param>
/// <param name="exclusionAreas">Exclusion areas.(An array of points in UV coordinate system)</param>
public static Texture2D CreateAlphaMaskTexture (float width, float height, Vector2[] baseArea, params Vector2[][] exclusionAreas)
public static Texture2D CreateAlphaMaskTexture(float width, float height, Vector2[] baseArea, params Vector2[][] exclusionAreas)
{
Mat baseAreaMaskMat = new Mat ((int)height, (int)width, CvType.CV_8UC4);
baseAreaMaskMat.setTo (new Scalar (0, 0, 0, 255));
Mat baseAreaMaskMat = new Mat((int)height, (int)width, CvType.CV_8UC4);
baseAreaMaskMat.setTo(new Scalar(0, 0, 0, 255));
Point[] baseAreaPoints = new Point[baseArea.Length];
for (int i = 0; i < baseArea.Length; i++) {
baseAreaPoints [i] = new Point (baseArea [i].x * width, height - baseArea [i].y * height);
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), 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));
Mat exclusionAreaMaskMat = new Mat ((int)height, (int)width, CvType.CV_8UC4);
exclusionAreaMaskMat.setTo (new Scalar (0, 0, 0, 255));
foreach (Vector2[] exclusionArea in exclusionAreas) {
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));
Mat exclusionAreaMaskMat = new Mat((int)height, (int)width, CvType.CV_8UC4);
exclusionAreaMaskMat.setTo(new Scalar(0, 0, 0, 255));
foreach (Vector2[] exclusionArea in exclusionAreas)
{
Point[] points = new Point[exclusionArea.Length];
for (int i = 0; i < exclusionArea.Length; i++) {
points [i] = new Point (exclusionArea [i].x * width, height - exclusionArea [i].y * height);
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), Imgproc.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.blur (exclusionAreaMaskMat, exclusionAreaMaskMat, new Size (width * 0.01, height * 0.01), new Point (-1, -1), Core.BORDER_CONSTANT);
//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);
Mat maskMat = new Mat ((int)height, (int)width, CvType.CV_8UC4);
Core.bitwise_xor (baseAreaMaskMat, exclusionAreaMaskMat, maskMat);
Mat maskMat = new Mat((int)height, (int)width, CvType.CV_8UC4);
Core.bitwise_xor(baseAreaMaskMat, exclusionAreaMaskMat, maskMat);
Texture2D texture = new Texture2D ((int)width, (int)height, TextureFormat.RGB24, false);
Utils.matToTexture2D (maskMat, texture);
Texture2D texture = new Texture2D((int)width, (int)height, TextureFormat.RGB24, false);
Utils.matToTexture2D(maskMat, texture);
maskMat.Dispose();
baseAreaMaskMat.Dispose();
exclusionAreaMaskMat.Dispose();
maskMat.Dispose ();
baseAreaMaskMat.Dispose ();
exclusionAreaMaskMat.Dispose ();
return texture;
}
}

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

@ -1,6 +1,5 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
namespace FaceMaskExample
{
@ -28,11 +27,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;
@ -48,13 +47,13 @@ namespace FaceMaskExample
int oldScrWidth;
int oldScrHeight;
Dictionary<string, string> outputDict = new Dictionary<string, string> ();
Dictionary<string, string> outputDict = new Dictionary<string, string>();
public string consoleText;
// Use this for initialization
void Start ()
void Start()
{
console_labelStyle = new GUIStyle ();
console_labelStyle = new GUIStyle();
console_labelStyle.fontSize = 32;
console_labelStyle.fontStyle = FontStyle.Normal;
console_labelStyle.wordWrap = true;
@ -62,116 +61,127 @@ 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) {
if (elapsed >= 1f)
{
fps = tick / elapsed;
tick = 0;
elapsed = 0;
}
}
void OnGUI ()
void OnGUI()
{
if (oldScrWidth != Screen.width || oldScrHeight != Screen.height) {
LocateGUI ();
if (oldScrWidth != Screen.width || oldScrHeight != Screen.height)
{
LocateGUI();
}
oldScrWidth = Screen.width;
oldScrHeight = Screen.height;
if (boxVisible) {
GUI.Box (outer, "");
}
GUILayout.BeginArea (inner);
if (boxVisible)
{
GUILayout.BeginVertical ();
GUILayout.Label ("fps : " + fps.ToString ("F1"));
foreach (KeyValuePair<string, string> pair in outputDict) {
GUILayout.Label (pair.Key + " : " + pair.Value);
}
GUILayout.EndVertical ();
GUI.Box(outer, "");
}
GUILayout.EndArea ();
if (!string.IsNullOrEmpty (consoleText)) {
if (boxVisible) {
GUI.Box (console_outer, "");
}
GUILayout.BeginArea (console_inner);
GUILayout.BeginArea(inner);
{
GUILayout.BeginVertical();
GUILayout.Label("fps : " + fps.ToString("F1"));
foreach (KeyValuePair<string, string> pair in outputDict)
{
GUILayout.BeginVertical ();
GUILayout.Label (consoleText, console_labelStyle);
GUILayout.EndVertical ();
GUILayout.Label(pair.Key + " : " + pair.Value);
}
GUILayout.EndArea ();
GUILayout.EndVertical();
}
GUILayout.EndArea();
if (!string.IsNullOrEmpty(consoleText))
{
if (boxVisible)
{
GUI.Box(console_outer, "");
}
GUILayout.BeginArea(console_inner);
{
GUILayout.BeginVertical();
GUILayout.Label(consoleText, console_labelStyle);
GUILayout.EndVertical();
}
GUILayout.EndArea();
}
}
public void Add (string key, string value)
public void Add(string key, string value)
{
if (outputDict.ContainsKey (key)) {
outputDict [key] = value;
} else {
outputDict.Add (key, value);
if (outputDict.ContainsKey(key))
{
outputDict[key] = value;
}
else
{
outputDict.Add(key, value);
}
}
public void Remove (string key)
public void Remove(string key)
{
outputDict.Remove (key);
outputDict.Remove(key);
}
public void Clear ()
public void Clear()
{
outputDict.Clear ();
outputDict.Clear();
}
public void LocateGUI ()
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);
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);
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:
case Alignment.LeftBottom:
return offset.x;
switch (anchor)
{
default:
case Alignment.LeftTop:
case Alignment.LeftBottom:
return offset.x;
case Alignment.RightTop:
case Alignment.RightBottom:
return Screen.width - w - offset.x;
case Alignment.RightTop:
case Alignment.RightBottom:
return Screen.width - w - offset.x;
}
}
float GetAlignedY (Alignment anchor, float h)
float GetAlignedY(Alignment anchor, float h)
{
switch (anchor) {
default:
case Alignment.LeftTop:
case Alignment.RightTop:
return offset.y;
switch (anchor)
{
default:
case Alignment.LeftTop:
case Alignment.RightTop:
return offset.y;
case Alignment.LeftBottom:
case Alignment.RightBottom:
return Screen.height - h - offset.y;
case Alignment.LeftBottom:
case Alignment.RightBottom:
return Screen.height - h - offset.y;
}
}
}

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

@ -1,9 +1,8 @@
using System;
using System.Collections;
using OpenCVForUnity.Calib3dModule;
using OpenCVForUnity.CoreModule;
using System;
using System.Collections.Generic;
using UnityEngine;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.Calib3dModule;
namespace FaceMaskExample
{
@ -16,7 +15,7 @@ namespace FaceMaskExample
float imageWidth;
float imageHeight;
Point[] landmarkPoints = new Point[7];
Matrix4x4 transformationM = new Matrix4x4 ();
Matrix4x4 transformationM = new Matrix4x4();
MatOfPoint3f objectPoints;
MatOfPoint2f imagePoints;
Mat rvec;
@ -32,72 +31,73 @@ namespace FaceMaskExample
/// </summary>
/// <param name="width">Width of the image which was used in the face landmark detection.</param>
/// <param name="height">Height of the image which was used in the face landmark detection.</param>
public FrontalFaceChecker (float width, float height)
public FrontalFaceChecker(float width, float height)
{
imageWidth = width;
imageHeight = height;
for (int i = 0; i < landmarkPoints.Length; i++) {
landmarkPoints [i] = new Point (0, 0);
for (int i = 0; i < landmarkPoints.Length; i++)
{
landmarkPoints[i] = new Point(0, 0);
}
objectPoints = new MatOfPoint3f (
new Point3 (-34, 90, 83),//l eye (Interpupillary breadth)
new Point3 (34, 90, 83),//r eye (Interpupillary breadth)
new Point3 (0.0, 50, 120),//nose (Nose top)
new Point3 (-26, 15, 83),//l mouse (Mouth breadth)
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)
objectPoints = new MatOfPoint3f(
new Point3(-34, 90, 83),//l eye (Interpupillary breadth)
new Point3(34, 90, 83),//r eye (Interpupillary breadth)
new Point3(0.0, 50, 120),//nose (Nose top)
new Point3(-26, 15, 83),//l mouse (Mouth breadth)
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 ();
rvec = new Mat (3, 1, CvType.CV_64FC1);
tvec = new Mat (3, 1, CvType.CV_64FC1);
imagePoints = new MatOfPoint2f();
rotM = new Mat (3, 3, CvType.CV_64FC1);
float max_d = Mathf.Max (imageHeight, imageWidth);
camMatrix = new Mat (3, 3, CvType.CV_64FC1);
camMatrix.put (0, 0, max_d);
camMatrix.put (0, 1, 0);
camMatrix.put (0, 2, imageWidth / 2.0f);
camMatrix.put (1, 0, 0);
camMatrix.put (1, 1, max_d);
camMatrix.put (1, 2, imageHeight / 2.0f);
camMatrix.put (2, 0, 0);
camMatrix.put (2, 1, 0);
camMatrix.put (2, 2, 1.0f);
distCoeffs = new MatOfDouble (0, 0, 0, 0);
invertYM = Matrix4x4.TRS (Vector3.zero, Quaternion.identity, new Vector3 (1, -1, 1));
invertZM = Matrix4x4.TRS (Vector3.zero, Quaternion.identity, new Vector3 (1, 1, -1));
rvec = new Mat(3, 1, CvType.CV_64FC1);
tvec = new Mat(3, 1, CvType.CV_64FC1);
rotM = new Mat(3, 3, CvType.CV_64FC1);
float max_d = Mathf.Max(imageHeight, imageWidth);
camMatrix = new Mat(3, 3, CvType.CV_64FC1);
camMatrix.put(0, 0, max_d);
camMatrix.put(0, 1, 0);
camMatrix.put(0, 2, imageWidth / 2.0f);
camMatrix.put(1, 0, 0);
camMatrix.put(1, 1, max_d);
camMatrix.put(1, 2, imageHeight / 2.0f);
camMatrix.put(2, 0, 0);
camMatrix.put(2, 1, 0);
camMatrix.put(2, 2, 1.0f);
distCoeffs = new MatOfDouble(0, 0, 0, 0);
invertYM = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1, -1, 1));
invertZM = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1, 1, -1));
}
public void Dispose ()
public void Dispose()
{
if (objectPoints != null && !objectPoints.IsDisposed)
objectPoints.Dispose ();
objectPoints.Dispose();
if (imagePoints != null && !imagePoints.IsDisposed)
imagePoints.Dispose ();
imagePoints.Dispose();
if (rvec != null && !rvec.IsDisposed)
rvec.Dispose ();
rvec.Dispose();
if (tvec != null && !tvec.IsDisposed)
tvec.Dispose ();
tvec.Dispose();
if (rotM != null && !rotM.IsDisposed)
rotM.Dispose ();
rotM.Dispose();
if (camMatrix != null && !camMatrix.IsDisposed)
camMatrix.Dispose ();
camMatrix.Dispose();
if (distCoeffs != null && !distCoeffs.IsDisposed)
distCoeffs.Dispose ();
distCoeffs.Dispose();
}
/// <summary>
@ -105,70 +105,75 @@ namespace FaceMaskExample
/// </summary>
/// <returns>Frontal face angles.</returns>
/// <param name="points">Points of face landmark which was detected with Dlib.</param>
public Vector3 GetFrontalFaceAngles (List<Vector2> points)
public Vector3 GetFrontalFaceAngles(List<Vector2> points)
{
if (points.Count < 68)
throw new ArgumentException ("Invalid face landmark points", "points");
throw new ArgumentException("Invalid face landmark points", "points");
landmarkPoints [0].x = (points [38].x + points [41].x) / 2;
landmarkPoints [0].y = (points [38].y + points [41].y) / 2;
landmarkPoints [1].x = (points [43].x + points [46].x) / 2;
landmarkPoints [1].y = (points [43].y + points [46].y) / 2;
landmarkPoints [2].x = points [30].x;
landmarkPoints [2].y = points [30].y;
landmarkPoints [3].x = points [48].x;
landmarkPoints [3].y = points [48].y;
landmarkPoints [4].x = points [54].x;
landmarkPoints [4].y = points [54].y;
landmarkPoints [5].x = points [0].x;
landmarkPoints [5].y = points [0].y;
landmarkPoints [6].x = points [16].x;
landmarkPoints [6].y = points [16].y;
landmarkPoints[0].x = (points[38].x + points[41].x) / 2;
landmarkPoints[0].y = (points[38].y + points[41].y) / 2;
landmarkPoints[1].x = (points[43].x + points[46].x) / 2;
landmarkPoints[1].y = (points[43].y + points[46].y) / 2;
landmarkPoints[2].x = points[30].x;
landmarkPoints[2].y = points[30].y;
landmarkPoints[3].x = points[48].x;
landmarkPoints[3].y = points[48].y;
landmarkPoints[4].x = points[54].x;
landmarkPoints[4].y = points[54].y;
landmarkPoints[5].x = points[0].x;
landmarkPoints[5].y = points[0].y;
landmarkPoints[6].x = points[16].x;
landmarkPoints[6].y = points[16].y;
// Normalize points.
Point centerOffset = landmarkPoints [2] - new Point (imageWidth / 2, imageHeight / 2);
for (int i = 0; i < landmarkPoints.Length; i++) {
landmarkPoints [i] = landmarkPoints [i] - centerOffset;
Point centerOffset = landmarkPoints[2] - new Point(imageWidth / 2, imageHeight / 2);
for (int i = 0; i < landmarkPoints.Length; i++)
{
landmarkPoints[i] = landmarkPoints[i] - centerOffset;
}
imagePoints.fromArray (landmarkPoints);
imagePoints.fromArray(landmarkPoints);
Calib3d.solvePnP (objectPoints, imagePoints, camMatrix, distCoeffs, rvec, tvec);
Calib3d.solvePnP(objectPoints, imagePoints, camMatrix, distCoeffs, rvec, tvec);
double tvec_z = tvec.get (2, 0) [0];
double tvec_z = tvec.get(2, 0)[0];
// Debug.Log (rvec.dump());
// Debug.Log (tvec.dump());
//Debug.Log (rvec.dump());
//Debug.Log (tvec.dump());
if (!double.IsNaN (tvec_z)) {
Calib3d.Rodrigues (rvec, rotM);
// Debug.Log (rotM.dump());
if (!double.IsNaN(tvec_z))
{
Calib3d.Rodrigues(rvec, rotM);
//Debug.Log (rotM.dump());
transformationM.SetRow(0, new Vector4((float)rotM.get(0, 0)[0], (float)rotM.get(0, 1)[0], (float)rotM.get(0, 2)[0], (float)tvec.get(0, 0)[0]));
transformationM.SetRow(1, new Vector4((float)rotM.get(1, 0)[0], (float)rotM.get(1, 1)[0], (float)rotM.get(1, 2)[0], (float)tvec.get(1, 0)[0]));
transformationM.SetRow(2, new Vector4((float)rotM.get(2, 0)[0], (float)rotM.get(2, 1)[0], (float)rotM.get(2, 2)[0], (float)tvec.get(2, 0)[0]));
transformationM.SetRow(3, new Vector4(0, 0, 0, 1));
transformationM.SetRow (0, new Vector4 ((float)rotM.get (0, 0) [0], (float)rotM.get (0, 1) [0], (float)rotM.get (0, 2) [0], (float)tvec.get (0, 0) [0]));
transformationM.SetRow (1, new Vector4 ((float)rotM.get (1, 0) [0], (float)rotM.get (1, 1) [0], (float)rotM.get (1, 2) [0], (float)tvec.get (1, 0) [0]));
transformationM.SetRow (2, new Vector4 ((float)rotM.get (2, 0) [0], (float)rotM.get (2, 1) [0], (float)rotM.get (2, 2) [0], (float)tvec.get (2, 0) [0]));
transformationM.SetRow (3, new Vector4 (0, 0, 0, 1));
transformationM = invertYM * transformationM * invertZM;
Vector3 angles = ExtractRotationFromMatrix (ref transformationM).eulerAngles;
// Debug.Log ("angles " + angles.x + " " + angles.y + " " + angles.z);
Vector3 angles = ExtractRotationFromMatrix(ref transformationM).eulerAngles;
//Debug.Log ("angles " + angles.x + " " + angles.y + " " + angles.z);
float rotationX = (angles.x > 180) ? angles.x - 360 : angles.x;
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);
} else {
return new Vector3 (0, 0, 0);
return new Vector3(rotationX, rotationY, rotationZ);
}
else
{
return new Vector3(0, 0, 0);
}
}
@ -177,16 +182,16 @@ namespace FaceMaskExample
/// </summary>
/// <returns>Frontal face rate.(a value of 0 to 1)</returns>
/// <param name="points">Points of face landmark which was detected with Dlib.</param>
public float GetFrontalFaceRate (List<Vector2> points)
public float GetFrontalFaceRate(List<Vector2> points)
{
Vector3 angles = GetFrontalFaceAngles (points);
Vector3 angles = GetFrontalFaceAngles(points);
// Debug.Log ("angles " + angles.x + " " + angles.y + " " + angles.z);
//Debug.Log ("angles " + angles.x + " " + angles.y + " " + angles.z);
float angle = Mathf.Max (Mathf.Abs (angles.x), Mathf.Abs (angles.y));
float angle = Mathf.Max(Mathf.Abs(angles.x), Mathf.Abs(angles.y));
float rate = (angle <= 90) ? angle / 90 : 1;
// Debug.Log ("ratio " + (1.0f - rate));
//Debug.Log ("ratio " + (1.0f - rate));
return 1.0f - rate;
}
@ -199,19 +204,19 @@ namespace FaceMaskExample
/// <returns>
/// Quaternion representation of rotation transform.
/// </returns>
private Quaternion ExtractRotationFromMatrix (ref Matrix4x4 matrix)
private Quaternion ExtractRotationFromMatrix(ref Matrix4x4 matrix)
{
Vector3 forward;
forward.x = matrix.m02;
forward.y = matrix.m12;
forward.z = matrix.m22;
Vector3 upwards;
upwards.x = matrix.m01;
upwards.y = matrix.m11;
upwards.z = matrix.m21;
return Quaternion.LookRotation (forward, upwards);
return Quaternion.LookRotation(forward, upwards);
}
}
}

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

@ -1,10 +1,9 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DlibFaceLandmarkDetector;
using DlibFaceLandmarkDetector;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using System;
using System.Collections.Generic;
using UnityEngine;
namespace FaceMaskExample
{
@ -18,12 +17,21 @@ namespace FaceMaskExample
/// </summary>
/// <param name="faceLandmarkDetector">Face landmark detector.</param>
/// <param name="imgMat">Image mat.</param>
public static void SetImage (FaceLandmarkDetector faceLandmarkDetector, Mat imgMat)
public static void SetImage(FaceLandmarkDetector faceLandmarkDetector, Mat imgMat)
{
if (!imgMat.isContinuous ()) {
throw new ArgumentException ("imgMat.isContinuous() must be true.");
}
faceLandmarkDetector.SetImage ((IntPtr)imgMat.dataAddr (), imgMat.width (), imgMat.height (), (int)imgMat.elemSize ());
if (faceLandmarkDetector == null)
throw new ArgumentNullException("faceLandmarkDetector");
if (faceLandmarkDetector != null)
faceLandmarkDetector.ThrowIfDisposed();
if (imgMat == null)
throw new ArgumentNullException("imgMat");
if (imgMat != null)
imgMat.ThrowIfDisposed();
if (!imgMat.isContinuous())
throw new ArgumentException("imgMat.isContinuous() must be true.");
faceLandmarkDetector.SetImage((IntPtr)imgMat.dataAddr(), imgMat.width(), imgMat.height(), (int)imgMat.elemSize());
}
/// <summary>
@ -33,9 +41,21 @@ namespace FaceMaskExample
/// <param name="rect">Rect.</param>
/// <param name="color">Color.</param>
/// <param name="thickness">Thickness.</param>
public static void DrawFaceRect (Mat imgMat, UnityEngine.Rect rect, Scalar color, int thickness)
public static void DrawFaceRect(Mat imgMat, UnityEngine.Rect rect, Scalar color, int thickness)
{
Imgproc.rectangle (imgMat, new Point (rect.xMin, rect.yMin), new Point (rect.xMax, rect.yMax), color, thickness);
Imgproc.rectangle(imgMat, new Point(rect.xMin, rect.yMin), new Point(rect.xMax, rect.yMax), color, thickness);
}
/// <summary>
/// Draws a face rect.
/// </summary>
/// <param name="imgMat">Image mat.</param>
/// <param name="rect">Rect.</param>
/// <param name="color">Color.</param>
/// <param name="thickness">Thickness.</param>
public static void DrawFaceRect(Mat imgMat, OpenCVForUnity.CoreModule.Rect rect, Scalar color, int thickness)
{
Imgproc.rectangle(imgMat, rect, color, thickness);
}
/// <summary>
@ -45,12 +65,15 @@ namespace FaceMaskExample
/// <param name="rect">RectDetection.</param>
/// <param name="color">Color.</param>
/// <param name="thickness">Thickness.</param>
public static void DrawFaceRect (Mat imgMat, DlibFaceLandmarkDetector.FaceLandmarkDetector.RectDetection rect, Scalar color, int thickness)
{
public static void DrawFaceRect(Mat imgMat, DlibFaceLandmarkDetector.FaceLandmarkDetector.RectDetection rect, Scalar color, int thickness)
{
if (rect == null)
throw new ArgumentNullException("rect");
UnityEngine.Rect _rect = rect.rect;
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);
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);
}
/// <summary>
@ -60,301 +83,603 @@ namespace FaceMaskExample
/// <param name="rect">Detected object's data. [left, top, width, height, detection_confidence, weight_index]</param>
/// <param name="color">Color.</param>
/// <param name="thickness">Thickness.</param>
public static void DrawFaceRect (Mat imgMat, double[] rect, Scalar color, int thickness)
{
public static void DrawFaceRect(Mat imgMat, double[] rect, Scalar color, int thickness)
{
if (rect == null)
throw new ArgumentNullException("rect");
if (rect.Length > 4)
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);
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), 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);
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>
/// Draws a face landmark.
/// This method supports 68 landmark points.
/// This method supports 68,17,6,5 landmark points.
/// </summary>
/// <param name="imgMat">Image mat.</param>
/// <param name="points">Points.</param>
/// <param name="color">Color.</param>
/// <param name="thickness">Thickness.</param>
/// <param name="drawIndexNumbers">Determines if draw index numbers.</param>
public static void DrawFaceLandmark (Mat imgMat, List<Vector2> points, Scalar color, int thickness, bool drawIndexNumbers = false)
public static void DrawFaceLandmark(Mat imgMat, IList<Vector2> points, Scalar color, int thickness, bool drawIndexNumbers = false)
{
if (points.Count == 5) {
if (points == null)
throw new ArgumentNullException("points");
Imgproc.line (imgMat, new Point (points [0].x, points [0].y), new Point (points [1].x, points [1].y), color, thickness);
Imgproc.line (imgMat, new Point (points [1].x, points [1].y), new Point (points [4].x, points [4].y), color, thickness);
Imgproc.line (imgMat, new Point (points [4].x, points [4].y), new Point (points [3].x, points [3].y), color, thickness);
Imgproc.line (imgMat, new Point (points [3].x, points [3].y), new Point (points [2].x, points [2].y), color, thickness);
if (points.Count == 5)
{
Imgproc.line(imgMat, new Point(points[0].x, points[0].y), new Point(points[1].x, points[1].y), color, thickness);
Imgproc.line(imgMat, new Point(points[1].x, points[1].y), new Point(points[4].x, points[4].y), color, thickness);
Imgproc.line(imgMat, new Point(points[4].x, points[4].y), new Point(points[3].x, points[3].y), color, thickness);
Imgproc.line(imgMat, new Point(points[3].x, points[3].y), new Point(points[2].x, points[2].y), color, thickness);
}
else if (points.Count == 6)
{
Imgproc.line(imgMat, new Point(points[2].x, points[2].y), new Point(points[3].x, points[3].y), color, thickness);
Imgproc.line(imgMat, new Point(points[4].x, points[4].y), new Point(points[5].x, points[5].y), color, thickness);
Imgproc.line(imgMat, new Point(points[3].x, points[3].y), new Point(points[0].x, points[0].y), color, thickness);
Imgproc.line(imgMat, new Point(points[4].x, points[4].y), new Point(points[0].x, points[0].y), color, thickness);
Imgproc.line(imgMat, new Point(points[0].x, points[0].y), new Point(points[1].x, points[1].y), color, thickness);
}
else if (points.Count == 17)
{
Imgproc.line(imgMat, new Point(points[2].x, points[2].y), new Point(points[9].x, points[9].y), color, thickness);
Imgproc.line(imgMat, new Point(points[9].x, points[9].y), new Point(points[3].x, points[3].y), color, thickness);
Imgproc.line(imgMat, new Point(points[3].x, points[3].y), new Point(points[10].x, points[10].y), color, thickness);
Imgproc.line(imgMat, new Point(points[10].x, points[10].y), new Point(points[2].x, points[2].y), color, thickness);
Imgproc.line(imgMat, new Point(points[4].x, points[4].y), new Point(points[11].x, points[11].y), color, thickness);
Imgproc.line(imgMat, new Point(points[11].x, points[11].y), new Point(points[5].x, points[5].y), color, thickness);
Imgproc.line(imgMat, new Point(points[5].x, points[5].y), new Point(points[12].x, points[12].y), color, thickness);
Imgproc.line(imgMat, new Point(points[12].x, points[12].y), new Point(points[4].x, points[4].y), color, thickness);
Imgproc.line(imgMat, new Point(points[3].x, points[3].y), new Point(points[0].x, points[0].y), color, thickness);
Imgproc.line(imgMat, new Point(points[4].x, points[4].y), new Point(points[0].x, points[0].y), color, thickness);
Imgproc.line(imgMat, new Point(points[0].x, points[0].y), new Point(points[1].x, points[1].y), color, thickness);
for (int i = 14; i <= 16; ++i)
Imgproc.line(imgMat, new Point(points[i].x, points[i].y), new Point(points[i - 1].x, points[i - 1].y), color, thickness);
Imgproc.line(imgMat, new Point(points[16].x, points[16].y), new Point(points[13].x, points[13].y), color, thickness);
for (int i = 6; i <= 8; i++)
Imgproc.circle(imgMat, new Point(points[i].x, points[i].y), 2, color, -1);
}
else if (points.Count == 68)
{
} else if (points.Count == 68) {
for (int i = 1; i <= 16; ++i)
Imgproc.line (imgMat, new Point (points [i].x, points [i].y), new Point (points [i - 1].x, points [i - 1].y), color, thickness);
Imgproc.line(imgMat, new Point(points[i].x, points[i].y), new Point(points[i - 1].x, points[i - 1].y), color, thickness);
for (int i = 28; i <= 30; ++i)
Imgproc.line (imgMat, new Point (points [i].x, points [i].y), new Point (points [i - 1].x, points [i - 1].y), color, thickness);
Imgproc.line(imgMat, new Point(points[i].x, points[i].y), new Point(points[i - 1].x, points[i - 1].y), color, thickness);
for (int i = 18; i <= 21; ++i)
Imgproc.line (imgMat, new Point (points [i].x, points [i].y), new Point (points [i - 1].x, points [i - 1].y), color, thickness);
Imgproc.line(imgMat, new Point(points[i].x, points[i].y), new Point(points[i - 1].x, points[i - 1].y), color, thickness);
for (int i = 23; i <= 26; ++i)
Imgproc.line (imgMat, new Point (points [i].x, points [i].y), new Point (points [i - 1].x, points [i - 1].y), color, thickness);
Imgproc.line(imgMat, new Point(points[i].x, points[i].y), new Point(points[i - 1].x, points[i - 1].y), color, thickness);
for (int i = 31; i <= 35; ++i)
Imgproc.line (imgMat, new Point (points [i].x, points [i].y), new Point (points [i - 1].x, points [i - 1].y), color, thickness);
Imgproc.line (imgMat, new Point (points [30].x, points [30].y), new Point (points [35].x, points [35].y), color, thickness);
Imgproc.line(imgMat, new Point(points[i].x, points[i].y), new Point(points[i - 1].x, points[i - 1].y), color, thickness);
Imgproc.line(imgMat, new Point(points[30].x, points[30].y), new Point(points[35].x, points[35].y), color, thickness);
for (int i = 37; i <= 41; ++i)
Imgproc.line (imgMat, new Point (points [i].x, points [i].y), new Point (points [i - 1].x, points [i - 1].y), color, thickness);
Imgproc.line (imgMat, new Point (points [36].x, points [36].y), new Point (points [41].x, points [41].y), color, thickness);
Imgproc.line(imgMat, new Point(points[i].x, points[i].y), new Point(points[i - 1].x, points[i - 1].y), color, thickness);
Imgproc.line(imgMat, new Point(points[36].x, points[36].y), new Point(points[41].x, points[41].y), color, thickness);
for (int i = 43; i <= 47; ++i)
Imgproc.line (imgMat, new Point (points [i].x, points [i].y), new Point (points [i - 1].x, points [i - 1].y), color, thickness);
Imgproc.line (imgMat, new Point (points [42].x, points [42].y), new Point (points [47].x, points [47].y), color, thickness);
Imgproc.line(imgMat, new Point(points[i].x, points[i].y), new Point(points[i - 1].x, points[i - 1].y), color, thickness);
Imgproc.line(imgMat, new Point(points[42].x, points[42].y), new Point(points[47].x, points[47].y), color, thickness);
for (int i = 49; i <= 59; ++i)
Imgproc.line (imgMat, new Point (points [i].x, points [i].y), new Point (points [i - 1].x, points [i - 1].y), color, thickness);
Imgproc.line (imgMat, new Point (points [48].x, points [48].y), new Point (points [59].x, points [59].y), color, thickness);
Imgproc.line(imgMat, new Point(points[i].x, points[i].y), new Point(points[i - 1].x, points[i - 1].y), color, thickness);
Imgproc.line(imgMat, new Point(points[48].x, points[48].y), new Point(points[59].x, points[59].y), color, thickness);
for (int i = 61; i <= 67; ++i)
Imgproc.line (imgMat, new Point (points [i].x, points [i].y), new Point (points [i - 1].x, points [i - 1].y), color, thickness);
Imgproc.line (imgMat, new Point (points [60].x, points [60].y), new Point (points [67].x, points [67].y), color, thickness);
} else {
for (int i = 0; i < points.Count; i++) {
Imgproc.circle (imgMat, new Point (points [i].x, points [i].y), 2, color, -1);
Imgproc.line(imgMat, new Point(points[i].x, points[i].y), new Point(points[i - 1].x, points[i - 1].y), color, thickness);
Imgproc.line(imgMat, new Point(points[60].x, points[60].y), new Point(points[67].x, points[67].y), color, thickness);
}
else
{
for (int i = 0; i < points.Count; i++)
{
Imgproc.circle(imgMat, new Point(points[i].x, points[i].y), 2, color, -1);
}
}
// Draw the index number of facelandmark points.
if (drawIndexNumbers) {
if (drawIndexNumbers)
{
for (int i = 0; i < points.Count; ++i)
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);
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);
}
}
/// <summary>
/// Draws a face landmark.
/// This method supports 68 landmark points.
/// This method supports 68,17,6,5 landmark points.
/// </summary>
/// <param name="imgMat">Image mat.</param>
/// <param name="points">Points.</param>
/// <param name="color">Color.</param>
/// <param name="thickness">Thickness.</param>
/// <param name="drawIndexNumbers">Determines if draw index numbers.</param>
public static void DrawFaceLandmark (Mat imgMat, List<Point> points, Scalar color, int thickness, bool drawIndexNumbers = false)
public static void DrawFaceLandmark(Mat imgMat, IList<Point> points, Scalar color, int thickness, bool drawIndexNumbers = false)
{
if (points.Count == 5) {
if (points == null)
throw new ArgumentNullException("points");
Imgproc.line (imgMat, points [0], points [1], color, thickness);
Imgproc.line (imgMat, points [1], points [4], color, thickness);
Imgproc.line (imgMat, points [4], points [3], color, thickness);
Imgproc.line (imgMat, points [3], points [2], color, thickness);
if (points.Count == 5)
{
} else if (points.Count == 68) {
Imgproc.line(imgMat, points[0], points[1], color, thickness);
Imgproc.line(imgMat, points[1], points[4], color, thickness);
Imgproc.line(imgMat, points[4], points[3], color, thickness);
Imgproc.line(imgMat, points[3], points[2], color, thickness);
}
else if (points.Count == 6)
{
Imgproc.line(imgMat, points[2], points[3], color, thickness);
Imgproc.line(imgMat, points[4], points[5], color, thickness);
Imgproc.line(imgMat, points[3], points[0], color, thickness);
Imgproc.line(imgMat, points[4], points[0], color, thickness);
Imgproc.line(imgMat, points[0], points[1], color, thickness);
}
else if (points.Count == 17)
{
Imgproc.line(imgMat, points[2], points[9], color, thickness);
Imgproc.line(imgMat, points[9], points[3], color, thickness);
Imgproc.line(imgMat, points[3], points[10], color, thickness);
Imgproc.line(imgMat, points[10], points[2], color, thickness);
Imgproc.line(imgMat, points[4], points[11], color, thickness);
Imgproc.line(imgMat, points[11], points[5], color, thickness);
Imgproc.line(imgMat, points[5], points[12], color, thickness);
Imgproc.line(imgMat, points[12], points[4], color, thickness);
Imgproc.line(imgMat, points[3], points[0], color, thickness);
Imgproc.line(imgMat, points[4], points[0], color, thickness);
Imgproc.line(imgMat, points[0], points[1], color, thickness);
for (int i = 14; i <= 16; ++i)
Imgproc.line(imgMat, points[i], points[i - 1], color, thickness);
Imgproc.line(imgMat, points[16], points[13], color, thickness);
for (int i = 6; i <= 8; i++)
Imgproc.circle(imgMat, points[i], 2, color, -1);
}
else if (points.Count == 68)
{
for (int i = 1; i <= 16; ++i)
Imgproc.line (imgMat, points [i], points [i - 1], color, thickness);
Imgproc.line(imgMat, points[i], points[i - 1], color, thickness);
for (int i = 28; i <= 30; ++i)
Imgproc.line (imgMat, points [i], points [i - 1], color, thickness);
Imgproc.line(imgMat, points[i], points[i - 1], color, thickness);
for (int i = 18; i <= 21; ++i)
Imgproc.line (imgMat, points [i], points [i - 1], color, thickness);
Imgproc.line(imgMat, points[i], points[i - 1], color, thickness);
for (int i = 23; i <= 26; ++i)
Imgproc.line (imgMat, points [i], points [i - 1], color, thickness);
Imgproc.line(imgMat, points[i], points[i - 1], color, thickness);
for (int i = 31; i <= 35; ++i)
Imgproc.line (imgMat, points [i], points [i - 1], color, thickness);
Imgproc.line (imgMat, points [30], points [35], color, thickness);
Imgproc.line(imgMat, points[i], points[i - 1], color, thickness);
Imgproc.line(imgMat, points[30], points[35], color, thickness);
for (int i = 37; i <= 41; ++i)
Imgproc.line (imgMat, points [i], points [i - 1], color, thickness);
Imgproc.line (imgMat, points [36], points [41], color, thickness);
Imgproc.line(imgMat, points[i], points[i - 1], color, thickness);
Imgproc.line(imgMat, points[36], points[41], color, thickness);
for (int i = 43; i <= 47; ++i)
Imgproc.line (imgMat, points [i], points [i - 1], color, thickness);
Imgproc.line (imgMat, points [42], points [47], color, thickness);
Imgproc.line(imgMat, points[i], points[i - 1], color, thickness);
Imgproc.line(imgMat, points[42], points[47], color, thickness);
for (int i = 49; i <= 59; ++i)
Imgproc.line (imgMat, points [i], points [i - 1], color, thickness);
Imgproc.line (imgMat, points [48], points [59], color, thickness);
Imgproc.line(imgMat, points[i], points[i - 1], color, thickness);
Imgproc.line(imgMat, points[48], points[59], color, thickness);
for (int i = 61; i <= 67; ++i)
Imgproc.line (imgMat, points [i], points [i - 1], color, thickness);
Imgproc.line (imgMat, points [60], points [67], color, thickness);
} else {
for (int i = 0; i < points.Count; i++) {
Imgproc.circle (imgMat, points [i], 2, color, -1);
Imgproc.line(imgMat, points[i], points[i - 1], color, thickness);
Imgproc.line(imgMat, points[60], points[67], color, thickness);
}
else
{
for (int i = 0; i < points.Count; i++)
{
Imgproc.circle(imgMat, points[i], 2, color, -1);
}
}
// Draw the index number of facelandmark points.
if (drawIndexNumbers) {
if (drawIndexNumbers)
{
for (int i = 0; i < points.Count; ++i)
Imgproc.putText (imgMat, i.ToString (), points [i], Imgproc.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);
}
}
/// <summary>
/// Draws a face landmark.
/// This method supports 68 landmark points.
/// This method supports 68,17,6,5 landmark points.
/// </summary>
/// <param name="imgMat">Image mat.</param>
/// <param name="points">Detected object landmark data.[x_0, y_0, x_1, y_1, ...]</param>
/// <param name="color">Color.</param>
/// <param name="thickness">Thickness.</param>
/// <param name="drawIndexNumbers">Determines if draw index numbers.</param>
public static void DrawFaceLandmark (Mat imgMat, double[] points, Scalar color, int thickness, bool drawIndexNumbers = false)
public static void DrawFaceLandmark(Mat imgMat, double[] points, Scalar color, int thickness, bool drawIndexNumbers = false)
{
List<Vector2> _points = new List<Vector2> ();
for (int i = 0; i < points.Length; i = i + 2) {
_points.Add (new Vector2 ((float)points [i], (float)points [i + 1]));
if (points == null)
throw new ArgumentNullException("points");
List<Vector2> _points = new List<Vector2>();
for (int i = 0; i < points.Length; i = i + 2)
{
_points.Add(new Vector2((float)points[i], (float)points[i + 1]));
}
DrawFaceLandmark (imgMat, _points, color, thickness, drawIndexNumbers);
DrawFaceLandmark(imgMat, _points, color, thickness, drawIndexNumbers);
}
/// <summary>
/// Convert Vector2 list to Vector2 array.
/// </summary>
/// <param name="src">List of Vector2.</param>
/// <param name="dst">Array of Vector2.</param>
/// <returns>Array of Vector2.</returns>
public static Vector2[] ConvertVector2ListToVector2Array(IList<Vector2> src, Vector2[] dst = null)
{
if (src == null)
throw new ArgumentNullException("src");
if (dst != null && src.Count != dst.Length)
throw new ArgumentException("src.Count != dst.Length");
if (dst == null)
{
dst = new Vector2[src.Count];
}
for (int i = 0; i < src.Count; ++i)
{
dst[i].x = src[i].x;
dst[i].y = src[i].y;
}
return dst;
}
/// <summary>
/// Convert vector2 list to point list.
/// Convert Vector2 list to Point list.
/// </summary>
/// <param name="vecs">List of vector2.</param>
/// <param name="pts">List of point.</param>
/// <returns>List of point.</returns>
public static List<Point> ConvertVector2ListToPointList (List<Vector2> vecs, List<Point> pts = null)
/// <param name="src">List of Vector2.</param>
/// <param name="dst">List of Point.</param>
/// <returns>List of Point.</returns>
public static List<Point> ConvertVector2ListToPointList(IList<Vector2> src, List<Point> dst = null)
{
if (pts == null) {
pts = new List<Point> ();
if (src == null)
throw new ArgumentNullException("src");
if (dst == null)
{
dst = new List<Point>();
}
if (pts.Count != vecs.Count) {
pts.Clear ();
for (int i = 0; i < vecs.Count; i++) {
pts.Add (new Point ());
if (dst.Count != src.Count)
{
dst.Clear();
for (int i = 0; i < src.Count; i++)
{
dst.Add(new Point());
}
}
for (int i = 0; i < vecs.Count; ++i) {
pts [i].x = vecs [i].x;
pts [i].y = vecs [i].y;
for (int i = 0; i < src.Count; ++i)
{
dst[i].x = src[i].x;
dst[i].y = src[i].y;
}
return pts;
return dst;
}
/// <summary>
/// Convert vector2 list to array.
/// Convert Vector2 list to Point array.
/// </summary>
/// <param name="vecs">List of vector2.</param>
/// <param name="arr">Array of double.</param>
/// <param name="src">List of Vector2.</param>
/// <param name="dst">Array of Point.</param>
/// <returns>Array of Point.</returns>
public static Point[] ConvertVector2ListToPointArray(IList<Vector2> src, Point[] dst = null)
{
if (src == null)
throw new ArgumentNullException("src");
if (dst != null && src.Count != dst.Length)
throw new ArgumentException("src.Count != dst.Length");
if (dst == null)
{
dst = new Point[src.Count];
}
for (int i = 0; i < src.Count; ++i)
{
dst[i] = new Point(src[i].x, src[i].y);
}
return dst;
}
/// <summary>
/// Convert Vector2 list to array.
/// </summary>
/// <param name="src">List of Vector2.</param>
/// <param name="dst">Array of double.</param>
/// <returns>Array of double.</returns>
public static double[] ConvertVector2ListToArray (List<Vector2> vecs, double[] arr = null)
public static double[] ConvertVector2ListToArray(IList<Vector2> src, double[] dst = null)
{
if (arr == null || (arr != null && arr.Length != vecs.Count * 2)) {
arr = new double[vecs.Count * 2];
if (src == null)
throw new ArgumentNullException("src");
if (dst != null && src.Count * 2 != dst.Length)
throw new ArgumentException("src.Count * 2 != dst.Length");
if (dst == null)
{
dst = new double[src.Count * 2];
}
for (int i = 0; i < vecs.Count; ++i) {
arr [i * 2] = vecs [i].x;
arr [i * 2 + 1] = vecs [i].y;
for (int i = 0; i < src.Count; ++i)
{
dst[i * 2] = src[i].x;
dst[i * 2 + 1] = src[i].y;
}
return arr;
return dst;
}
/// <summary>
/// Convert Point list to Point array.
/// </summary>
/// <param name="src">List of Point.</param>
/// <param name="dst">Array of Point.</param>
/// <returns>Array of Point.</returns>
public static Point[] ConvertPointListToPointArray(IList<Point> src, Point[] dst = null)
{
if (src == null)
throw new ArgumentNullException("src");
if (dst != null && src.Count != dst.Length)
throw new ArgumentException("src.Count != dst.Length");
if (dst == null)
{
dst = new Point[src.Count];
}
for (int i = 0; i < src.Count; ++i)
{
dst[i] = new Point(src[i].x, src[i].y);
}
return dst;
}
/// <summary>
/// Convert point list to vector2 list.
/// Convert Point list to Vector2 list.
/// </summary>
/// <param name="pts">List of point.</param>
/// <param name="vecs">List of vector2.</param>
/// <returns>List of vector2.</returns>
public static List<Vector2> ConvertPointListToVector2List (List<Point> pts, List<Vector2> vecs = null)
/// <param name="src">List of Point.</param>
/// <param name="dst">List of Vector2.</param>
/// <returns>List of Vector2.</returns>
public static List<Vector2> ConvertPointListToVector2List(IList<Point> src, List<Vector2> dst = null)
{
if (vecs == null) {
vecs = new List<Vector2> ();
if (src == null)
throw new ArgumentNullException("src");
if (dst == null)
{
dst = new List<Vector2>();
}
if (vecs.Count != pts.Count) {
vecs.Clear ();
for (int i = 0; i < pts.Count; i++) {
vecs.Add (new Vector2 ());
}
dst.Clear();
for (int i = 0; i < src.Count; ++i)
{
dst.Add(new Vector2((float)src[i].x, (float)src[i].y));
}
for (int i = 0; i < pts.Count; ++i) {
vecs.Add (new Vector2 ((float)pts [i].x, (float)pts [i].y));
}
return vecs;
return dst;
}
/// <summary>
/// Convert point list to array.
/// Convert Point list to Vector2 array.
/// </summary>
/// <param name="pts">List of point.</param>
/// <param name="arr">Array of double.</param>
/// <param name="src">List of Point.</param>
/// <param name="dst">Array of Vector2.</param>
/// <returns>Array of Vector2.</returns>
public static Vector2[] ConvertPointListToVector2Array(IList<Point> src, Vector2[] dst = null)
{
if (src == null)
throw new ArgumentNullException("src");
if (dst != null && src.Count != dst.Length)
throw new ArgumentException("src.Count != dst.Length");
if (dst == null)
{
dst = new Vector2[src.Count];
}
for (int i = 0; i < src.Count; ++i)
{
dst[i].x = (float)src[i].x;
dst[i].y = (float)src[i].y;
}
return dst;
}
/// <summary>
/// Convert Point list to array.
/// </summary>
/// <param name="src">List of Point.</param>
/// <param name="dst">Array of double.</param>
/// <returns>Array of double.</returns>
public static double[] ConvertPointListToArray (List<Point> pts, double[] arr = null)
public static double[] ConvertPointListToArray(IList<Point> src, double[] dst = null)
{
if (arr == null || (arr != null && arr.Length != pts.Count * 2)) {
arr = new double[pts.Count * 2];
if (src == null)
throw new ArgumentNullException("src");
if (dst != null && src.Count * 2 != dst.Length)
throw new ArgumentException("src.Count * 2 != dst.Length");
if (dst == null)
{
dst = new double[src.Count * 2];
}
for (int i = 0; i < pts.Count; ++i) {
arr [i * 2] = pts [i].x;
arr [i * 2 + 1] = pts [i].y;
for (int i = 0; i < src.Count; ++i)
{
dst[i * 2] = src[i].x;
dst[i * 2 + 1] = src[i].y;
}
return arr;
return dst;
}
/// <summary>
/// Convert array to Vector2 list.
/// </summary>
/// <param name="src">Array of double.</param>
/// <param name="dst">List of Vector2.</param>
/// <returns>List of Vector2.</returns>
public static List<Vector2> ConvertArrayToVector2List(double[] src, List<Vector2> dst = null)
{
if (src == null)
throw new ArgumentNullException("src");
if (dst == null)
{
dst = new List<Vector2>();
}
dst.Clear();
int len = src.Length / 2;
for (int i = 0; i < len; ++i)
{
dst.Add(new Vector2((float)src[i * 2], (float)src[i * 2 + 1]));
}
return dst;
}
/// <summary>
/// Convert array to vector2 list.
/// Convert array to Vector2 array.
/// </summary>
/// <param name="arr">Array of double.</param>
/// <param name="vecs">List of vector2.</param>
/// <returns>List of vector2.</returns>
public static List<Vector2> ConvertArrayToVector2List (double[] arr, List<Vector2> vecs = null)
/// <param name="src">Array of double.</param>
/// <param name="dst">Array of Vector2.</param>
/// <returns>Array of Vector2.</returns>
public static Vector2[] ConvertArrayToVector2Array(double[] src, Vector2[] dst = null)
{
if (vecs == null) {
vecs = new List<Vector2> ();
if (src == null)
throw new ArgumentNullException("src");
if (dst != null && src.Length / 2 != dst.Length)
throw new ArgumentException("src.Length / 2 != dst.Length");
if (dst == null)
{
dst = new Vector2[src.Length / 2];
}
if (vecs.Count != arr.Length / 2) {
vecs.Clear ();
for (int i = 0; i < arr.Length / 2; i++) {
vecs.Add (new Vector2 ());
}
for (int i = 0; i < dst.Length; ++i)
{
dst[i].x = (float)src[i * 2];
dst[i].y = (float)src[i * 2 + 1];
}
for (int i = 0; i < vecs.Count; ++i) {
vecs [i] = new Vector2 ((float)arr [i * 2], (float)arr [i * 2 + 1]);
}
return vecs;
return dst;
}
/// <summary>
/// Convert array to point list.
/// Convert array to Point list.
/// </summary>
/// <param name="arr">Array of double.</param>
/// <param name="pts">List of point.</param>
/// <returns>List of point.</returns>
public static List<Point> ConvertArrayToPointList (double[] arr, List<Point> pts = null)
/// <param name="src">Array of double.</param>
/// <param name="dst">List of Point.</param>
/// <returns>List of Point.</returns>
public static List<Point> ConvertArrayToPointList(double[] src, List<Point> dst = null)
{
if (pts == null) {
pts = new List<Point> ();
if (src == null)
throw new ArgumentNullException("src");
if (dst == null)
{
dst = new List<Point>();
}
if (pts.Count != arr.Length / 2) {
pts.Clear ();
for (int i = 0; i < arr.Length / 2; i++) {
pts.Add (new Point ());
if (dst.Count != src.Length / 2)
{
dst.Clear();
for (int i = 0; i < src.Length / 2; i++)
{
dst.Add(new Point());
}
}
for (int i = 0; i < pts.Count; ++i) {
pts [i].x = arr [i * 2];
pts [i].y = arr [i * 2 + 1];
for (int i = 0; i < dst.Count; ++i)
{
dst[i].x = src[i * 2];
dst[i].y = src[i * 2 + 1];
}
return pts;
return dst;
}
/// <summary>
/// Convert array to Point array.
/// </summary>
/// <param name="src">Array of double.</param>
/// <param name="dst">Array of Point.</param>
/// <returns>Array of Point.</returns>
public static Point[] ConvertArrayToPointArray(double[] src, Point[] dst = null)
{
if (src == null)
throw new ArgumentNullException("src");
if (dst != null && src.Length / 2 != dst.Length)
throw new ArgumentException("src.Length / 2 != dst.Length");
if (dst == null)
{
dst = new Point[src.Length / 2];
}
for (int i = 0; i < dst.Length; ++i)
{
dst[i] = new Point(src[i * 2], src[i * 2 + 1]);
}
return dst;
}
}
}

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

@ -1,6 +1,5 @@
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;
namespace FaceMaskExample
{
@ -10,20 +9,20 @@ namespace FaceMaskExample
public class ShowLicense : MonoBehaviour
{
// Use this for initialization
void Start ()
void Start()
{
}
// Update is called once per frame
void Update ()
void Update()
{
}
public void OnBackButtonClick ()
public void OnBackButtonClick()
{
SceneManager.LoadScene ("FaceMaskExample");
SceneManager.LoadScene("FaceMaskExample");
}
}
}

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

@ -13,7 +13,7 @@ OcclusionCullingSettings:
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 8
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
@ -39,6 +39,7 @@ RenderSettings:
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &4
LightmapSettings:
m_ObjectHideFlags: 0
@ -49,16 +50,14 @@ LightmapSettings:
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 9
serializedVersion: 10
m_Resolution: 1
m_BakeResolution: 50
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AtlasSize: 1024
m_AO: 1
m_AOMaxDistance: 1
m_CompAOExponent: 1
@ -88,6 +87,7 @@ LightmapSettings:
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ShowResolutionOverlay: 1
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 0
--- !u!196 &5
@ -109,13 +109,17 @@ NavMeshSettings:
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &300643201
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100010, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_CorrespondingSourceObject: {fileID: 100010, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 300643204}
- component: {fileID: 300643203}
@ -130,9 +134,10 @@ GameObject:
--- !u!114 &300643202
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 11400016, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 11400016, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 300643201}
m_Enabled: 1
m_EditorHideFlags: 0
@ -145,8 +150,6 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
@ -155,19 +158,23 @@ MonoBehaviour:
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
--- !u!222 &300643203
CanvasRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22200008, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22200008, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 300643201}
m_CullTransparentMesh: 0
--- !u!224 &300643204
RectTransform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22400010, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22400010, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 300643201}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
@ -184,9 +191,11 @@ RectTransform:
--- !u!1 &813140185
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100012, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_CorrespondingSourceObject: {fileID: 100012, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 813140186}
- component: {fileID: 813140189}
@ -202,9 +211,10 @@ GameObject:
--- !u!224 &813140186
RectTransform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22400012, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22400012, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 813140185}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
@ -215,15 +225,16 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0.000012397766, y: -0.000091552734}
m_AnchoredPosition: {x: 0, y: 0.00004486633}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 1}
--- !u!114 &813140187
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 11400020, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 11400020, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 813140185}
m_Enabled: 1
m_EditorHideFlags: 0
@ -235,9 +246,10 @@ MonoBehaviour:
--- !u!114 &813140188
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 11400018, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 11400018, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 813140185}
m_Enabled: 1
m_EditorHideFlags: 0
@ -250,8 +262,6 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 20
@ -265,44 +275,169 @@ MonoBehaviour:
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: "IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.\r\n\r\n
By downloading, copying, installing or using the software you agree to this license.\r\n
If you do not agree to this license, do not download, install,\r\n copy or use
the software.\r\n\r\n\r\n License Agreement\r\n For
Open Source Computer Vision Library\r\n\r\nCopyright (C) 2000-2008, Intel Corporation,
all rights reserved.\r\nCopyright (C) 2008-2011, Willow Garage Inc., all rights
reserved.\r\nThird party copyrights are property of their respective owners.\r\n\r\nRedistribution
and use in source and binary forms, with or without modification,\r\nare permitted
provided that the following conditions are met:\r\n\r\n * Redistributions of
source code must retain the above copyright notice,\r\n this list of conditions
and the following disclaimer.\r\n\r\n * Redistributions in binary form must reproduce
the above copyright notice,\r\n this list of conditions and the following disclaimer
in the documentation\r\n and/or other materials provided with the distribution.\r\n\r\n
\ * The name of the copyright holders may not be used to endorse or promote products\r\n
\ derived from this software without specific prior written permission.\r\n\r\nThis
software is provided by the copyright holders and contributors \"as is\" and\r\nany
express or implied warranties, including, but not limited to, the implied\r\nwarranties
of merchantability and fitness for a particular purpose are disclaimed.\r\nIn
no event shall the Intel Corporation or contributors be liable for any direct,\r\nindirect,
incidental, special, exemplary, or consequential damages\r\n(including, but not
limited to, procurement of substitute goods or services;\r\nloss of use, data,
or profits; or business interruption) however caused\r\nand on any theory of liability,
whether in contract, strict liability,\r\nor tort (including negligence or otherwise)
arising in any way out of\r\nthe use of this software, even if advised of the
possibility of such damage.\r\n"
m_Text: "This software includes the work that is distributed in the Apache License
2.0.\r\n\r\n Apache License\r\n Version
2.0, January 2004\r\n http://www.apache.org/licenses/\r\n\r\n
\ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r\n\r\n 1. Definitions.\r\n\r\n
\ \"License\" shall mean the terms and conditions for use, reproduction,\r\n
\ and distribution as defined by Sections 1 through 9 of this document.\r\n\r\n
\ \"Licensor\" shall mean the copyright owner or entity authorized by\r\n
\ the copyright owner that is granting the License.\r\n\r\n \"Legal Entity\"
shall mean the union of the acting entity and all\r\n other entities that
control, are controlled by, or are under common\r\n control with that entity.
For the purposes of this definition,\r\n \"control\" means (i) the power,
direct or indirect, to cause the\r\n direction or management of such entity,
whether by contract or\r\n otherwise, or (ii) ownership of fifty percent
(50%) or more of the\r\n outstanding shares, or (iii) beneficial ownership
of such entity.\r\n\r\n \"You\" (or \"Your\") shall mean an individual or
Legal Entity\r\n exercising permissions granted by this License.\r\n\r\n
\ \"Source\" form shall mean the preferred form for making modifications,\r\n
\ including but not limited to software source code, documentation\r\n source,
and configuration files.\r\n\r\n \"Object\" form shall mean any form resulting
from mechanical\r\n transformation or translation of a Source form, including
but\r\n not limited to compiled object code, generated documentation,\r\n
\ and conversions to other media types.\r\n\r\n \"Work\" shall mean the
work of authorship, whether in Source or\r\n Object form, made available
under the License, as indicated by a\r\n copyright notice that is included
in or attached to the work\r\n (an example is provided in the Appendix below).\r\n\r\n
\ \"Derivative Works\" shall mean any work, whether in Source or Object\r\n
\ form, that is based on (or derived from) the Work and for which the\r\n
\ editorial revisions, annotations, elaborations, or other modifications\r\n
\ represent, as a whole, an original work of authorship. For the purposes\r\n
\ of this License, Derivative Works shall not include works that remain\r\n
\ separable from, or merely link (or bind by name) to the interfaces of,\r\n
\ the Work and Derivative Works thereof.\r\n\r\n \"Contribution\" shall
mean any work of authorship, including\r\n the original version of the Work
and any modifications or additions\r\n to that Work or Derivative Works thereof,
that is intentionally\r\n submitted to Licensor for inclusion in the Work
by the copyright owner\r\n or by an individual or Legal Entity authorized
to submit on behalf of\r\n the copyright owner. For the purposes of this
definition, \"submitted\"\r\n means any form of electronic, verbal, or written
communication sent\r\n to the Licensor or its representatives, including
but not limited to\r\n communication on electronic mailing lists, source
code control systems,\r\n and issue tracking systems that are managed by,
or on behalf of, the\r\n Licensor for the purpose of discussing and improving
the Work, but\r\n excluding communication that is conspicuously marked or
otherwise\r\n designated in writing by the copyright owner as \"Not a Contribution.\"\r\n\r\n
\ \"Contributor\" shall mean Licensor and any individual or Legal Entity\r\n
\ on behalf of whom a Contribution has been received by Licensor and\r\n subsequently
incorporated within the Work.\r\n\r\n 2. Grant of Copyright License. Subject
to the terms and conditions of\r\n this License, each Contributor hereby
grants to You a perpetual,\r\n worldwide, non-exclusive, no-charge, royalty-free,
irrevocable\r\n copyright license to reproduce, prepare Derivative Works
of,\r\n publicly display, publicly perform, sublicense, and distribute the\r\n
\ Work and such Derivative Works in Source or Object form.\r\n\r\n 3. Grant
of Patent License. Subject to the terms and conditions of\r\n this License,
each Contributor hereby grants to You a perpetual,\r\n worldwide, non-exclusive,
no-charge, royalty-free, irrevocable\r\n (except as stated in this section)
patent license to make, have made,\r\n use, offer to sell, sell, import,
and otherwise transfer the Work,\r\n where such license applies only to those
patent claims licensable\r\n by such Contributor that are necessarily infringed
by their\r\n Contribution(s) alone or by combination of their Contribution(s)\r\n
\ with the Work to which such Contribution(s) was submitted. If You\r\n institute
patent litigation against any entity (including a\r\n cross-claim or counterclaim
in a lawsuit) alleging that the Work\r\n or a Contribution incorporated within
the Work constitutes direct\r\n or contributory patent infringement, then
any patent licenses\r\n granted to You under this License for that Work shall
terminate\r\n as of the date such litigation is filed.\r\n\r\n 4. Redistribution.
You may reproduce and distribute copies of the\r\n Work or Derivative Works
thereof in any medium, with or without\r\n modifications, and in Source or
Object form, provided that You\r\n meet the following conditions:\r\n\r\n
\ (a) You must give any other recipients of the Work or\r\n Derivative
Works a copy of this License; and\r\n\r\n (b) You must cause any modified
files to carry prominent notices\r\n stating that You changed the files;
and\r\n\r\n (c) You must retain, in the Source form of any Derivative Works\r\n
\ that You distribute, all copyright, patent, trademark, and\r\n attribution
notices from the Source form of the Work,\r\n excluding those notices
that do not pertain to any part of\r\n the Derivative Works; and\r\n\r\n
\ (d) If the Work includes a \"NOTICE\" text file as part of its\r\n distribution,
then any Derivative Works that You distribute must\r\n include a readable
copy of the attribution notices contained\r\n within such NOTICE file,
excluding those notices that do not\r\n pertain to any part of the Derivative
Works, in at least one\r\n of the following places: within a NOTICE text
file distributed\r\n as part of the Derivative Works; within the Source
form or\r\n documentation, if provided along with the Derivative Works;
or,\r\n within a display generated by the Derivative Works, if and\r\n
\ wherever such third-party notices normally appear. The contents\r\n
\ of the NOTICE file are for informational purposes only and\r\n do
not modify the License. You may add Your own attribution\r\n notices
within Derivative Works that You distribute, alongside\r\n or as an addendum
to the NOTICE text from the Work, provided\r\n that such additional attribution
notices cannot be construed\r\n as modifying the License.\r\n\r\n You
may add Your own copyright statement to Your modifications and\r\n may provide
additional or different license terms and conditions\r\n for use, reproduction,
or distribution of Your modifications, or\r\n for any such Derivative Works
as a whole, provided Your use,\r\n reproduction, and distribution of the
Work otherwise complies with\r\n the conditions stated in this License.\r\n\r\n
\ 5. Submission of Contributions. Unless You explicitly state otherwise,\r\n
\ any Contribution intentionally submitted for inclusion in the Work\r\n by
You to the Licensor shall be under the terms and conditions of\r\n this License,
without any additional terms or conditions.\r\n Notwithstanding the above,
nothing herein shall supersede or modify\r\n the terms of any separate license
agreement you may have executed\r\n with Licensor regarding such Contributions.\r\n\r\n
\ 6. Trademarks. This License does not grant permission to use the trade\r\n
\ names, trademarks, service marks, or product names of the Licensor,\r\n
\ except as required for reasonable and customary use in describing the\r\n
\ origin of the Work and reproducing the content of the NOTICE file.\r\n\r\n
\ 7. Disclaimer of Warranty. Unless required by applicable law or\r\n agreed
to in writing, Licensor provides the Work (and each\r\n Contributor provides
its Contributions) on an \"AS IS\" BASIS,\r\n WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or\r\n implied, including, without limitation,
any warranties or conditions\r\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY,
or FITNESS FOR A\r\n PARTICULAR PURPOSE. You are solely responsible for determining
the\r\n appropriateness of using or redistributing the Work and assume any\r\n
\ risks associated with Your exercise of permissions under this License.\r\n\r\n
\ 8. Limitation of Liability. In no event and under no legal theory,\r\n whether
in tort (including negligence), contract, or otherwise,\r\n unless required
by applicable law (such as deliberate and grossly\r\n negligent acts) or
agreed to in writing, shall any Contributor be\r\n liable to You for damages,
including any direct, indirect, special,\r\n incidental, or consequential
damages of any character arising as a\r\n result of this License or out of
the use or inability to use the\r\n Work (including but not limited to damages
for loss of goodwill,\r\n work stoppage, computer failure or malfunction,
or any and all\r\n other commercial damages or losses), even if such Contributor\r\n
\ has been advised of the possibility of such damages.\r\n\r\n 9. Accepting
Warranty or Additional Liability. While redistributing\r\n the Work or Derivative
Works thereof, You may choose to offer,\r\n and charge a fee for, acceptance
of support, warranty, indemnity,\r\n or other liability obligations and/or
rights consistent with this\r\n License. However, in accepting such obligations,
You may act only\r\n on Your own behalf and on Your sole responsibility,
not on behalf\r\n of any other Contributor, and only if You agree to indemnify,\r\n
\ defend, and hold each Contributor harmless for any liability\r\n incurred
by, or claims asserted against, such Contributor by reason\r\n of your accepting
any such warranty or additional liability.\r\n\r\n END OF TERMS AND CONDITIONS\r\n\r\n
\ APPENDIX: How to apply the Apache License to your work.\r\n\r\n To apply
the Apache License to your work, attach the following\r\n boilerplate notice,
with the fields enclosed by brackets \"[]\"\r\n replaced with your own identifying
information. (Don't include\r\n the brackets!) The text should be enclosed
in the appropriate\r\n comment syntax for the file format. We also recommend
that a\r\n file or class name and description of purpose be included on the\r\n
\ same \"printed page\" as the copyright notice for easier\r\n identification
within third-party archives.\r\n\r\n Copyright [yyyy] [name of copyright owner]\r\n\r\n
\ Licensed under the Apache License, Version 2.0 (the \"License\");\r\n you
may not use this file except in compliance with the License.\r\n You may obtain
a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\n
\ Unless required by applicable law or agreed to in writing, software\r\n distributed
under the License is distributed on an \"AS IS\" BASIS,\r\n WITHOUT WARRANTIES
OR CONDITIONS OF ANY KIND, either express or implied.\r\n See the License for
the specific language governing permissions and\r\n limitations under the License."
--- !u!222 &813140189
CanvasRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22200010, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22200010, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 813140185}
m_CullTransparentMesh: 0
--- !u!1 &905987153
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100008, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_CorrespondingSourceObject: {fileID: 100008, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 905987154}
m_Layer: 5
@ -315,9 +450,10 @@ GameObject:
--- !u!224 &905987154
RectTransform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22400008, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22400008, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 905987153}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
@ -335,9 +471,11 @@ RectTransform:
--- !u!1 &1207454862
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100014, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_CorrespondingSourceObject: {fileID: 100014, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1207454863}
- component: {fileID: 1207454866}
@ -353,9 +491,10 @@ GameObject:
--- !u!224 &1207454863
RectTransform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22400014, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22400014, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1207454862}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
@ -374,9 +513,10 @@ RectTransform:
--- !u!114 &1207454864
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 11400022, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 11400022, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1207454862}
m_Enabled: 1
m_EditorHideFlags: 0
@ -391,9 +531,10 @@ MonoBehaviour:
--- !u!114 &1207454865
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 11400024, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 11400024, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1207454862}
m_Enabled: 1
m_EditorHideFlags: 0
@ -413,9 +554,10 @@ MonoBehaviour:
--- !u!223 &1207454866
Canvas:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22300000, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22300000, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1207454862}
m_Enabled: 1
serializedVersion: 3
@ -434,9 +576,11 @@ Canvas:
--- !u!1 &1288247988
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100016, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_CorrespondingSourceObject: {fileID: 100016, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1288247989}
m_Layer: 5
@ -449,9 +593,10 @@ GameObject:
--- !u!224 &1288247989
RectTransform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22400016, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22400016, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1288247988}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
@ -470,9 +615,11 @@ RectTransform:
--- !u!1 &1815817330
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100004, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_CorrespondingSourceObject: {fileID: 100004, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1815817331}
- component: {fileID: 1815817334}
@ -488,9 +635,10 @@ GameObject:
--- !u!224 &1815817331
RectTransform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22400004, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22400004, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1815817330}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
@ -508,9 +656,10 @@ RectTransform:
--- !u!114 &1815817332
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 11400010, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 11400010, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1815817330}
m_Enabled: 1
m_EditorHideFlags: 0
@ -556,14 +705,13 @@ MonoBehaviour:
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
--- !u!114 &1815817333
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 11400012, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 11400012, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1815817330}
m_Enabled: 1
m_EditorHideFlags: 0
@ -576,8 +724,6 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
@ -586,19 +732,24 @@ MonoBehaviour:
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
--- !u!222 &1815817334
CanvasRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22200004, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22200004, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1815817330}
m_CullTransparentMesh: 0
--- !u!1 &1845963478
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100000, guid: 1ccccd5701fc6ee48964a3c728b8ab62, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_CorrespondingSourceObject: {fileID: 100000, guid: 1ccccd5701fc6ee48964a3c728b8ab62,
type: 2}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1845963482}
- component: {fileID: 1845963481}
@ -613,9 +764,10 @@ GameObject:
--- !u!114 &1845963480
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 11400002, guid: 1ccccd5701fc6ee48964a3c728b8ab62,
m_CorrespondingSourceObject: {fileID: 11400002, guid: 1ccccd5701fc6ee48964a3c728b8ab62,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1845963478}
m_Enabled: 1
m_EditorHideFlags: 0
@ -632,9 +784,10 @@ MonoBehaviour:
--- !u!114 &1845963481
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 11400004, guid: 1ccccd5701fc6ee48964a3c728b8ab62,
m_CorrespondingSourceObject: {fileID: 11400004, guid: 1ccccd5701fc6ee48964a3c728b8ab62,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1845963478}
m_Enabled: 1
m_EditorHideFlags: 0
@ -647,8 +800,10 @@ MonoBehaviour:
--- !u!4 &1845963482
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 400000, guid: 1ccccd5701fc6ee48964a3c728b8ab62, type: 2}
m_PrefabInternal: {fileID: 0}
m_CorrespondingSourceObject: {fileID: 400000, guid: 1ccccd5701fc6ee48964a3c728b8ab62,
type: 2}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1845963478}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
@ -660,9 +815,10 @@ Transform:
--- !u!1 &2009915974
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2009915980}
- component: {fileID: 2009915979}
@ -679,8 +835,9 @@ GameObject:
--- !u!114 &2009915975
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2009915974}
m_Enabled: 1
m_EditorHideFlags: 0
@ -690,27 +847,35 @@ MonoBehaviour:
--- !u!81 &2009915976
AudioListener:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2009915974}
m_Enabled: 1
--- !u!124 &2009915977
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2009915974}
m_Enabled: 1
--- !u!20 &2009915979
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2009915974}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0.019607844}
m_projectionMatrixMode: 1
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_GateFitMode: 2
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
@ -732,16 +897,17 @@ Camera:
m_TargetEye: 3
m_HDR: 0
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
m_StereoMirrorMode: 0
--- !u!4 &2009915980
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2009915974}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
@ -753,9 +919,11 @@ Transform:
--- !u!1 &2027945392
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100002, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_CorrespondingSourceObject: {fileID: 100002, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2027945393}
- component: {fileID: 2027945396}
@ -771,9 +939,10 @@ GameObject:
--- !u!224 &2027945393
RectTransform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22400002, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22400002, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2027945392}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
@ -791,9 +960,10 @@ RectTransform:
--- !u!114 &2027945394
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 11400006, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 11400006, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2027945392}
m_Enabled: 1
m_EditorHideFlags: 0
@ -828,19 +998,18 @@ MonoBehaviour:
m_HandleRect: {fileID: 300643204}
m_Direction: 2
m_Value: 1
m_Size: 0.66089743
m_Size: 0.14562789
m_NumberOfSteps: 0
m_OnValueChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.Scrollbar+ScrollEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
--- !u!114 &2027945395
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 11400008, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 11400008, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2027945392}
m_Enabled: 1
m_EditorHideFlags: 0
@ -853,8 +1022,6 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
@ -863,19 +1030,24 @@ MonoBehaviour:
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
--- !u!222 &2027945396
CanvasRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22200002, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22200002, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2027945392}
m_CullTransparentMesh: 0
--- !u!1 &2040852814
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100000, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_CorrespondingSourceObject: {fileID: 100000, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2040852815}
- component: {fileID: 2040852819}
@ -892,9 +1064,10 @@ GameObject:
--- !u!224 &2040852815
RectTransform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22400000, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22400000, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2040852814}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
@ -912,9 +1085,10 @@ RectTransform:
--- !u!114 &2040852816
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 11400000, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 11400000, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2040852814}
m_Enabled: 1
m_EditorHideFlags: 0
@ -927,8 +1101,6 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
@ -937,19 +1109,23 @@ MonoBehaviour:
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
--- !u!222 &2040852817
CanvasRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22200000, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22200000, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2040852814}
m_CullTransparentMesh: 0
--- !u!114 &2040852818
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 11400002, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 11400002, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2040852814}
m_Enabled: 1
m_EditorHideFlags: 0
@ -960,9 +1136,10 @@ MonoBehaviour:
--- !u!114 &2040852819
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 11400004, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 11400004, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2040852814}
m_Enabled: 1
m_EditorHideFlags: 0
@ -987,14 +1164,14 @@ MonoBehaviour:
m_OnValueChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.ScrollRect+ScrollRectEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
--- !u!1 &2092781163
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 100006, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_CorrespondingSourceObject: {fileID: 100006, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2092781164}
- component: {fileID: 2092781166}
@ -1009,9 +1186,10 @@ GameObject:
--- !u!224 &2092781164
RectTransform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22400006, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22400006, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2092781163}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
@ -1028,9 +1206,10 @@ RectTransform:
--- !u!114 &2092781165
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 11400014, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 11400014, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2092781163}
m_Enabled: 1
m_EditorHideFlags: 0
@ -1043,8 +1222,6 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 14
@ -1062,7 +1239,9 @@ MonoBehaviour:
--- !u!222 &2092781166
CanvasRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 22200006, guid: e4ed316126173e54da8ebe67c2421b33,
m_CorrespondingSourceObject: {fileID: 22200006, guid: e4ed316126173e54da8ebe67c2421b33,
type: 2}
m_PrefabInternal: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2092781163}
m_CullTransparentMesh: 0

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

@ -1,15 +1,14 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using DlibFaceLandmarkDetector;
using OpenCVForUnity.ObjdetectModule;
using DlibFaceLandmarkDetector;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using OpenCVForUnity.ObjdetectModule;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Rect = OpenCVForUnity.CoreModule.Rect;
namespace FaceMaskExample
@ -17,7 +16,7 @@ namespace FaceMaskExample
/// <summary>
/// Texture2D FaceMask Example
/// </summary>
[RequireComponent (typeof(TrackedMeshOverlay))]
[RequireComponent(typeof(TrackedMeshOverlay))]
public class Texture2DFaceMaskExample : MonoBehaviour
{
/// <summary>
@ -53,14 +52,14 @@ namespace FaceMaskExample
/// <summary>
/// The frontal face rate lower limit.
/// </summary>
[Range (0.0f, 1.0f)]
[Range(0.0f, 1.0f)]
public float frontalFaceRateLowerLimit = 0.85f;
/// <summary>
/// Determines if displays face rects.
/// </summary>
public bool displayFaceRects = false;
/// <summary>
/// The toggle for switching face rects display state
/// </summary>
@ -75,12 +74,12 @@ namespace FaceMaskExample
/// The toggle for switching debug face points display state.
/// </summary>
public Toggle displayDebugFacePointsToggle;
/// <summary>
/// The image texture.
/// </summary>
Texture2D imgTexture;
/// <summary>
/// The cascade.
/// </summary>
@ -111,45 +110,47 @@ namespace FaceMaskExample
/// </summary>
string sp_human_face_68_dat_filepath;
#if UNITY_WEBGL && !UNITY_EDITOR
#if UNITY_WEBGL
IEnumerator getFilePath_Coroutine;
#endif
#endif
// Use this for initialization
void Start ()
void Start()
{
#if UNITY_WEBGL && !UNITY_EDITOR
getFilePath_Coroutine = GetFilePath ();
StartCoroutine (getFilePath_Coroutine);
#else
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
#if UNITY_WEBGL
getFilePath_Coroutine = GetFilePath();
StartCoroutine(getFilePath_Coroutine);
#else
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
}
#if UNITY_WEBGL && !UNITY_EDITOR
private IEnumerator GetFilePath ()
#if UNITY_WEBGL
private IEnumerator GetFilePath()
{
var getFilePathAsync_0_Coroutine = OpenCVForUnity.UnityUtils.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;
});
yield return getFilePathAsync_0_Coroutine;
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.UnityUtils.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;
});
yield return getFilePathAsync_1_Coroutine;
getFilePath_Coroutine = null;
Run ();
Run();
}
#endif
#endif
private void Run ()
private void Run()
{
meshOverlay = this.GetComponent<TrackedMeshOverlay> ();
meshOverlay = this.GetComponent<TrackedMeshOverlay>();
displayFaceRectsToggle.isOn = displayFaceRects;
useDlibFaceDetecterToggle.isOn = useDlibFaceDetecter;
@ -158,13 +159,13 @@ namespace FaceMaskExample
displayDebugFacePointsToggle.isOn = displayDebugFacePoints;
if (imgTexture == null)
imgTexture = Resources.Load ("family") as Texture2D;
imgTexture = Resources.Load("family") as Texture2D;
gameObject.transform.localScale = new Vector3 (imgTexture.width, imgTexture.height, 1);
Debug.Log ("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation);
gameObject.transform.localScale = new Vector3(imgTexture.width, imgTexture.height, 1);
Debug.Log("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation);
meshOverlay.UpdateOverlayTransform (gameObject.transform);
meshOverlay.Reset ();
meshOverlay.UpdateOverlayTransform(gameObject.transform);
meshOverlay.Reset();
float width = 0;
@ -174,265 +175,307 @@ namespace FaceMaskExample
float widthScale = (float)Screen.width / width;
float heightScale = (float)Screen.height / height;
if (widthScale < heightScale) {
if (widthScale < heightScale)
{
Camera.main.orthographicSize = (width * (float)Screen.height / (float)Screen.width) / 2;
} else {
}
else
{
Camera.main.orthographicSize = height / 2;
}
Mat rgbaMat = new Mat (imgTexture.height, imgTexture.width, CvType.CV_8UC4);
Mat rgbaMat = new Mat(imgTexture.height, imgTexture.width, CvType.CV_8UC4);
OpenCVForUnity.UnityUtils.Utils.texture2DToMat (imgTexture, rgbaMat);
Debug.Log ("rgbaMat ToString " + rgbaMat.ToString ());
OpenCVForUnity.UnityUtils.Utils.texture2DToMat(imgTexture, rgbaMat);
Debug.Log("rgbaMat ToString " + rgbaMat.ToString());
if (faceLandmarkDetector == null)
faceLandmarkDetector = new FaceLandmarkDetector (sp_human_face_68_dat_filepath);
faceLandmarkDetector = new FaceLandmarkDetector(sp_human_face_68_dat_filepath);
faceMaskColorCorrector = faceMaskColorCorrector ?? new FaceMaskColorCorrector ();
FrontalFaceChecker frontalFaceChecker = new FrontalFaceChecker (width, height);
faceMaskColorCorrector = faceMaskColorCorrector ?? new FaceMaskColorCorrector();
FrontalFaceChecker frontalFaceChecker = new FrontalFaceChecker(width, height);
// detect faces.
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 Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
}
} else {
if (cascade == null)
cascade = new CascadeClassifier (haarcascade_frontalface_alt_xml_filepath);
// if (cascade.empty ()) {
// Debug.LogError ("cascade file is not loaded.Please copy from “FaceTrackerExample/StreamingAssets/” to “Assets/StreamingAssets/” folder. ");
// }
// convert image to greyscale.
Mat gray = new Mat ();
Imgproc.cvtColor (rgbaMat, gray, Imgproc.COLOR_RGBA2GRAY);
List<Rect> detectResult = new List<Rect>();
if (useDlibFaceDetecter)
{
OpenCVForUnityUtils.SetImage(faceLandmarkDetector, rgbaMat);
List<UnityEngine.Rect> result = faceLandmarkDetector.Detect();
MatOfRect faces = new MatOfRect ();
Imgproc.equalizeHist (gray, gray);
cascade.detectMultiScale (gray, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size (gray.cols () * 0.05, gray.cols () * 0.05), new Size ());
foreach (var unityRect in result)
{
detectResult.Add(new Rect((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
}
}
else
{
if (cascade == null)
cascade = new CascadeClassifier(haarcascade_frontalface_alt_xml_filepath);
//if (cascade.empty())
//{
// Debug.LogError("cascade file is not loaded.Please copy from “FaceTrackerExample/StreamingAssets/” to “Assets/StreamingAssets/” folder. ");
//}
// convert image to greyscale.
Mat gray = new Mat();
Imgproc.cvtColor(rgbaMat, gray, Imgproc.COLOR_RGBA2GRAY);
MatOfRect faces = new MatOfRect();
Imgproc.equalizeHist(gray, gray);
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 ();
detectResult = faces.toList();
// corrects the deviation of a detection result between OpenCV and Dlib.
foreach (Rect r in detectResult) {
foreach (Rect r in detectResult)
{
r.y += (int)(r.height * 0.1f);
}
gray.Dispose ();
}
gray.Dispose();
}
// detect face landmark points.
OpenCVForUnityUtils.SetImage (faceLandmarkDetector, rgbaMat);
List<List<Vector2>> landmarkPoints = new List<List<Vector2>> ();
foreach (var openCVRect in detectResult) {
UnityEngine.Rect rect = new UnityEngine.Rect (openCVRect.x, openCVRect.y, openCVRect.width, openCVRect.height);
Debug.Log ("face : " + rect);
OpenCVForUnityUtils.SetImage(faceLandmarkDetector, rgbaMat);
List<List<Vector2>> landmarkPoints = new List<List<Vector2>>();
foreach (var openCVRect in detectResult)
{
UnityEngine.Rect rect = new UnityEngine.Rect(openCVRect.x, openCVRect.y, openCVRect.width, openCVRect.height);
Debug.Log("face : " + rect);
//OpenCVForUnityUtils.DrawFaceRect(imgMat, rect, new Scalar(255, 0, 0, 255), 2);
List<Vector2> points = faceLandmarkDetector.DetectLandmark (rect);
List<Vector2> points = faceLandmarkDetector.DetectLandmark(rect);
//OpenCVForUnityUtils.DrawFaceLandmark(imgMat, points, new Scalar(0, 255, 0, 255), 2);
landmarkPoints.Add (points);
landmarkPoints.Add(points);
}
// mask faces.
int[] face_nums = new int[landmarkPoints.Count];
for (int i = 0; i < face_nums.Length; i++) {
face_nums [i] = i;
for (int i = 0; i < face_nums.Length; i++)
{
face_nums[i] = i;
}
face_nums = face_nums.OrderBy (i => System.Guid.NewGuid ()).ToArray ();
face_nums = face_nums.OrderBy(i => System.Guid.NewGuid()).ToArray();
float imageWidth = meshOverlay.width;
float imageHeight = meshOverlay.height;
float imageHeight = meshOverlay.height;
float maskImageWidth = imgTexture.width;
float maskImageHeight = imgTexture.height;
TrackedMesh tm;
for (int i = 0; i < face_nums.Length; i++) {
for (int i = 0; i < face_nums.Length; i++)
{
meshOverlay.CreateObject(i, imgTexture);
tm = meshOverlay.GetObjectById(i);
meshOverlay.CreateObject (i, imgTexture);
tm = meshOverlay.GetObjectById (i);
Vector3[] vertices = tm.meshFilter.mesh.vertices;
if (vertices.Length == landmarkPoints [face_nums [i]].Count) {
for (int j = 0; j < vertices.Length; j++) {
vertices [j].x = landmarkPoints [face_nums [i]] [j].x / imageWidth - 0.5f;
vertices [j].y = 0.5f - landmarkPoints [face_nums [i]] [j].y / imageHeight;
if (vertices.Length == landmarkPoints[face_nums[i]].Count)
{
for (int j = 0; j < vertices.Length; j++)
{
vertices[j].x = landmarkPoints[face_nums[i]][j].x / imageWidth - 0.5f;
vertices[j].y = 0.5f - landmarkPoints[face_nums[i]][j].y / imageHeight;
}
}
Vector2[] uv = tm.meshFilter.mesh.uv;
if (uv.Length == landmarkPoints [face_nums [0]].Count) {
for (int jj = 0; jj < uv.Length; jj++) {
uv [jj].x = landmarkPoints [face_nums [0]] [jj].x / maskImageWidth;
uv [jj].y = (maskImageHeight - landmarkPoints [face_nums [0]] [jj].y) / maskImageHeight;
if (uv.Length == landmarkPoints[face_nums[0]].Count)
{
for (int jj = 0; jj < uv.Length; jj++)
{
uv[jj].x = landmarkPoints[face_nums[0]][jj].x / maskImageWidth;
uv[jj].y = (maskImageHeight - landmarkPoints[face_nums[0]][jj].y) / maskImageHeight;
}
}
meshOverlay.UpdateObject (i, vertices, null, uv);
if (enableColorCorrection) {
faceMaskColorCorrector.CreateLUTTex (i);
Texture2D LUTTex = faceMaskColorCorrector.UpdateLUTTex (i, rgbaMat, rgbaMat, landmarkPoints [face_nums [0]], landmarkPoints [face_nums [i]]);
tm.sharedMaterial.SetTexture ("_LUTTex", LUTTex);
tm.sharedMaterial.SetFloat ("_ColorCorrection", 1f);
} else {
tm.sharedMaterial.SetFloat ("_ColorCorrection", 0f);
meshOverlay.UpdateObject(i, vertices, null, uv);
if (enableColorCorrection)
{
faceMaskColorCorrector.CreateLUTTex(i);
Texture2D LUTTex = faceMaskColorCorrector.UpdateLUTTex(i, rgbaMat, rgbaMat, landmarkPoints[face_nums[0]], landmarkPoints[face_nums[i]]);
tm.sharedMaterial.SetTexture("_LUTTex", LUTTex);
tm.sharedMaterial.SetFloat("_ColorCorrection", 1f);
}
else
{
tm.sharedMaterial.SetFloat("_ColorCorrection", 0f);
}
// filter non frontal faces.
if (filterNonFrontalFaces && frontalFaceChecker.GetFrontalFaceRate (landmarkPoints [i]) < frontalFaceRateLowerLimit) {
tm.sharedMaterial.SetFloat ("_Fade", 1f);
} else {
tm.sharedMaterial.SetFloat ("_Fade", 0.3f);
if (filterNonFrontalFaces && frontalFaceChecker.GetFrontalFaceRate(landmarkPoints[i]) < frontalFaceRateLowerLimit)
{
tm.sharedMaterial.SetFloat("_Fade", 1f);
}
else
{
tm.sharedMaterial.SetFloat("_Fade", 0.3f);
}
}
// draw face rects.
if (displayFaceRects) {
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);
if (displayFaceRects)
{
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++) {
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);
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);
}
}
// draw face points.
if (displayDebugFacePoints) {
for (int i = 0; i < landmarkPoints.Count; i++) {
OpenCVForUnityUtils.DrawFaceLandmark (rgbaMat, landmarkPoints [i], new Scalar (0, 255, 0, 255), 2);
if (displayDebugFacePoints)
{
for (int i = 0; i < landmarkPoints.Count; i++)
{
OpenCVForUnityUtils.DrawFaceLandmark(rgbaMat, landmarkPoints[i], new Scalar(0, 255, 0, 255), 2);
}
}
Texture2D texture = new Texture2D (rgbaMat.cols (), rgbaMat.rows (), TextureFormat.RGBA32, false);
OpenCVForUnity.UnityUtils.Utils.matToTexture2D (rgbaMat, texture);
gameObject.transform.GetComponent<Renderer> ().material.mainTexture = texture;
Texture2D texture = new Texture2D(rgbaMat.cols(), rgbaMat.rows(), TextureFormat.RGBA32, false);
OpenCVForUnity.UnityUtils.Utils.matToTexture2D(rgbaMat, texture);
gameObject.transform.GetComponent<Renderer>().material.mainTexture = texture;
frontalFaceChecker.Dispose ();
rgbaMat.Dispose ();
frontalFaceChecker.Dispose();
rgbaMat.Dispose();
}
/// <summary>
/// Raises the destroy event.
/// </summary>
void OnDestroy ()
void OnDestroy()
{
if (faceMaskColorCorrector != null)
faceMaskColorCorrector.Dispose ();
faceMaskColorCorrector.Dispose();
if (faceLandmarkDetector != null)
faceLandmarkDetector.Dispose ();
faceLandmarkDetector.Dispose();
if (cascade != null)
cascade.Dispose ();
cascade.Dispose();
#if UNITY_WEBGL && !UNITY_EDITOR
if (getFilePath_Coroutine != null) {
StopCoroutine (getFilePath_Coroutine);
((IDisposable)getFilePath_Coroutine).Dispose ();
#if UNITY_WEBGL
if (getFilePath_Coroutine != null)
{
StopCoroutine(getFilePath_Coroutine);
((IDisposable)getFilePath_Coroutine).Dispose();
}
#endif
#endif
}
/// <summary>
/// Raises the back button click event.
/// </summary>
public void OnBackButtonClick ()
public void OnBackButtonClick()
{
SceneManager.LoadScene ("FaceMaskExample");
SceneManager.LoadScene("FaceMaskExample");
}
/// <summary>
/// Raises the shuffle button click event.
/// </summary>
public void OnShuffleButtonClick ()
public void OnShuffleButtonClick()
{
if (imgTexture != null)
Run ();
Run();
}
/// <summary>
/// Raises the use Dlib face detector toggle value changed event.
/// </summary>
public void OnUseDlibFaceDetecterToggleValueChanged ()
public void OnUseDlibFaceDetecterToggleValueChanged()
{
if (useDlibFaceDetecterToggle.isOn) {
if (useDlibFaceDetecterToggle.isOn)
{
useDlibFaceDetecter = true;
} else {
}
else
{
useDlibFaceDetecter = false;
}
if (imgTexture != null)
Run ();
Run();
}
/// <summary>
/// Raises the enable color correction toggle value changed event.
/// </summary>
public void OnEnableColorCorrectionToggleValueChanged ()
public void OnEnableColorCorrectionToggleValueChanged()
{
if (enableColorCorrectionToggle.isOn) {
if (enableColorCorrectionToggle.isOn)
{
enableColorCorrection = true;
} else {
}
else
{
enableColorCorrection = false;
}
if (imgTexture != null)
Run ();
Run();
}
/// <summary>
/// Raises the filter non frontal faces toggle value changed event.
/// </summary>
public void OnFilterNonFrontalFacesToggleValueChanged ()
public void OnFilterNonFrontalFacesToggleValueChanged()
{
if (filterNonFrontalFacesToggle.isOn) {
if (filterNonFrontalFacesToggle.isOn)
{
filterNonFrontalFaces = true;
} else {
}
else
{
filterNonFrontalFaces = false;
}
if (imgTexture != null)
Run ();
Run();
}
/// <summary>
/// Raises the display face rects toggle value changed event.
/// </summary>
public void OnDisplayFaceRectsToggleValueChanged ()
public void OnDisplayFaceRectsToggleValueChanged()
{
if (displayFaceRectsToggle.isOn) {
if (displayFaceRectsToggle.isOn)
{
displayFaceRects = true;
} else {
}
else
{
displayFaceRects = false;
}
if (imgTexture != null)
Run ();
Run();
}
/// <summary>
/// Raises the display debug face points toggle value changed event.
/// </summary>
public void OnDisplayDebugFacePointsToggleValueChanged ()
public void OnDisplayDebugFacePointsToggleValueChanged()
{
if (displayDebugFacePointsToggle.isOn) {
if (displayDebugFacePointsToggle.isOn)
{
displayDebugFacePoints = true;
} else {
}
else
{
displayDebugFacePoints = false;
}
if (imgTexture != null)
Run ();
Run();
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: b5b15518ef2238443905fff4839cfaec
timeCreated: 1483051440
licenseType: Free
MovieImporter:
serializedVersion: 1
quality: .5
linearTexture: 0
userData:
assetBundleName:
assetBundleVariant:

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

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0855c0873096fe74a830babe059e61ed
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: