10 public class Snake : MonoBehaviour {
29 private float _touchTime = -0.5f;
41 _renderer = GetComponent<Renderer> ();
42 _I = GameObject.Find (
"2texCam").GetComponent<
grabPicture> ().binaryImageAll;
47 _initVx =
new Matrix();
48 _initVy =
new Matrix();
66 Vector3[] points =
new Vector3[_Vx.RowCount];
68 for(
int i = 0; i < _Vx.RowCount; i++) {
69 points[i] =
new Vector3((
float)_Vx[i + 1].Re, (
float)_Vy[i + 1].Re, 0.0f);
70 points[i] = GameObject.Find(
"2texCam").GetComponent<Camera>().ScreenToWorldPoint(points[i]);
83 Vector3[] points =
new Vector3[_Vx.RowCount];
85 for(
int i = 0; i < _Vx.RowCount; i++) {
86 points[i] =
new Vector3((
float)_initVx[i + 1].Re, (
float)_initVy[i + 1].Re, 0.0f);
87 points[i] = GameObject.Find(
"2texCam").GetComponent<Camera>().ScreenToWorldPoint(points[i]);
103 _initVx =
new Matrix();
104 _initVy =
new Matrix();
106 foreach (Vector3 cp
in controlPoints) {
108 Vector3 position = GameObject.Find(
"2texCam").GetComponent<Camera>().WorldToScreenPoint(cp);
111 if (Physics.Raycast (GameObject.Find(
"2texCam").GetComponent<Camera>().ScreenPointToRay (position), out hit)) {
112 Vector2 uv = hit.textureCoord;
114 tmpX =
new Matrix (
new double[] {uv.x * _I.width});
115 tmpY =
new Matrix (
new double[] {uv.y * _I.height});
117 if (_initVx.RowCount > 0) {
118 _initVx = Matrix.HorizontalConcat (_initVx, tmpX);
119 _initVy = Matrix.HorizontalConcat (_initVy, tmpY);
134 _renderer.enabled = display;
141 drawContour (_I, _Vx, _Vy, 1.0f);
156 Texture2D drawContour(Texture2D image, Matrix contourX, Matrix contourY,
float alpha) {
157 Color[] c =
new Color[] {
158 Color.blue, Color.cyan, Color.green, Color.yellow, Color.red,
159 Color.magenta, Color.gray
161 int N = contourX.RowCount;
163 for (
int i = 0; i < N; i++) {
165 c[ci] = c[ci] * alpha;
167 x = (int)Math.Round(contourX[i + 1].Re);
168 y = (int)Math.Round(contourY[i + 1].Re);
171 image.SetPixel(x, y, c[ci]);
173 image.SetPixel(x +1, y, c[ci]);
174 image.SetPixel(x, y +1,c[ci]);
175 image.SetPixel(x -1, y, c[ci]);
176 image.SetPixel(x, y -1,c[ci]);
178 image.SetPixel(x +1, y +1,c[ci]);
179 image.SetPixel(x -1, y +1,c[ci]);
180 image.SetPixel(x -1, y -1,c[ci]);
181 image.SetPixel(x +1, y -1,c[ci]);
183 image.SetPixel(x +1, y +2,c[ci]);
184 image.SetPixel(x -1, y +2,c[ci]);
185 image.SetPixel(x -1, y -2,c[ci]);
186 image.SetPixel(x +1, y -2,c[ci]);
187 image.SetPixel(x +2, y +1,c[ci]);
188 image.SetPixel(x -2, y +1,c[ci]);
189 image.SetPixel(x -2, y -1,c[ci]);
190 image.SetPixel(x +2, y -1,c[ci]);
192 image.SetPixel(x +2, y +2,c[ci]);
193 image.SetPixel(x -2, y +2,c[ci]);
194 image.SetPixel(x -2, y -2,c[ci]);
195 image.SetPixel(x +2, y -2,c[ci]);
197 image.SetPixel(x +3, y +3,c[ci]);
198 image.SetPixel(x -3, y +3,c[ci]);
199 image.SetPixel(x -3, y -3,c[ci]);
200 image.SetPixel(x +3, y -3,c[ci]);
205 colorIndex = (colorIndex + 1)% c.Length;
220 GameObject dFdxQuad = GameObject.Find(
"dFdxCam");
225 GameObject dFdyQuad = GameObject.Find(
"dFdyCam");
230 Color[] dVdx = _dIdx.GetPixels ();
231 Color[] dVdy = _dIdy.GetPixels ();
236 drawContour(_I, _Vx, _Vy, 1.0f);
237 for (
int i = 0; i < iterations; i++) {
239 vfx = interpolate(dVdx, _Vx, _Vy);
240 vfy = interpolate(dVdy, _Vx, _Vy);
242 _Vx = _AInv * ( _gamma * _Vx - _kappa * vfx);
243 _Vy = _AInv * ( _gamma * _Vy - _kappa * vfy);
245 if(i % 50 == 0 && drawSteps) {
246 drawContour(_I, _Vx, _Vy, 1.0f);
250 drawContour(_I, _Vx, _Vy, 1.0f);
264 Matrix interpolate(Color[] gradient, Matrix Vx, Matrix Vy) {
267 double[] p =
new double[N];
271 for (
int i = 0; i < N; i++) {
272 x = (int)Math.Round(Vx[i + 1].Re);
273 y = (int)Math.Round(Vy[i + 1].Re);
275 int j = x + y * _I.width;
276 if(j > gradient.Length)
277 j = gradient.Length-1;
284 p[i] = (((d.r * 2.0) - 1.0) + ((d.g * 2.0) - 1.0) + ((d.b * 2.0) - 1.0)) / 3.0;
290 return new Matrix (p);
302 _Vx = _initVx.Clone ();
303 _Vy = _initVy.Clone ();
305 int N = _Vx.RowCount;
306 Matrix alphaV = _alpha * Matrix.Ones (1, N);
307 Matrix betaV = _beta * Matrix.Ones (1, N);
308 Matrix gammaV = _gamma * Matrix.Ones (1, N);
315 Matrix diag1 = 2 * alphaV + 6 * betaV;
316 Matrix diag2 = -alphaV - 4 * betaV;
317 Matrix diag3 = betaV;
339 Matrix A = Matrix.Diag (diag1);
340 Matrix Diag2 = Matrix.Diag (diag2, 1) + Matrix.Diag (diag2, -1);
341 Matrix Diag2a = Matrix.Diag (diag2, N - 1) + Matrix.Diag (diag2, -(N - 1));
343 Matrix Diag3 = Matrix.Diag (diag3, 2) + Matrix.Diag (diag3, -2);
344 Matrix Diag3a = Matrix.Diag (diag3, N - 2) + Matrix.Diag (diag3, -(N - 2));
346 A += Diag2.Extract (1, N, 1, N);
347 A += Diag2a.Extract (1, N, 1, N);
348 A += Diag3.Extract (1, N, 1, N);
349 A += Diag3a.Extract (1, N, 1, N);
350 A += Matrix.Diag (gammaV);
352 _AInv = A.Inverse ();
void DisplayImagePlane(bool display)
Renders the snake image plane.
void SetControlPoints(Vector3[] controlPoints)
Sets the contour.
Vector3[] GetSnakeWorldPoints()
Gets the resulting contour in world coordinates.
void InitSnake(bool expanding=false)
Initializes the snake with the given contour.
void UpdateSnake(int iterations, bool drawSteps)
Executes the snake algorithm.
void ShowContour()
Renders the current contour state on the image plane.
Vector3[] GetStartWorldPoints()
Gets the start contour in world coordinates.