1 #region Using Statements
3 using System.Collections.Generic;
6 using System.Collections.Generic;
9 using Microsoft.Xna.Framework;
10 using Microsoft.Xna.Framework.Graphics;
11 using Microsoft.Xna.Framework.Graphics.PackedVector;
27 Texture2D recoloredImage;
28 Texture2D recoloredImageTest;
29 Texture2D recoloredImageMask;
31 List<TransferControlPoint> colorCP;
32 List<TransferControlPoint> alphaCP;
34 List<TransferControlPoint> cvdColorCP;
35 Texture2D cvdTransferTexture;
43 ILArray<double> omegaWeightsR;
44 ILArray<double> omegaWeightsG;
45 ILArray<double> omegaWeightsB;
47 Point[] selectedPixels;
49 ILArray<double> recoloredPixelsR;
50 ILArray<double> recoloredPixelsG;
51 ILArray<double> recoloredPixelsB;
59 GraphicsDevice graphics;
66 set { lambda = value; }
70 set { delta = value; }
72 public Texture2D CVDtransferFunction
74 get {
return cvdTransferTexture; }
76 public Point[] SelectedPixels
78 get {
return selectedPixels; }
80 public Texture2D RecoloredImageMask
82 get {
return recoloredImageMask; }
87 public CVDtf(Texture2D _recoloredImage, GraphicsDevice _graphics)
90 recoloredImage = _recoloredImage;
91 recoloredImageTest = _recoloredImage;
92 recoloredImageMask =
new Texture2D(graphics, recoloredImage.Width, recoloredImage.Height,
false, SurfaceFormat.Rgba64);
98 N = recoloredImage.Width * recoloredImage.Height;
101 if (Nr <= M) Nr = M + (int)((N - M) * 0.5f);
102 if (Nr >= N) Nr = N - (int)((N - M) * 0.5f);
103 selectedPixels =
new Point[Nr];
104 recoloredPixelsR = ILMath.zeros(Nr, 1);
105 recoloredPixelsG = ILMath.zeros(Nr, 1);
106 recoloredPixelsB = ILMath.zeros(Nr, 1);
109 delta =
new double[M];
110 for (
int i = 0; i < delta.Length; i++)
118 omegaWeightsR = ILMath.ones(Nr, M);
119 omegaWeightsG = ILMath.ones(Nr, M);
120 omegaWeightsB = ILMath.ones(Nr, M);
127 private void saveScreenshot(Texture2D texture, String name, String ext)
129 Console.WriteLine(
"saving " + name);
132 if (!name.ElementAt(name.Length - 4).Equals(
".")) name = name +
"." + ext;
133 FileStream stream = File.OpenWrite(name);
137 texture.SaveAsPng(stream, texture.Width, texture.Height);
140 texture.SaveAsJpeg(stream, texture.Width, texture.Height);
143 if (name.ElementAt(name.Length - 4).Equals(
".")) name = name.Substring(0, name.Length - 4);
144 name = name +
".png";
145 texture.SaveAsPng(stream, texture.Width, texture.Height);
152 Console.WriteLine(
"Save Screenshot: ");
153 Console.WriteLine(e);
158 public void selectRecoloredPixels()
161 saveScreenshot(recoloredImage,
"recoloredImageForCVD",
"png");
162 Rgba64[] recoloredArray =
new Rgba64[recoloredImage.Width * recoloredImage.Height];
163 recoloredImage.GetData<Rgba64>(recoloredArray);
167 Rgba64[] recoloredArrayMask =
new Rgba64[recoloredImage.Width * recoloredImage.Height];
168 recoloredArrayMask.Initialize();
171 Texture2D selectedPixelsMask =
new Texture2D(graphics, recoloredImage.Width, recoloredImage.Height,
false, SurfaceFormat.Color);
172 Color[] selectedPixelsArray =
new Color[recoloredImage.Width * recoloredImage.Height];
173 for (
int i = 0; i < selectedPixelsArray.Length; i++)
175 selectedPixelsArray[i] = Color.Black;
178 for (
int j = 0; j < recoloredArrayMask.Length; j++)
180 recoloredArrayMask[j] =
new Rgba64(0, 0, 0, 1);
183 Random randomPos =
new Random();
184 Random randomScale =
new Random();
189 double xScale = randomPos.NextDouble();
190 double yScale = randomPos.NextDouble();
191 int x = (int)(randomScale.Next(recoloredImage.Width) * xScale);
192 int y = (int)(randomScale.Next(recoloredImage.Height) * yScale);
193 int selectedPos = x + y * recoloredImage.Width;
195 #region median filter
224 #region average filter
251 Vector4 selectedPixel = recoloredArray[selectedPos].ToVector4();
252 if (selectedPixel.X > 0.2f || selectedPixel.Y > 0.2f || selectedPixel.Z > 0.2f)
256 selectedPixels[next] =
new Point(x, y);
257 recoloredPixelsR.SetValue((
double)selectedPixel.X, next, 0);
258 recoloredPixelsG.SetValue((
double)selectedPixel.Y, next, 0);
259 recoloredPixelsB.SetValue((
double)selectedPixel.Z, next, 0);
263 recoloredArrayMask[selectedPos] =
new Rgba64((
float)x / recoloredImage.Width, (
float)y / recoloredImage.Height, 0.0f, 1.0f);
264 selectedPixelsArray[selectedPos] =
new Color(selectedPixel);
272 recoloredImageMask.SetData<Rgba64>(recoloredArrayMask);
273 selectedPixelsMask.SetData<Color>(selectedPixelsArray);
276 saveScreenshot(recoloredImageMask,
"recoloredImageMask",
"png");
277 saveScreenshot(selectedPixelsMask,
"selectedPixelsMask",
"png");
285 public Texture2D calculateCVDColors()
288 #region calculate cvd colors for the tf
289 xR = ILMath.linsolve(omegaWeightsR, recoloredPixelsR);
290 xG = ILMath.linsolve(omegaWeightsG, recoloredPixelsG);
291 xB = ILMath.linsolve(omegaWeightsB, recoloredPixelsB);
295 ILArray<double> bTestR = ILMath.multiply(omegaWeightsR, xR);
296 ILArray<double> errR = ILMath.abs(bTestR - recoloredPixelsR);
297 ILArray<double> errRnorm = ILMath.norm(bTestR - recoloredPixelsR);
299 ILArray<double> bTestG = ILMath.multiply(omegaWeightsG, xG);
300 ILArray<double> errG = ILMath.abs(bTestG - recoloredPixelsG);
301 ILArray<double> errGnorm = ILMath.norm(bTestG - recoloredPixelsG);
303 ILArray<double> bTestB = ILMath.multiply(omegaWeightsB, xB);
304 ILArray<double> errB = ILMath.abs(bTestB - recoloredPixelsB);
305 ILArray<double> errBnorm = ILMath.norm(bTestB - recoloredPixelsB);
310 for (
int i = 0; i < M; i++)
312 max = Math.Max(Math.Abs(xR.GetValue(i, 0)), max);
313 max = Math.Max(Math.Abs(xG.GetValue(i, 0)), max);
314 max = Math.Max(Math.Abs(xB.GetValue(i, 0)), max);
328 List<TransferControlPoint> ctColorCP =
GameProperties.Instance.colorControlPoints;
332 ILArray<double> deltaWeights = ILMath.zeros(M, 1);
333 ILArray<double> referenceTFR = ILMath.zeros(M, 1);
334 ILArray<double> referenceTFG = ILMath.zeros(M, 1);
335 ILArray<double> referenceTFB = ILMath.zeros(M, 1);
336 for (
int i = 0; i < M; i++)
338 deltaWeights.SetValue(delta[i], i, 0);
339 referenceTFR.SetValue(ctColorCP[i].color.X * delta[i], i, 0);
340 referenceTFG.SetValue(ctColorCP[i].color.Y * delta[i], i, 0);
341 referenceTFB.SetValue(ctColorCP[i].color.Z * delta[i], i, 0);
344 ILArray<double> xR2 = ILMath.linsolve(deltaWeights, referenceTFR);
345 ILArray<double> xG2 = ILMath.linsolve(deltaWeights, referenceTFG);
346 ILArray<double> xB2 = ILMath.linsolve(deltaWeights, referenceTFB);
349 ILArray<double> bTestR2 = ILMath.multiply(deltaWeights, xR2);
350 ILArray<double> errR2 = ILMath.abs(bTestR2 - referenceTFR);
351 ILArray<double> errRnorm2 = ILMath.norm(errR2);
353 ILArray<double> bTestG2 = ILMath.multiply(deltaWeights, xG2);
354 ILArray<double> errG2 = ILMath.abs(bTestG2 - referenceTFG);
355 ILArray<double> errGnorm2 = ILMath.norm(errG2);
357 ILArray<double> bTestB2 = ILMath.multiply(deltaWeights, xB2);
358 ILArray<double> errB2 = ILMath.abs(bTestB2 - referenceTFG);
359 ILArray<double> errBnorm2 = ILMath.norm(errB2);
364 for (
int i = 0; i < M; i++)
366 xR.SetValue((1 - lambda) * xR.GetValue(i, 0) + lambda * xR2.GetValue(0,0) , i, 0);
367 xG.SetValue((1 - lambda) * xG.GetValue(i, 0) + lambda * xG2.GetValue(0, 0), i, 0);
368 xB.SetValue((1 - lambda) * xB.GetValue(i, 0) + lambda * xB2.GetValue(0, 0), i, 0);
373 #region set in the cvd cp list
374 cvdColorCP =
new List<TransferControlPoint>();
375 for (
int i = 0; i < M; i++)
378 cvdColorCP.Add(
new TransferControlPoint((
float)xR.GetValue(i, 0), (float)xG.GetValue(i, 0), (float)xB.GetValue(i, 0), ctColorCP[i].isoValue));
384 #region interpolate between ControlPoints
386 Color[] colorArray =
new Color[256];
393 for (
int i = 0; i < cvdColorCP[0].isoValue; i++)
395 colorArray[i] =
new Color(0.0f, 0.0f, 0.0f, 0.0f);
398 for (
int j = 0; j < cvdColorCP.Count - 1; j++)
400 for (
int i = cvdColorCP[j].isoValue; i <= cvdColorCP[j + 1].isoValue; i++)
402 amount = (((float)i - cvdColorCP[j].isoValue) /
403 (cvdColorCP[j + 1].isoValue - cvdColorCP[j].isoValue));
404 colorArray[i] = Color.Lerp(
new Color(cvdColorCP[j].color),
405 new Color(cvdColorCP[j + 1].color), amount);
410 for (
int i = cvdColorCP[cvdColorCP.Count - 1].isoValue + 1; i < 256; i++)
412 colorArray[i] =
new Color(0.0f, 0.0f, 0.0f, 0.0f);
418 cvdTransferTexture =
new Texture2D(graphics, 256, 1,
false, SurfaceFormat.Color);
419 cvdTransferTexture.SetData<Color>(colorArray);
420 saveScreenshot(cvdTransferTexture,
"CVDTF",
"png");
423 return cvdTransferTexture;
427 public void setTFWeights(Texture2D weights,
int controlPointIdx)
429 if (controlPointIdx >= M)
return;
431 Rgba64[] weightsArray =
new Rgba64[weights.Width * weights.Height];
432 weights.GetData<Rgba64>(weightsArray);
435 for (
int i = 0; i < selectedPixels.Length; i++)
437 int pos = (selectedPixels[i].X + selectedPixels[i].Y * weights.Width);
438 Vector4 nextWeight = weightsArray[pos].ToVector4();
440 omegaWeightsR.SetValue((
double)nextWeight.X, i, controlPointIdx);
441 omegaWeightsG.SetValue((
double)nextWeight.Y, i, controlPointIdx);
442 omegaWeightsB.SetValue((
double)nextWeight.Z, i, controlPointIdx);
446 Console.WriteLine(
"Weights for CP:" + controlPointIdx +
":" + nextWeight.X +
"," + nextWeight.Y +
"," + nextWeight.Z +
"," + nextWeight.W);