Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // All rights to this code sample waived under Creative Commons Zero Waiver
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Drawing;
- namespace timewarp
- {
- class Program
- {
- static int imageWidth = 2560;
- static int imageHeight = 1440;
- //static string filenamePrefix = "teapotwarped";
- //static string depthFilename = "teapotdepthnoaa.raw";
- //static string pixelsFilename = "teapot.raw";
- //static double fovDegreesHorizontal = 45.0;
- //static double fovDegreesVertical = 26.231;
- //static double zscale = 1.5;
- //static double minDepth = 93.0;
- //static double maxDepth = 123.0;
- //static string filenamePrefix = "room";
- //static string depthFilename = "roomdepthnoaa.raw";
- //static string pixelsFilename = "room.raw";
- //static double fovDegreesHorizontal = 110.0;
- //static double fovDegreesVertical = 77.552;
- //static double zscale = 1.0;
- //static double minDepth = 60;
- //static double maxDepth = 330.0;
- static string filenamePrefix = "planes1";
- static string depthFilename = "planes1depthnoaa.raw";
- static string pixelsFilename = "planes1.raw";
- static double fovDegreesHorizontal = 106.26;
- static double fovDegreesVertical = 73.74;
- static double zscale = 1.0;
- static double minDepth = 69.0;
- static double maxDepth = 111.0;
- static void Main(string[] args)
- {
- byte[] depthMapBytes = File.ReadAllBytes(depthFilename);
- double[] depthMap = new double[depthMapBytes.Length/2];
- for (int i=0; i < depthMap.Length; i++)
- {
- ushort depthShort = (ushort)(depthMapBytes[2 * i] + (depthMapBytes[2 * i + 1] << 8));
- depthMap[i] = maxDepth - (maxDepth - minDepth)*depthShort/ushort.MaxValue;
- }
- byte[] pixelRgbBytes = File.ReadAllBytes(pixelsFilename);
- Color[] pixels = new Color[pixelRgbBytes.Length/3];
- for (int i=0; i < pixels.Length; i++)
- {
- pixels[i] = Color.FromArgb(255, pixelRgbBytes[3 * i],
- pixelRgbBytes[3 * i + 1],
- pixelRgbBytes[3 * i + 2]);
- }
- pixelRgbBytes = null;
- CreateRotatedImage(pixels, depthMap, 0, 0, filenamePrefix + ".shiftright.png", 0.0, 30.0);
- int counter = 1;
- for (double degrees = -90; degrees <= 90; degrees+=0.5, counter++)
- {
- //Console.WriteLine("Degrees: " + degrees);
- //CreateRotatedImage(pixels, depthMap, degrees, 0, filenamePrefix + "." + counter + ".rotateeye.png", 0.0, 0.0);
- //CreateRotatedImage(pixels, depthMap, 0, degrees, filenamePrefix + "." + counter + ".rotateeyey.png", 0.0, 0.0);
- //CreateRotatedImage(pixels, depthMap, degrees, 0, filenamePrefix + "." + counter + ".rotateneck.png", 15.0, 0.0);
- //CreateRotatedImage(pixels, depthMap, degrees, 0, filenamePrefix + "." + counter + ".rotatearound.png", -((minDepth + maxDepth) / 2), 0.0);
- }
- }
- private static void CreateRotatedImage(Color[] pixels, double[] depthMap, double rotateDegreesX, double rotateDegreesY, string filename, double zTranslate, double xTranslate)
- {
- double[] resultDepthMap = new double[depthMap.Length];
- for (int i = 0; i < resultDepthMap.Length; i++)
- {
- resultDepthMap[i] = double.PositiveInfinity;
- }
- Color[] result = new Color[pixels.Length];
- Bitmap bitmap = new Bitmap(imageWidth, imageHeight);
- Graphics g = Graphics.FromImage(bitmap);
- for (int i = 0; i < pixels.Length; i++)
- {
- int xi = i % imageWidth;
- int yi = i / imageWidth;
- double x = xi;
- double y = yi;
- double newZ;
- double centerZ = depthMap[i];
- double[] zvalues = new double[4] { centerZ, centerZ, centerZ, centerZ };
- if (xi - 1 >= 0 && yi - 1 >= 0) { zvalues[0] = (centerZ + depthMap[(yi - 1) * imageWidth + (xi - 1)]) / 2; }
- if (xi + 1 < imageWidth && yi - 1 >= 0) { zvalues[1] = (centerZ + depthMap[(yi - 1) * imageWidth + (xi + 1)]) / 2; }
- if (xi + 1 < imageWidth && yi + 1 < imageHeight) { zvalues[2] = (centerZ + depthMap[(yi + 1) * imageWidth + (xi + 1)]) / 2; }
- if (xi - 1 >= 0 && yi + 1 < imageHeight) { zvalues[3] = (centerZ + depthMap[(yi + 1) * imageWidth + (xi - 1)]) / 2; }
- if (Math.Max(Math.Max(Math.Max(zvalues[0], zvalues[1]), zvalues[2]), zvalues[3]) - Math.Min(Math.Min(Math.Min(zvalues[0], zvalues[1]), zvalues[2]), zvalues[3]) > 1.0)
- {
- zvalues[0] = centerZ; zvalues[1] = centerZ; zvalues[2] = centerZ; zvalues[3] = centerZ;
- }
- PointF vertex = TransformImagePoint(rotateDegreesX, rotateDegreesY, zTranslate, xTranslate, x, y, centerZ, out newZ);
- #if true
- PointF[] vertices = new PointF[4];
- double dummyZ;
- vertices[0] = TransformImagePoint(rotateDegreesX, rotateDegreesY, zTranslate, xTranslate, x - 0.5, y - 0.5, zvalues[0], out dummyZ);
- vertices[1] = TransformImagePoint(rotateDegreesX, rotateDegreesY, zTranslate, xTranslate, x + 0.5, y - 0.5, zvalues[1], out dummyZ);
- vertices[2] = TransformImagePoint(rotateDegreesX, rotateDegreesY, zTranslate, xTranslate, x + 0.5, y + 0.5, zvalues[2], out dummyZ);
- vertices[3] = TransformImagePoint(rotateDegreesX, rotateDegreesY, zTranslate, xTranslate, x - 0.5, y + 0.5, zvalues[3], out dummyZ);
- #endif
- int depthMapIndex = (int)Math.Round(vertex.Y) * imageWidth + (int)Math.Round(vertex.X);
- if (newZ >= 1 && vertex.X >= 0 && vertex.Y >= 0 && vertex.X < imageWidth - 0.5 && vertex.Y < imageHeight - 0.5 && newZ <= resultDepthMap[depthMapIndex])
- {
- bitmap.SetPixel((int)Math.Round(vertex.X), (int)Math.Round(vertex.Y), pixels[i]);
- #if true
- using (Brush brush = new SolidBrush(pixels[i]))
- {
- g.FillPolygon(brush, vertices);
- using (Pen pen = new Pen(pixels[i]))
- {
- g.DrawPolygon(pen, vertices);
- }
- g.FillRectangle(brush, new Rectangle((int)Math.Round(vertex.X) - 1, (int)Math.Round(vertex.Y) - 1, 2, 2));
- }
- #endif
- resultDepthMap[depthMapIndex] = newZ;
- }
- }
- bitmap.Save(filename);
- bitmap.Dispose();
- }
- private static PointF TransformImagePoint(double rotateDegreesX, double rotateDegreesY, double zTranslate, double xTranslate, double x, double y, double z, out double newZ)
- {
- // z /= Math.Sqrt(1*1+Math.Sqrt(x*x+y*y));
- ImageSpaceToWorldSpace(x, y, out x, out y);
- TransformPoint(zTranslate, xTranslate, rotateDegreesX, rotateDegreesY, ref x, ref y, ref z);
- WorldSpaceToImageSpace(ref x, ref y);
- PointF transformedScreenPoint = new PointF((float)x, (float)y);
- newZ = z;
- return transformedScreenPoint;
- }
- private static void WorldSpaceToImageSpace(ref double x, ref double y)
- {
- double scalex;
- double scaley;
- GetScaleFactors(out scalex, out scaley);
- x = (x / scalex) * (imageWidth) + (imageWidth / 2);
- y = (y / scaley) * (imageHeight) + (imageHeight / 2);
- }
- private static void ImageSpaceToWorldSpace(double xin, double yin, out double x, out double y)
- {
- double scalex;
- double scaley;
- GetScaleFactors(out scalex, out scaley);
- x = (xin - imageWidth / 2) / (imageWidth) * scalex;
- y = (yin - imageHeight / 2) / (imageHeight) * scaley;
- }
- private static void GetScaleFactors(out double scalex, out double scaley)
- {
- // At z=1 plane, image should be fovDegrees wide
- scalex = 2 * Math.Tan(fovDegreesHorizontal * Math.PI / 180 / 2) * zscale;
- scaley = 2 * Math.Tan(fovDegreesVertical * Math.PI / 180 / 2) * zscale;
- }
- private static void TransformPoint(double zTranslate, double xTranslate, double rotateDegreesX, double rotateDegreesY, ref double x, ref double y, ref double z)
- {
- double sina, cosa;
- x *= z;
- y *= z;
- z += zTranslate;
- x -= xTranslate;
- if (rotateDegreesX != 0.0)
- {
- sina = Math.Sin(rotateDegreesX * Math.PI / 180);
- cosa = Math.Cos(rotateDegreesX * Math.PI / 180);
- double xnew = x * cosa - z * sina;
- double znew = x * sina + z * cosa;
- x = xnew; z = znew;
- }
- if (rotateDegreesY != 0.0)
- {
- sina = Math.Sin(rotateDegreesY * Math.PI / 180);
- cosa = Math.Cos(rotateDegreesY * Math.PI / 180);
- double ynew = y * cosa - z * sina;
- double znew = y * sina + z * cosa;
- y = ynew; z = znew;
- }
- z -= zTranslate;
- x /= z;
- y /= z;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement