diff --git a/Assets/FaceTrackerExample/FaceTrackerARExample/FaceTrackerARExample.cs b/Assets/FaceTrackerExample/FaceTrackerARExample/FaceTrackerARExample.cs
index 2b0302e..b6fb9bb 100644
--- a/Assets/FaceTrackerExample/FaceTrackerARExample/FaceTrackerARExample.cs
+++ b/Assets/FaceTrackerExample/FaceTrackerARExample/FaceTrackerARExample.cs
@@ -19,7 +19,7 @@ namespace FaceTrackerExample
/// This example was referring to http://www.morethantechnical.com/2012/10/17/head-pose-estimation-with-opencv-opengl-revisited-w-code/
/// and use effect asset from http://ktk-kumamoto.hatenablog.com/entry/2014/09/14/092400
///
- [RequireComponent (typeof(WebCamTextureToMatHelper))]
+ [RequireComponent(typeof(WebCamTextureToMatHelper))]
public class FaceTrackerARExample : MonoBehaviour
{
///
@@ -31,7 +31,7 @@ namespace FaceTrackerExample
/// The is showing face points toggle.
///
public Toggle isShowingFacePointsToggle;
-
+
///
/// The should draw axes.
///
@@ -41,7 +41,7 @@ namespace FaceTrackerExample
/// The is showing axes toggle.
///
public Toggle isShowingAxesToggle;
-
+
///
/// The should draw head.
///
@@ -51,7 +51,7 @@ namespace FaceTrackerExample
/// The is showing head toggle.
///
public Toggle isShowingHeadToggle;
-
+
///
/// The should draw effects.
///
@@ -71,101 +71,101 @@ namespace FaceTrackerExample
/// The auto reset mode toggle.
///
public Toggle isAutoResetModeToggle;
-
+
///
/// The axes.
///
public GameObject axes;
-
+
///
/// The head.
///
public GameObject head;
-
+
///
/// The right eye.
///
public GameObject rightEye;
-
+
///
/// The left eye.
///
public GameObject leftEye;
-
+
///
/// The mouth.
///
public GameObject mouth;
-
+
///
/// The rvec noise filter range.
///
- [Range (0, 50)]
+ [Range(0, 50)]
public float
rvecNoiseFilterRange = 8;
-
+
///
/// The tvec noise filter range.
///
- [Range (0, 360)]
+ [Range(0, 360)]
public float
tvecNoiseFilterRange = 90;
-
+
///
/// The gray mat.
///
Mat grayMat;
-
+
///
/// The texture.
///
Texture2D texture;
-
+
///
/// The cascade.
///
CascadeClassifier cascade;
-
+
///
/// The face tracker.
///
FaceTracker faceTracker;
-
+
///
/// The face tracker parameters.
///
FaceTrackerParams faceTrackerParams;
-
+
///
/// The AR camera.
///
public Camera ARCamera;
-
+
///
/// The cam matrix.
///
Mat camMatrix;
-
+
///
/// The dist coeffs.
///
MatOfDouble distCoeffs;
-
+
///
/// The invert Y.
///
Matrix4x4 invertYM;
-
+
///
/// The transformation m.
///
- Matrix4x4 transformationM = new Matrix4x4 ();
-
+ Matrix4x4 transformationM = new Matrix4x4();
+
///
/// The invert Z.
///
Matrix4x4 invertZM;
-
+
///
/// The ar m.
///
@@ -180,37 +180,37 @@ namespace FaceTrackerExample
/// The should move AR camera.
///
public bool shouldMoveARCamera;
-
+
///
/// The 3d face object points.
///
MatOfPoint3f objectPoints;
-
+
///
/// The image points.
///
MatOfPoint2f imagePoints;
-
+
///
/// The rvec.
///
Mat rvec;
-
+
///
/// The tvec.
///
Mat tvec;
-
+
///
/// The rot m.
///
Mat rotM;
-
+
///
/// The old rvec.
///
Mat oldRvec;
-
+
///
/// The old tvec.
///
@@ -225,20 +225,20 @@ namespace FaceTrackerExample
/// The tracker_model_json_filepath.
///
private string tracker_model_json_filepath;
-
+
///
/// The haarcascade_frontalface_alt_xml_filepath.
///
private string haarcascade_frontalface_alt_xml_filepath;
- #if UNITY_WEBGL && !UNITY_EDITOR
+#if UNITY_WEBGL && !UNITY_EDITOR
IEnumerator getFilePath_Coroutine;
- #endif
+#endif
// Use this for initialization
- void Start ()
+ void Start()
{
- webCamTextureToMatHelper = gameObject.GetComponent ();
+ webCamTextureToMatHelper = gameObject.GetComponent();
isShowingFacePointsToggle.isOn = isShowingFacePoints;
@@ -247,382 +247,417 @@ namespace FaceTrackerExample
isShowingEffectsToggle.isOn = isShowingEffects;
isAutoResetModeToggle.isOn = isAutoResetMode;
- #if UNITY_WEBGL && !UNITY_EDITOR
- getFilePath_Coroutine = GetFilePath ();
- StartCoroutine (getFilePath_Coroutine);
- #else
- tracker_model_json_filepath = Utils.getFilePath ("tracker_model.json");
- haarcascade_frontalface_alt_xml_filepath = Utils.getFilePath ("haarcascade_frontalface_alt.xml");
- Run ();
- #endif
-
+#if UNITY_WEBGL && !UNITY_EDITOR
+ getFilePath_Coroutine = GetFilePath();
+ StartCoroutine(getFilePath_Coroutine);
+#else
+ tracker_model_json_filepath = Utils.getFilePath("tracker_model.json");
+ haarcascade_frontalface_alt_xml_filepath = Utils.getFilePath("haarcascade_frontalface_alt.xml");
+ Run();
+#endif
+
}
- #if UNITY_WEBGL && !UNITY_EDITOR
- private IEnumerator GetFilePath ()
+#if UNITY_WEBGL && !UNITY_EDITOR
+ private IEnumerator GetFilePath()
{
- var getFilePathAsync_0_Coroutine = Utils.getFilePathAsync ("tracker_model.json", (result) => {
+ var getFilePathAsync_0_Coroutine = Utils.getFilePathAsync("tracker_model.json", (result) =>
+ {
tracker_model_json_filepath = result;
});
yield return getFilePathAsync_0_Coroutine;
- var getFilePathAsync_1_Coroutine = Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
+ var getFilePathAsync_1_Coroutine = Utils.getFilePathAsync("haarcascade_frontalface_alt.xml", (result) =>
+ {
haarcascade_frontalface_alt_xml_filepath = result;
});
yield return getFilePathAsync_1_Coroutine;
getFilePath_Coroutine = null;
-
+
Run();
}
- #endif
+#endif
- private void Run ()
+ private void Run()
{
//set 3d face object points.
- objectPoints = new MatOfPoint3f (new Point3 (-31, 72, 86),//l eye
- new Point3 (31, 72, 86),//r eye
- new Point3 (0, 40, 114),//nose
- new Point3 (-20, 15, 90),//l mouse
- new Point3 (20, 15, 90)//r mouse
-// ,
-// new Point3 (-70, 60, -9),//l ear
-// new Point3 (70, 60, -9)//r ear
+ objectPoints = new MatOfPoint3f(new Point3(-31, 72, 86),//l eye
+ new Point3(31, 72, 86),//r eye
+ new Point3(0, 40, 114),//nose
+ new Point3(-20, 15, 90),//l mouse
+ new Point3(20, 15, 90),//r mouse
+ new Point3(-70, 60, -9),//l ear
+ new Point3(70, 60, -9)//r ear
);
- imagePoints = new MatOfPoint2f ();
- rvec = new Mat ();
- tvec = new Mat ();
- rotM = new Mat (3, 3, CvType.CV_64FC1);
+ imagePoints = new MatOfPoint2f();
+ rvec = new Mat();
+ tvec = new Mat();
+ rotM = new Mat(3, 3, CvType.CV_64FC1);
//initialize FaceTracker
- faceTracker = new FaceTracker (tracker_model_json_filepath);
+ faceTracker = new FaceTracker(tracker_model_json_filepath);
//initialize FaceTrackerParams
- faceTrackerParams = new FaceTrackerParams ();
+ faceTrackerParams = new FaceTrackerParams();
- cascade = new CascadeClassifier ();
- cascade.load (haarcascade_frontalface_alt_xml_filepath);
-// if (cascade.empty())
-// {
-// Debug.LogError("cascade file is not loaded.Please copy from “FaceTrackerExample/StreamingAssets/” to “Assets/StreamingAssets/” folder. ");
-// }
+ cascade = new CascadeClassifier();
+ cascade.load(haarcascade_frontalface_alt_xml_filepath);
+ //if (cascade.empty())
+ //{
+ // Debug.LogError("cascade file is not loaded.Please copy from “FaceTrackerExample/StreamingAssets/” to “Assets/StreamingAssets/” folder. ");
+ //}
- #if UNITY_ANDROID && !UNITY_EDITOR
+#if UNITY_ANDROID && !UNITY_EDITOR
// Avoids the front camera low light issue that occurs in only some Android devices (e.g. Google Pixel, Pixel2).
webCamTextureToMatHelper.avoidAndroidFrontCameraLowLightIssue = true;
- #endif
- webCamTextureToMatHelper.Initialize ();
+#endif
+ webCamTextureToMatHelper.Initialize();
}
///
/// Raises the webcam texture to mat helper initialized event.
///
- public void OnWebCamTextureToMatHelperInitialized ()
+ public void OnWebCamTextureToMatHelperInitialized()
{
- Debug.Log ("OnWebCamTextureToMatHelperInitialized");
-
- Mat webCamTextureMat = webCamTextureToMatHelper.GetMat ();
+ Debug.Log("OnWebCamTextureToMatHelperInitialized");
- texture = new Texture2D (webCamTextureMat.cols (), webCamTextureMat.rows (), TextureFormat.RGBA32, false);
+ Mat webCamTextureMat = webCamTextureToMatHelper.GetMat();
- gameObject.GetComponent ().material.mainTexture = texture;
+ texture = new Texture2D(webCamTextureMat.cols(), webCamTextureMat.rows(), TextureFormat.RGBA32, false);
- gameObject.transform.localScale = new Vector3 (webCamTextureMat.cols (), webCamTextureMat.rows (), 1);
- Debug.Log ("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation);
+ gameObject.GetComponent().material.mainTexture = texture;
+
+ gameObject.transform.localScale = new Vector3(webCamTextureMat.cols(), webCamTextureMat.rows(), 1);
+ Debug.Log("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation);
- float width = webCamTextureMat.width ();
- float height = webCamTextureMat.height ();
-
+ float width = webCamTextureMat.width();
+ float height = webCamTextureMat.height();
+
float imageSizeScale = 1.0f;
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;
imageSizeScale = (float)Screen.height / (float)Screen.width;
- } else {
+ }
+ else
+ {
Camera.main.orthographicSize = height / 2;
}
-
-
+
+
//set cameraparam
- int max_d = (int)Mathf.Max (width, height);
+ int max_d = (int)Mathf.Max(width, height);
double fx = max_d;
double fy = max_d;
double cx = width / 2.0f;
double cy = height / 2.0f;
- camMatrix = new Mat (3, 3, CvType.CV_64FC1);
- camMatrix.put (0, 0, fx);
- camMatrix.put (0, 1, 0);
- camMatrix.put (0, 2, cx);
- camMatrix.put (1, 0, 0);
- camMatrix.put (1, 1, fy);
- camMatrix.put (1, 2, cy);
- camMatrix.put (2, 0, 0);
- camMatrix.put (2, 1, 0);
- camMatrix.put (2, 2, 1.0f);
- Debug.Log ("camMatrix " + camMatrix.dump ());
+ camMatrix = new Mat(3, 3, CvType.CV_64FC1);
+ camMatrix.put(0, 0, fx);
+ camMatrix.put(0, 1, 0);
+ camMatrix.put(0, 2, cx);
+ camMatrix.put(1, 0, 0);
+ camMatrix.put(1, 1, fy);
+ camMatrix.put(1, 2, cy);
+ camMatrix.put(2, 0, 0);
+ camMatrix.put(2, 1, 0);
+ camMatrix.put(2, 2, 1.0f);
+ Debug.Log("camMatrix " + camMatrix.dump());
+
+ distCoeffs = new MatOfDouble(0, 0, 0, 0);
+ Debug.Log("distCoeffs " + distCoeffs.dump());
- distCoeffs = new MatOfDouble (0, 0, 0, 0);
- Debug.Log ("distCoeffs " + distCoeffs.dump ());
-
//calibration camera
- Size imageSize = new Size (width * imageSizeScale, height * imageSizeScale);
+ Size imageSize = new Size(width * imageSizeScale, height * imageSizeScale);
double apertureWidth = 0;
double apertureHeight = 0;
double[] fovx = new double[1];
double[] fovy = new double[1];
double[] focalLength = new double[1];
- Point principalPoint = new Point (0, 0);
+ Point principalPoint = new Point(0, 0);
double[] aspectratio = new double[1];
-
- Calib3d.calibrationMatrixValues (camMatrix, imageSize, apertureWidth, apertureHeight, fovx, fovy, focalLength, principalPoint, aspectratio);
-
- Debug.Log ("imageSize " + imageSize.ToString ());
- Debug.Log ("apertureWidth " + apertureWidth);
- Debug.Log ("apertureHeight " + apertureHeight);
- Debug.Log ("fovx " + fovx [0]);
- Debug.Log ("fovy " + fovy [0]);
- Debug.Log ("focalLength " + focalLength [0]);
- Debug.Log ("principalPoint " + principalPoint.ToString ());
- Debug.Log ("aspectratio " + aspectratio [0]);
-
-
+
+ Calib3d.calibrationMatrixValues(camMatrix, imageSize, apertureWidth, apertureHeight, fovx, fovy, focalLength, principalPoint, aspectratio);
+
+ Debug.Log("imageSize " + imageSize.ToString());
+ Debug.Log("apertureWidth " + apertureWidth);
+ Debug.Log("apertureHeight " + apertureHeight);
+ Debug.Log("fovx " + fovx[0]);
+ Debug.Log("fovy " + fovy[0]);
+ Debug.Log("focalLength " + focalLength[0]);
+ Debug.Log("principalPoint " + principalPoint.ToString());
+ Debug.Log("aspectratio " + aspectratio[0]);
+
+
//To convert the difference of the FOV value of the OpenCV and Unity.
- double fovXScale = (2.0 * Mathf.Atan ((float)(imageSize.width / (2.0 * fx)))) / (Mathf.Atan2 ((float)cx, (float)fx) + Mathf.Atan2 ((float)(imageSize.width - cx), (float)fx));
- double fovYScale = (2.0 * Mathf.Atan ((float)(imageSize.height / (2.0 * fy)))) / (Mathf.Atan2 ((float)cy, (float)fy) + Mathf.Atan2 ((float)(imageSize.height - cy), (float)fy));
-
- Debug.Log ("fovXScale " + fovXScale);
- Debug.Log ("fovYScale " + fovYScale);
-
-
+ double fovXScale = (2.0 * Mathf.Atan((float)(imageSize.width / (2.0 * fx)))) / (Mathf.Atan2((float)cx, (float)fx) + Mathf.Atan2((float)(imageSize.width - cx), (float)fx));
+ double fovYScale = (2.0 * Mathf.Atan((float)(imageSize.height / (2.0 * fy)))) / (Mathf.Atan2((float)cy, (float)fy) + Mathf.Atan2((float)(imageSize.height - cy), (float)fy));
+
+ Debug.Log("fovXScale " + fovXScale);
+ Debug.Log("fovYScale " + fovYScale);
+
+
//Adjust Unity Camera FOV https://github.com/opencv/opencv/commit/8ed1945ccd52501f5ab22bdec6aa1f91f1e2cfd4
- if (widthScale < heightScale) {
- ARCamera.fieldOfView = (float)(fovx [0] * fovXScale);
- } else {
- ARCamera.fieldOfView = (float)(fovy [0] * fovYScale);
+ if (widthScale < heightScale)
+ {
+ ARCamera.fieldOfView = (float)(fovx[0] * fovXScale);
}
-
-
- invertYM = Matrix4x4.TRS (Vector3.zero, Quaternion.identity, new Vector3 (1, -1, 1));
- Debug.Log ("invertYM " + invertYM.ToString ());
-
- invertZM = Matrix4x4.TRS (Vector3.zero, Quaternion.identity, new Vector3 (1, 1, -1));
- Debug.Log ("invertZM " + invertZM.ToString ());
+ else
+ {
+ ARCamera.fieldOfView = (float)(fovy[0] * fovYScale);
+ }
+
+
+ invertYM = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1, -1, 1));
+ Debug.Log("invertYM " + invertYM.ToString());
+
+ invertZM = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1, 1, -1));
+ Debug.Log("invertZM " + invertZM.ToString());
- grayMat = new Mat (webCamTextureMat.rows (), webCamTextureMat.cols (), CvType.CV_8UC1);
-
- axes.SetActive (false);
- head.SetActive (false);
- rightEye.SetActive (false);
- leftEye.SetActive (false);
- mouth.SetActive (false);
+ grayMat = new Mat(webCamTextureMat.rows(), webCamTextureMat.cols(), CvType.CV_8UC1);
+
+ axes.SetActive(false);
+ head.SetActive(false);
+ rightEye.SetActive(false);
+ leftEye.SetActive(false);
+ mouth.SetActive(false);
}
///
/// Raises the webcam texture to mat helper disposed event.
///
- public void OnWebCamTextureToMatHelperDisposed ()
+ public void OnWebCamTextureToMatHelperDisposed()
{
- Debug.Log ("OnWebCamTextureToMatHelperDisposed");
-
- faceTracker.reset ();
+ Debug.Log("OnWebCamTextureToMatHelperDisposed");
- grayMat.Dispose ();
- camMatrix.Dispose ();
- distCoeffs.Dispose ();
+ faceTracker.reset();
+
+ grayMat.Dispose();
+ camMatrix.Dispose();
+ distCoeffs.Dispose();
}
///
/// Raises the webcam texture to mat helper error occurred event.
///
/// Error code.
- public void OnWebCamTextureToMatHelperErrorOccurred (WebCamTextureToMatHelper.ErrorCode errorCode)
+ public void OnWebCamTextureToMatHelperErrorOccurred(WebCamTextureToMatHelper.ErrorCode errorCode)
{
- Debug.Log ("OnWebCamTextureToMatHelperErrorOccurred " + errorCode);
+ Debug.Log("OnWebCamTextureToMatHelperErrorOccurred " + errorCode);
}
// Update is called once per frame
- void Update ()
+ void Update()
{
- if (webCamTextureToMatHelper.IsPlaying () && webCamTextureToMatHelper.DidUpdateThisFrame ()) {
-
- Mat rgbaMat = webCamTextureToMatHelper.GetMat ();
+ if (webCamTextureToMatHelper.IsPlaying() && webCamTextureToMatHelper.DidUpdateThisFrame())
+ {
+
+ Mat rgbaMat = webCamTextureToMatHelper.GetMat();
//convert image to greyscale
- Imgproc.cvtColor (rgbaMat, grayMat, Imgproc.COLOR_RGBA2GRAY);
-
-
- if (isAutoResetMode || faceTracker.getPoints ().Count <= 0) {
-// Debug.Log ("detectFace");
-
- //convert image to greyscale
- using (Mat equalizeHistMat = new Mat ()) using (MatOfRect faces = new MatOfRect ()) {
-
- Imgproc.equalizeHist (grayMat, equalizeHistMat);
-
- cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0
- | Objdetect.CASCADE_FIND_BIGGEST_OBJECT
- | Objdetect.CASCADE_SCALE_IMAGE, new Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
-
-
-
- if (faces.rows () > 0) {
-// Debug.Log ("faces " + faces.dump ());
+ Imgproc.cvtColor(rgbaMat, grayMat, Imgproc.COLOR_RGBA2GRAY);
- List rectsList = faces.toList ();
- List pointsList = faceTracker.getPoints ();
-
- if (isAutoResetMode) {
+
+ if (isAutoResetMode || faceTracker.getPoints().Count <= 0)
+ {
+ // Debug.Log ("detectFace");
+
+ //convert image to greyscale
+ using (Mat equalizeHistMat = new Mat()) using (MatOfRect faces = new MatOfRect())
+ {
+
+ Imgproc.equalizeHist(grayMat, equalizeHistMat);
+
+ cascade.detectMultiScale(equalizeHistMat, faces, 1.1f, 2, 0
+ | Objdetect.CASCADE_FIND_BIGGEST_OBJECT
+ | Objdetect.CASCADE_SCALE_IMAGE, new Size(equalizeHistMat.cols() * 0.15, equalizeHistMat.cols() * 0.15), new Size());
+
+
+
+ if (faces.rows() > 0)
+ {
+ // Debug.Log ("faces " + faces.dump ());
+
+ List rectsList = faces.toList();
+ List pointsList = faceTracker.getPoints();
+
+ if (isAutoResetMode)
+ {
//add initial face points from MatOfRect
- if (pointsList.Count <= 0) {
- faceTracker.addPoints (faces);
-// Debug.Log ("reset faces ");
- } else {
-
- for (int i = 0; i < rectsList.Count; i++) {
-
- OpenCVForUnity.CoreModule.Rect trackRect = new OpenCVForUnity.CoreModule.Rect (rectsList [i].x + rectsList [i].width / 3, rectsList [i].y + rectsList [i].height / 2, rectsList [i].width / 3, rectsList [i].height / 3);
+ if (pointsList.Count <= 0)
+ {
+ faceTracker.addPoints(faces);
+ // Debug.Log ("reset faces ");
+ }
+ else
+ {
+
+ for (int i = 0; i < rectsList.Count; i++)
+ {
+
+ OpenCVForUnity.CoreModule.Rect trackRect = new OpenCVForUnity.CoreModule.Rect(rectsList[i].x + rectsList[i].width / 3, rectsList[i].y + rectsList[i].height / 2, rectsList[i].width / 3, rectsList[i].height / 3);
//It determines whether nose point has been included in trackRect.
- if (i < pointsList.Count && !trackRect.contains (pointsList [i] [67])) {
- rectsList.RemoveAt (i);
- pointsList.RemoveAt (i);
-// Debug.Log ("remove " + i);
+ if (i < pointsList.Count && !trackRect.contains(pointsList[i][67]))
+ {
+ rectsList.RemoveAt(i);
+ pointsList.RemoveAt(i);
+ // Debug.Log ("remove " + i);
}
- Imgproc.rectangle (rgbaMat, new Point (trackRect.x, trackRect.y), new Point (trackRect.x + trackRect.width, trackRect.y + trackRect.height), new Scalar (0, 0, 255, 255), 2);
+ Imgproc.rectangle(rgbaMat, new Point(trackRect.x, trackRect.y), new Point(trackRect.x + trackRect.width, trackRect.y + trackRect.height), new Scalar(0, 0, 255, 255), 2);
}
}
- } else {
- faceTracker.addPoints (faces);
+ }
+ else
+ {
+ faceTracker.addPoints(faces);
}
//draw face rect
- for (int i = 0; i < rectsList.Count; i++) {
- Imgproc.rectangle (rgbaMat, new Point (rectsList [i].x, rectsList [i].y), new Point (rectsList [i].x + rectsList [i].width, rectsList [i].y + rectsList [i].height), new Scalar (255, 0, 0, 255), 2);
+ for (int i = 0; i < rectsList.Count; i++)
+ {
+ Imgproc.rectangle(rgbaMat, new Point(rectsList[i].x, rectsList[i].y), new Point(rectsList[i].x + rectsList[i].width, rectsList[i].y + rectsList[i].height), new Scalar(255, 0, 0, 255), 2);
}
- } else {
- if (isAutoResetMode) {
- faceTracker.reset ();
-
- rightEye.SetActive (false);
- leftEye.SetActive (false);
- head.SetActive (false);
- mouth.SetActive (false);
- axes.SetActive (false);
- }
- }
- }
- }
-
-
- //track face points.if face points <= 0, always return false.
- if (faceTracker.track (grayMat, faceTrackerParams)) {
- if (isShowingFacePoints) faceTracker.draw (rgbaMat, new Scalar (255, 0, 0, 255), new Scalar (0, 255, 0, 255));
-
- Imgproc.putText (rgbaMat, "'Tap' or 'Space Key' to Reset", new Point (5, rgbaMat.rows () - 5), Imgproc.FONT_HERSHEY_SIMPLEX, 0.8, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
-
-
- Point[] points = faceTracker.getPoints () [0];
-
-
- if (points.Length > 0) {
-
-// for (int i = 0; i < points.Length; i++)
-// {
-// Imgproc.putText(rgbaMat, "" + i, new Point(points [i].x, points [i].y), Imgproc.FONT_HERSHEY_SIMPLEX, 0.3, new Scalar(0, 0, 255, 255), 2, Imgproc.LINE_AA, false);
-// }
-
-
- imagePoints.fromArray (
- points [31],//l eye
- points [36],//r eye
- points [67],//nose
- points [48],//l mouth
- points [54] //r mouth
-// ,
-// points [0],//l ear
-// points [14]//r ear
- );
-
-
- Calib3d.solvePnP (objectPoints, imagePoints, camMatrix, distCoeffs, rvec, tvec);
-
- bool isRefresh = false;
-
- if (tvec.get (2, 0) [0] > 0 && tvec.get (2, 0) [0] < 1200 * ((float)rgbaMat.cols () / (float)webCamTextureToMatHelper.requestedWidth)) {
-
- isRefresh = true;
-
- if (oldRvec == null) {
- oldRvec = new Mat ();
- rvec.copyTo (oldRvec);
- }
- if (oldTvec == null) {
- oldTvec = new Mat ();
- tvec.copyTo (oldTvec);
- }
-
-
- //filter Rvec Noise.
- using (Mat absDiffRvec = new Mat ()) {
- Core.absdiff (rvec, oldRvec, absDiffRvec);
-
- // Debug.Log ("absDiffRvec " + absDiffRvec.dump());
-
- using (Mat cmpRvec = new Mat ()) {
- Core.compare (absDiffRvec, new Scalar (rvecNoiseFilterRange), cmpRvec, Core.CMP_GT);
-
- if (Core.countNonZero (cmpRvec) > 0) isRefresh = false;
- }
- }
-
- //filter Tvec Noise.
- using (Mat absDiffTvec = new Mat ()) {
- Core.absdiff (tvec, oldTvec, absDiffTvec);
-
- // Debug.Log ("absDiffRvec " + absDiffRvec.dump());
-
- using (Mat cmpTvec = new Mat ()) {
- Core.compare (absDiffTvec, new Scalar (tvecNoiseFilterRange), cmpTvec, Core.CMP_GT);
-
- if (Core.countNonZero (cmpTvec) > 0) isRefresh = false;
- }
- }
}
-
- if (isRefresh) {
-
- if (isShowingEffects) rightEye.SetActive (true);
- if (isShowingEffects) leftEye.SetActive (true);
- if (isShowingHead) head.SetActive (true);
- if (isShowingAxes) axes.SetActive (true);
-
-
- if ((Mathf.Abs ((float)(points [48].x - points [56].x)) < Mathf.Abs ((float)(points [31].x - points [36].x)) / 2.2
- && Mathf.Abs ((float)(points [51].y - points [57].y)) > Mathf.Abs ((float)(points [31].x - points [36].x)) / 2.9)
- || Mathf.Abs ((float)(points [51].y - points [57].y)) > Mathf.Abs ((float)(points [31].x - points [36].x)) / 2.7) {
-
- if (isShowingEffects) mouth.SetActive (true);
-
- } else {
- if (isShowingEffects) mouth.SetActive (false);
- }
-
- rvec.copyTo (oldRvec);
- tvec.copyTo (oldTvec);
-
- Calib3d.Rodrigues (rvec, rotM);
-
- 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));
+ else
+ {
+ if (isAutoResetMode)
+ {
+ faceTracker.reset();
+
+ rightEye.SetActive(false);
+ leftEye.SetActive(false);
+ head.SetActive(false);
+ mouth.SetActive(false);
+ axes.SetActive(false);
+ }
+ }
+ }
+ }
+
+
+ //track face points.if face points <= 0, always return false.
+ if (faceTracker.track(grayMat, faceTrackerParams))
+ {
+ if (isShowingFacePoints) faceTracker.draw(rgbaMat, new Scalar(255, 0, 0, 255), new Scalar(0, 255, 0, 255));
+
+ Imgproc.putText(rgbaMat, "'Tap' or 'Space Key' to Reset", new Point(5, rgbaMat.rows() - 5), Imgproc.FONT_HERSHEY_SIMPLEX, 0.8, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
+
+
+ Point[] points = faceTracker.getPoints()[0];
+
+
+ if (points.Length > 0)
+ {
+
+ //for (int i = 0; i < points.Length; i++)
+ //{
+ // Imgproc.putText(rgbaMat, "" + i, new Point(points [i].x, points [i].y), Imgproc.FONT_HERSHEY_SIMPLEX, 0.3, new Scalar(0, 0, 255, 255), 2, Imgproc.LINE_AA, false);
+ //}
+
+
+ imagePoints.fromArray(
+ points[31],//l eye
+ points[36],//r eye
+ points[67],//nose
+ points[48],//l mouth
+ points[54], //r mouth
+ points[0],//l ear
+ points[14]//r ear
+ );
+
+
+ Calib3d.solvePnP(objectPoints, imagePoints, camMatrix, distCoeffs, rvec, tvec);
+
+ bool isRefresh = false;
+
+ if (tvec.dims() != 0 && tvec.get(2, 0)[0] > 0 && tvec.get(2, 0)[0] < 1200 * ((float)rgbaMat.cols() / (float)webCamTextureToMatHelper.requestedWidth))
+ {
+
+ isRefresh = true;
+
+ if (oldRvec == null)
+ {
+ oldRvec = new Mat();
+ rvec.copyTo(oldRvec);
+ }
+ if (oldTvec == null)
+ {
+ oldTvec = new Mat();
+ tvec.copyTo(oldTvec);
+ }
+
+
+ //filter Rvec Noise.
+ using (Mat absDiffRvec = new Mat())
+ {
+ Core.absdiff(rvec, oldRvec, absDiffRvec);
+
+ //Debug.Log ("absDiffRvec " + absDiffRvec.dump());
+
+ using (Mat cmpRvec = new Mat())
+ {
+ Core.compare(absDiffRvec, new Scalar(rvecNoiseFilterRange), cmpRvec, Core.CMP_GT);
+
+ if (Core.countNonZero(cmpRvec) > 0) isRefresh = false;
+ }
+ }
+
+ //filter Tvec Noise.
+ using (Mat absDiffTvec = new Mat())
+ {
+ Core.absdiff(tvec, oldTvec, absDiffTvec);
+
+ //Debug.Log ("absDiffRvec " + absDiffRvec.dump());
+
+ using (Mat cmpTvec = new Mat())
+ {
+ Core.compare(absDiffTvec, new Scalar(tvecNoiseFilterRange), cmpTvec, Core.CMP_GT);
+
+ if (Core.countNonZero(cmpTvec) > 0) isRefresh = false;
+ }
+ }
+ }
+
+ if (isRefresh)
+ {
+
+ if (isShowingEffects) rightEye.SetActive(true);
+ if (isShowingEffects) leftEye.SetActive(true);
+ if (isShowingHead) head.SetActive(true);
+ if (isShowingAxes) axes.SetActive(true);
+
+
+ if ((Mathf.Abs((float)(points[48].x - points[56].x)) < Mathf.Abs((float)(points[31].x - points[36].x)) / 2.2
+ && Mathf.Abs((float)(points[51].y - points[57].y)) > Mathf.Abs((float)(points[31].x - points[36].x)) / 2.9)
+ || Mathf.Abs((float)(points[51].y - points[57].y)) > Mathf.Abs((float)(points[31].x - points[36].x)) / 2.7)
+ {
+
+ if (isShowingEffects) mouth.SetActive(true);
+
+ }
+ else
+ {
+ if (isShowingEffects) mouth.SetActive(false);
+ }
+
+ rvec.copyTo(oldRvec);
+ tvec.copyTo(oldTvec);
+
+ Calib3d.Rodrigues(rvec, rotM);
+
+ 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));
// right-handed coordinates system (OpenCV) to left-handed one (Unity)
ARM = invertYM * transformationM;
@@ -630,114 +665,126 @@ namespace FaceTrackerExample
// Apply Z-axis inverted matrix.
ARM = ARM * invertZM;
- if (shouldMoveARCamera) {
+ if (shouldMoveARCamera)
+ {
- if (ARGameObject != null) {
+ if (ARGameObject != null)
+ {
ARM = ARGameObject.transform.localToWorldMatrix * ARM.inverse;
- ARUtils.SetTransformFromMatrix (ARCamera.transform, ref ARM);
- ARGameObject.SetActive (true);
+ ARUtils.SetTransformFromMatrix(ARCamera.transform, ref ARM);
+ ARGameObject.SetActive(true);
}
- } else {
+ }
+ else
+ {
ARM = ARCamera.transform.localToWorldMatrix * ARM;
- if (ARGameObject != null) {
- ARUtils.SetTransformFromMatrix (ARGameObject.transform, ref ARM);
- ARGameObject.SetActive (true);
+ if (ARGameObject != null)
+ {
+ ARUtils.SetTransformFromMatrix(ARGameObject.transform, ref ARM);
+ ARGameObject.SetActive(true);
}
}
}
}
}
-
-// Imgproc.putText (rgbaMat, "W:" + rgbaMat.width () + " H:" + rgbaMat.height () + " SO:" + Screen.orientation, new Point (5, rgbaMat.rows () - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
-
- Utils.fastMatToTexture2D (rgbaMat, texture);
+
+ //Imgproc.putText (rgbaMat, "W:" + rgbaMat.width () + " H:" + rgbaMat.height () + " SO:" + Screen.orientation, new Point (5, rgbaMat.rows () - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
+
+ Utils.fastMatToTexture2D(rgbaMat, texture);
}
-
- if (Input.GetKeyUp (KeyCode.Space) || Input.touchCount > 0) {
- faceTracker.reset ();
- if (oldRvec != null) {
- oldRvec.Dispose ();
+
+ if (Input.GetKeyUp(KeyCode.Space) || Input.touchCount > 0)
+ {
+ faceTracker.reset();
+ if (oldRvec != null)
+ {
+ oldRvec.Dispose();
oldRvec = null;
}
- if (oldTvec != null) {
- oldTvec.Dispose ();
+ if (oldTvec != null)
+ {
+ oldTvec.Dispose();
oldTvec = null;
}
-
- rightEye.SetActive (false);
- leftEye.SetActive (false);
- head.SetActive (false);
- mouth.SetActive (false);
- axes.SetActive (false);
- }
+
+ rightEye.SetActive(false);
+ leftEye.SetActive(false);
+ head.SetActive(false);
+ mouth.SetActive(false);
+ axes.SetActive(false);
+ }
}
///
/// Raises the disable event.
///
- void OnDisable ()
+ void OnDisable()
{
- webCamTextureToMatHelper.Dispose ();
+ webCamTextureToMatHelper.Dispose();
- if (cascade != null) cascade.Dispose ();
+ if (cascade != null) cascade.Dispose();
- #if UNITY_WEBGL && !UNITY_EDITOR
- if (getFilePath_Coroutine != null) {
- StopCoroutine (getFilePath_Coroutine);
- ((IDisposable)getFilePath_Coroutine).Dispose ();
+#if UNITY_WEBGL && !UNITY_EDITOR
+ if (getFilePath_Coroutine != null)
+ {
+ StopCoroutine(getFilePath_Coroutine);
+ ((IDisposable)getFilePath_Coroutine).Dispose();
}
- #endif
+#endif
}
///
/// Raises the back button event.
///
- public void OnBackButton ()
+ public void OnBackButton()
{
- SceneManager.LoadScene ("FaceTrackerExample");
+ SceneManager.LoadScene("FaceTrackerExample");
}
///
/// Raises the play button event.
///
- public void OnPlayButton ()
+ public void OnPlayButton()
{
- webCamTextureToMatHelper.Play ();
+ webCamTextureToMatHelper.Play();
}
///
/// Raises the pause button event.
///
- public void OnPauseButton ()
+ public void OnPauseButton()
{
- webCamTextureToMatHelper.Pause ();
+ webCamTextureToMatHelper.Pause();
}
///
/// Raises the stop button event.
///
- public void OnStopButton ()
+ public void OnStopButton()
{
- webCamTextureToMatHelper.Stop ();
+ webCamTextureToMatHelper.Stop();
}
///
/// Raises the change camera button event.
///
- public void OnChangeCameraButton ()
+ public void OnChangeCameraButton()
{
- webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.IsFrontFacing ();
+ webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.IsFrontFacing();
}
///
/// Raises the is showing face points toggle event.
///
- public void OnIsShowingFacePointsToggle ()
+ public void OnIsShowingFacePointsToggle()
{
- if (isShowingFacePointsToggle.isOn) {
+ if (isShowingFacePointsToggle.isOn)
+ {
isShowingFacePoints = true;
- } else {
+ }
+ else
+ {
isShowingFacePoints = false;
}
}
@@ -745,52 +792,64 @@ namespace FaceTrackerExample
///
/// Raises the is showing axes toggle event.
///
- public void OnIsShowingAxesToggle ()
+ public void OnIsShowingAxesToggle()
{
- if (isShowingAxesToggle.isOn) {
+ if (isShowingAxesToggle.isOn)
+ {
isShowingAxes = true;
- } else {
+ }
+ else
+ {
isShowingAxes = false;
- axes.SetActive (false);
+ axes.SetActive(false);
}
}
///
/// Raises the is showing head toggle event.
///
- public void OnIsShowingHeadToggle ()
+ public void OnIsShowingHeadToggle()
{
- if (isShowingHeadToggle.isOn) {
+ if (isShowingHeadToggle.isOn)
+ {
isShowingHead = true;
- } else {
+ }
+ else
+ {
isShowingHead = false;
- head.SetActive (false);
+ head.SetActive(false);
}
}
///
/// Raises the is showin effects toggle event.
///
- public void OnIsShowingEffectsToggle ()
+ public void OnIsShowingEffectsToggle()
{
- if (isShowingEffectsToggle.isOn) {
+ if (isShowingEffectsToggle.isOn)
+ {
isShowingEffects = true;
- } else {
+ }
+ else
+ {
isShowingEffects = false;
- rightEye.SetActive (false);
- leftEye.SetActive (false);
- mouth.SetActive (false);
+ rightEye.SetActive(false);
+ leftEye.SetActive(false);
+ mouth.SetActive(false);
}
}
///
/// Raises the change auto reset mode toggle event.
///
- public void OnIsAutoResetModeToggle ()
+ public void OnIsAutoResetModeToggle()
{
- if (isAutoResetModeToggle.isOn) {
+ if (isAutoResetModeToggle.isOn)
+ {
isAutoResetMode = true;
- } else {
+ }
+ else
+ {
isAutoResetMode = false;
}
}
diff --git a/Assets/FaceTrackerExample/ReadMe.pdf b/Assets/FaceTrackerExample/ReadMe.pdf
index ecfd6db..80bc085 100644
Binary files a/Assets/FaceTrackerExample/ReadMe.pdf and b/Assets/FaceTrackerExample/ReadMe.pdf differ