3 using System.Collections.Generic;
59 LineRenderer eyesHelpLines;
60 LineRenderer mouthHelpLines;
61 LineRenderer leftEyeHelpLines;
62 LineRenderer rightEyeHelpLines;
63 LineRenderer eyeBrowsHelpLines;
70 private float[] thresholds ;
88 buttonText =
"Capture Face Contour";
90 sQuad = GameObject.Find (
"ScreenQuad");
91 quadScript = sQuad.GetComponent<
screenQuad> ();
93 Camera mainCam = GameObject.Find (
"Main Camera").GetComponent<Camera> ();
95 binaryCam = gameObject.GetComponent<Camera>();
96 binaryCam.enabled =
false;
99 screenHeight = (float)Screen.
height;
100 screenWidth = (
float)Screen.width;
103 texWidth = sQuad.GetComponent<Renderer> ().material.mainTexture.width;
104 texHeight = sQuad.GetComponent<Renderer> ().material.mainTexture.height;
109 eyesArea =
new Rect ( 0.25f, 0.5f, 0.5f, 0.055f);
110 eyeBrowsArea =
new Rect ( 0.2f, 0.56f, 0.6f, 0.08f);
111 mouthArea =
new Rect ( 0.35f, 0.312f, 0.3f, 0.08f);
112 leftEyeArea =
new Rect ( 0.275f, 0.51f, 0.15f, 0.04f);
113 rightEyeArea =
new Rect ( 0.575f, 0.51f, 0.15f, 0.04f);
117 eyeBrowsAreaTex =
new Rect (eyeBrowsArea.xMin * texWidth, eyeBrowsArea.yMin * texHeight, eyeBrowsArea.width * texWidth, eyeBrowsArea.height * texHeight);
118 eyesAreaTex =
new Rect (eyesArea.xMin * texWidth, eyesArea.yMin * texHeight, eyesArea.width * texWidth, eyesArea.height * texHeight);
119 mouthAreaTex =
new Rect ( mouthArea.xMin * texWidth, mouthArea.yMin * texHeight, mouthArea.width * texWidth, mouthArea.height * texHeight);
122 controller = GameObject.Find (
"SnakeScript").GetComponent<
Controller> ();
133 Camera.main.transform.position =
new Vector3 (0.5f, 0.5f, -2f);
136 binaryImageHead =
new Texture2D (texWidth, texHeight);
137 binaryImageFace =
new Texture2D (texWidth, texHeight);
138 binaryImageEyebrows =
new Texture2D (texWidth, texHeight);
139 binaryImageFaceSide =
new Texture2D (texWidth, texHeight);
141 for (
int x =0; x<texWidth; x++)
142 for (
int y=0; y<texHeight; y++) {
143 binaryImageFace.SetPixel (x, y, Color.white);
144 binaryImageEyebrows.SetPixel (x, y, Color.white);
152 GameObject.Find (
"ResizeQuad").transform.localScale =
new Vector3 (1.8f, 1.0f, 1f);
153 GameObject.Find (
"ResizeQuad").transform.localPosition =
new Vector3 (0.5f, 0.5f, 0f);
165 eyesHelpLines = GameObject.Find (
"EyesHelpLines").GetComponent<LineRenderer>();
168 leftEyeHelpLines = GameObject.Find (
"LeftEyeHelpLines").GetComponent<LineRenderer>();
171 rightEyeHelpLines = GameObject.Find (
"RightEyeHelpLines").GetComponent<LineRenderer>();
174 mouthHelpLines = GameObject.Find (
"MouthHelpLines").GetComponent<LineRenderer>();
177 eyeBrowsHelpLines = GameObject.Find (
"EyeBrowsHelpLines").GetComponent<LineRenderer>();
191 g.SetPosition(0,
new Vector3(area.xMin * 0.6f + 0.2f, (area.yMin), -1.0f));
192 g.SetPosition(1,
new Vector3(area.xMin * 0.6f + 0.2f, (area.yMax), -1.0f));
193 g.SetPosition(2,
new Vector3(area.xMax * 0.6f + 0.2f, (area.yMax), -1.0f));
194 g.SetPosition(3,
new Vector3(area.xMax * 0.6f + 0.2f, (area.yMin), -1.0f));
195 g.SetPosition(4,
new Vector3(area.xMin * 0.6f + 0.2f, (area.yMin), -1.0f));
198 g.SetPosition(5,
new Vector3(area.xMax * 0.6f + 0.2f, (area.yMin), -1.0f));
199 g.SetPosition(6,
new Vector3(area.xMax * 0.6f + 0.2f, (area.yMax), -1.0f));
200 g.SetPosition(7,
new Vector3(area.xMin * 0.6f + 0.2f, (area.yMax), -1.0f));
201 g.SetPosition(8,
new Vector3(area.xMin * 0.6f + 0.2f, (area.yMin), -1.0f));
212 bool nextStep =
false;
216 if (renderStep > 6 && !snake)
225 nextRenderStep =
true;
237 buttonText =
"Capture Sideview Contour";
243 buttonText =
"Capture Mouth Contour";
248 buttonText =
"Capture Eyebrows Contour";
251 if (renderStep == 0) {
255 buttonText =
"Capture Eyes Contour";
272 void setHelpLinesEnabled(
bool e){
274 eyesHelpLines.enabled = e;
275 mouthHelpLines.enabled = e;
276 leftEyeHelpLines.enabled = e;
277 rightEyeHelpLines.enabled = e;
278 eyeBrowsHelpLines.enabled = e;
293 int thresholdPrev = sQuad.GetComponent<Renderer> ().material.GetInt (
"_ThresholdMode");
294 int binaryPrev = sQuad.GetComponent<Renderer> ().material.GetInt (
"_BinaryMode");
296 sQuad.GetComponent<Renderer>().material.SetFloat (
"_ThresholdMode", thresholdEnabled);
297 sQuad.GetComponent<Renderer>().material.SetFloat (
"_BinaryMode", binaryEnabled);
299 setHelpLinesEnabled (
false);
302 binaryCam.enabled =
true;
304 binaryCam.enabled =
false;
307 setHelpLinesEnabled (
true);
309 sQuad.GetComponent<Renderer>().material.SetFloat (
"_ThresholdMode", thresholdPrev);
310 sQuad.GetComponent<Renderer>().material.SetFloat (
"_BinaryMode", binaryPrev);
320 private void renderCam(
string camName){
322 Camera cam = GameObject.Find (camName).GetComponent<Camera> ();
335 private void renderAllCams(){
337 renderCam(
"gaussXCam");
338 renderCam(
"gaussYCam");
339 renderCam(
"CornerCamera");
340 renderCam(
"dFdxCam");
341 renderCam(
"dFdyCam");
354 if (nextRenderStep) {
355 nextRenderStep =
false;
359 colorImageSide =
new Texture2D (texWidth, texHeight);
360 colorImageSide.ReadPixels (binaryCam.pixelRect, 0, 0);
361 colorImageSide.Apply ();
367 binaryImageFaceSide.ReadPixels (binaryCam.pixelRect, 0, 0);
368 binaryImageFaceSide.Apply ();
375 binaryImageFace.ReadPixels (mouthAreaTex, (
int)mouthAreaTex.xMin, (
int)mouthAreaTex.yMin);
376 binaryImageFace.Apply ();
377 binaryImageAll.ReadPixels (mouthAreaTex, (
int)mouthAreaTex.xMin, (
int)mouthAreaTex.yMin);
378 binaryImageAll.Apply();
384 binaryImageEyebrows.ReadPixels (eyeBrowsAreaTex, (
int)eyeBrowsAreaTex.xMin, (
int)eyeBrowsAreaTex.yMin);
385 binaryImageEyebrows.Apply ();
386 binaryImageAll.ReadPixels (eyeBrowsAreaTex, (
int)eyeBrowsAreaTex.xMin, (
int)eyeBrowsAreaTex.yMin);
387 binaryImageAll.Apply();
392 if (renderStep == 2) {
394 binaryImageFace.ReadPixels (eyesAreaTex, (
int)eyesAreaTex.xMin, (
int)eyesAreaTex.yMin);
395 binaryImageFace.Apply ();
396 binaryImageAll.ReadPixels (eyesAreaTex, (
int)eyesAreaTex.xMin, (
int)eyesAreaTex.yMin);
397 binaryImageAll.Apply();
401 if (renderStep == 1) {
403 binaryImageHead.ReadPixels (binaryCam.pixelRect, 0, 0);
404 binaryImageHead.Apply ();
406 binaryImageAll.Apply ();
409 if (renderStep == 0) {
410 colorImage =
new Texture2D (texWidth, texHeight);
411 colorImage.ReadPixels (binaryCam.pixelRect, 0, 0);
430 nextRenderStep =
true;
438 faceHeight = yc [yc.Count - 1].Value;
439 faceYPos = yc [yc.Count - 1].Key/texHeight;
457 nextRenderStep =
true;
466 Vector2[] eyesPos = findEyeFeatures (hist, eyesArea, eyesAreaTex, eyesXdistBorder);
470 leftEyePos = eyesPos[0];
471 rightEyePos = eyesPos[1];
475 Debug.DrawLine (
new Vector3 (0.0f, leftEyePos.y, -1.0f),
new Vector3 (2.0f, leftEyePos.y, -1.0f), Color.cyan, 30.0f,
false);
477 Debug.DrawLine (
new Vector3 (leftEyePos.x, 1.0f, -1.0f),
new Vector3 (leftEyePos.x, 0.0f, -1.0f), Color.cyan, 30.0f,
false);
478 Debug.DrawLine (
new Vector3 (rightEyePos.x, 1.0f, -1.0f),
new Vector3 (rightEyePos.x, 0.0f, -1.0f), Color.cyan, 30.0f,
false);
479 Debug.DrawLine (
new Vector3 (1 + leftEyePos.x, 1.0f, -1.0f),
new Vector3 (1 + leftEyePos.x, 0.0f, -1.0f), Color.cyan, 30.0f,
false);
480 Debug.DrawLine (
new Vector3 (1 + rightEyePos.x, 1.0f, -1.0f),
new Vector3 (1 + rightEyePos.x, 0.0f, -1.0f), Color.cyan, 30.0f,
false);
496 Vector2 leftEyeBrowPos;
497 Vector2 rightEyeBrowPos;
501 nextRenderStep =
true;
509 Vector2[] eyeBrowsPos = findEyeFeatures (hist, eyeBrowsArea, eyeBrowsAreaTex, eyeBrowsXdistBorder);
512 leftEyeBrowPos = eyeBrowsPos[0];
513 rightEyeBrowPos = eyeBrowsPos[1];
515 Debug.DrawLine (
new Vector3 (0.0f, leftEyeBrowPos.y, -1.0f),
new Vector3 (2.0f, leftEyeBrowPos.y, -1.0f), Color.cyan, 30.0f,
false);
517 Debug.DrawLine (
new Vector3 (leftEyeBrowPos.x, 1.0f, -1.0f),
new Vector3 (leftEyeBrowPos.x, 0.0f, -1.0f), Color.cyan, 30.0f,
false);
518 Debug.DrawLine (
new Vector3 (rightEyeBrowPos.x, 1.0f, -1.0f),
new Vector3 (rightEyeBrowPos.x, 0.0f, -1.0f), Color.cyan, 30.0f,
false);
519 Debug.DrawLine (
new Vector3 (1 + leftEyeBrowPos.x, 1.0f, -1.0f),
new Vector3 (1 + leftEyeBrowPos.x, 0.0f, -1.0f), Color.cyan, 30.0f,
false);
520 Debug.DrawLine (
new Vector3 (1 + rightEyeBrowPos.x, 1.0f, -1.0f),
new Vector3 (1 + rightEyeBrowPos.x, 0.0f, -1.0f), Color.cyan, 30.0f,
false);
543 Vector2[] findEyeFeatures(
Histogram hist, Rect area, Rect areaTex,
int xDistBorder){
548 List<KeyValuePair<int, float>> yMin = hist.
findMin(hist.
yHist);
553 int min0 = (int)(bounds[0] + bounds[1]) / 2;
555 Vector2 left =
new Vector2 ();
556 Vector2 right =
new Vector2 ();
558 left.y = area.yMin + ((float)min0)/texHeight;
559 right.y = area.yMin + ((float)min0)/texHeight;
564 List<KeyValuePair<int, float>> xMin = hist.
findMin(hist.
xHist);
568 while (m3<xMin.Count && (xMin[m3].Key < xDistBorder || xMin[m3].Key > areaTex.xMax - areaTex.xMin - xDistBorder)) {
575 int min1 = (int)(bounds[0] + bounds[1]) / 2;
578 while (m4<xMin.Count && (Mathf.Abs((min1- xMin[m4].Key)) < eyesXdist || xMin[m4].Key < xDistBorder || xMin[m4].Key > areaTex.xMax - areaTex.xMin - xDistBorder)) {
583 throw new MissingComponentException (
"Could not find eye features)");
587 int min2 = (int)(bounds[0] + bounds[1]) / 2;
591 left.x = (area.xMin + ((float)min1)/texWidth) * 0.6f + 0.2f;
592 right.x = (area.xMin + ((float)min2)/texWidth) * 0.6f + 0.2f;
594 left.x = (area.xMin + ((float)min2)/texWidth) * 0.6f + 0.2f;
595 right.x = (area.xMin + ((float)min1)/texWidth) * 0.6f + 0.2f;
599 return new Vector2[]{left, right};
612 nextRenderStep =
true;
619 List<KeyValuePair<int, float>> yMin = hist.
findMin(hist.
yHist);
623 while ( m1<yMin.Count && (yMin[m1].Key < mouthYdist || yMin[m1].Key > mouthAreaTex.yMax - mouthAreaTex.yMin - mouthYdist)) {
627 List<KeyValuePair<int, float>> xMin = hist.
findMin(hist.
xHist);
631 while ( m2<xMin.Count && (xMin[m2].Key < mouthXdist || xMin[m2].Key > mouthAreaTex.xMax - mouthAreaTex.xMin - mouthXdist)) {
635 mouthPos =
new Vector2 ();
637 mouthPos.x = (mouthArea.xMin + ((float)xMin[m2].Key)/texWidth) * 0.6f + 0.2f;
638 mouthPos.y = mouthArea.yMin + ((float)yMin[m1].Key)/texHeight;
640 Debug.DrawLine (
new Vector3 (0.0f, mouthPos.y, -1.0f),
new Vector3 (2.0f, mouthPos.y, -1.0f), Color.green, 20.0f,
false);
641 Debug.DrawLine (
new Vector3 (mouthPos.x, 1.0f, -1.0f),
new Vector3 (mouthPos.x, 0.0f, -1.0f), Color.green, 20.0f,
false);
642 Debug.DrawLine (
new Vector3 (mouthPos.x + 1f, 1.0f, -1.0f),
new Vector3 (mouthPos.x + 1f, 0.0f, -1.0f), Color.green, 20.0f,
false);
649 setHelpLinesEnabled (
false);
664 nextRenderStep =
true;
673 float height = yc [yc.Count-1].Value;
675 float scale = height / faceHeight;
681 List<KeyValuePair<int, float>> yMax = hist2.
findMax(hist2.
yHist);
683 int m1 = yMax.Count-1;
685 while ( m1>=0 && (yMax[m1].Key < noseYdist || yMax[m1].Key > texHeight - noseYdist)) {
689 Debug.DrawLine (
new Vector3 ( 0.0f, ((
float)yMax[m1].Key)/((
float)texHeight), -1.0f),
new Vector3 ( 1.0f, ((
float)yMax[m1].Key/texHeight), -1.0f), Color.yellow, 20.0f,
false);
692 float nosePos = 0.55f;
694 float yOffset = nosePos - yMax [m1].Key/texHeight;
695 float xOffset = 0.5f - (xc[xc.Count - 1].Key/texWidth) * 0.6f + 0.2f;
698 GameObject.Find (
"ResizeQuad").transform.localScale *= scale;
699 GameObject.Find (
"ResizeQuad").transform.position +=
new Vector3 (xOffset, yOffset, 0f);
702 nextRenderStep =
true;
706 GameObject.Find (
"Head_mesh").GetComponent<Renderer> ().material.SetTexture (
"_MainTex", colorImage);
707 GameObject.Find (
"Head_mesh").GetComponent<Renderer> ().material.SetTexture (
"_Side", colorImageSide);
710 Camera.main.transform.position =
new Vector3 (1.5f, 0.5f, -2f);
711 GameObject.Find(
"SnakeScript").GetComponent<Renderer>().material.SetTexture (
"_MainTex", binaryImageAll);
725 private void startSnake(){
732 GameObject.Find(
"GaussQuadX").GetComponent<Renderer>().material.mainTexture = binaryImageHead;
737 GameObject.Find(
"GaussQuadX").GetComponent<Renderer>().material.mainTexture = binaryImageFace;
744 GameObject.Find(
"GaussQuadX").GetComponent<Renderer>().material.mainTexture = binaryImageEyebrows;
747 controller.
findEyebrows (leftEyeBrowPos, rightEyeBrowPos);
762 if (renderStep <= 6) {
763 float sliderWidth = Screen.width * 0.1f;
764 float sliderY = Screen.height * 0.75f;
765 float sliderHeight = Screen.height * 0.2f;
768 thresholds [0] = GUI.VerticalSlider (
new Rect (Screen.width * 0.2f, sliderY, sliderWidth, sliderHeight), thresholds [0], 240.0F, 16.0F);
769 thresholds [1] = GUI.VerticalSlider (
new Rect (Screen.width * 0.3f, sliderY, sliderWidth, sliderHeight), thresholds [1], 240.0F, 16.0F);
770 thresholds [2] = GUI.VerticalSlider (
new Rect (Screen.width * 0.45f, sliderY, sliderWidth, sliderHeight), thresholds [2], 240.0F, 16.0F);
771 thresholds [3] = GUI.VerticalSlider (
new Rect (Screen.width * 0.55f, sliderY, sliderWidth, sliderHeight), thresholds [3], 240.0F, 16.0F);
773 thresholds [4] = GUI.VerticalSlider (
new Rect (Screen.width * 0.7f, sliderY, sliderWidth, sliderHeight), thresholds [4], 240.0F, 16.0F);
774 thresholds [5] = GUI.VerticalSlider (
new Rect (Screen.width * 0.8f, sliderY, sliderWidth, sliderHeight), thresholds [5], 240.0F, 16.0F);
776 if (GUI.Button (
new Rect (Screen.width / 2 - 75, 20, 200, 50), buttonText))
780 sQuad.GetComponent<Renderer> ().material.SetVector (
"_Thresholds",
new Vector4 (thresholds [2], thresholds [3], thresholds [4], thresholds [5]));
781 sQuad.GetComponent<Renderer> ().material.SetVector (
"_Thresholds2",
new Vector4 (thresholds [0], thresholds [1], 0, 0));
Texture2D binaryImageHead
void resetSnake()
Reinitializes the snake and control points script.
void setHelpLines()
Sets help lines.
List< KeyValuePair< int, float > > findCluster(float[] hist)
Finds all clusters in the given histogram.
WebCamTexture webcamTexture
void findEyebrows(Vector2 leftEyeBrowCenter, Vector2 rightEyeBrowCenter)
Runs the eyebrow deformation.
Texture2D binaryImageFaceSide
void OnPostRender()
Saves rendersteps into textures.
Texture2D binaryImageEyebrows
Texture2D binaryImageEyesSide
void RunContourDeformation()
runs the deformation for the face contour
List< KeyValuePair< int, float > > findMin(float[] hist)
Finds all local minima in the given histogram.
void renderCamImage(int thresholdEnabled, int binaryEnabled)
Renders the camera image.
void reset()
Resets the image creation progress.
Texture2D binaryImageMouthSide
void ApplyDeformation()
Applies the deformation to the model.
List< KeyValuePair< int, float > > findMax(float[] hist)
Finds all local maxima in the given histogram.
void draw()
Draws the histogram.
int[] findSimilarArea(int index, float eps, float[] hist)
Finds all surrounding Values, which are not larger than the value with the given index by eps in the ...
Texture2D binaryImageFace
void findFaceContours(Vector2 leftEyeCenter, Vector2 rightEyeCenter, Vector2 mouthCenter)
Runs the left/rigt eye and mouth deformation.