update 1.0.9
This commit is contained in:
Родитель
33d73abe73
Коммит
5f4576a907
|
@ -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
Двоичные данные
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:
|
Загрузка…
Ссылка в новой задаче