public NeighborhoodBuffer(FloatMapImage depthMap) { UndefinedValue = 1.0f; Width = (int)depthMap.Width; Height = (int)depthMap.Height; // For simple evaluation with a single bounding power-of-2 square // there is Ceiling function, otherwise when evaluating with four // smaller rectangles Floor is ok (we need one less level). LevelCount = (int)Math.Ceiling(Math.Log(Math.Max(Width, Height), 2)); minLevels = new FloatMapImage[LevelCount]; maxLevels = new FloatMapImage[LevelCount]; // The fist level has no neighborhood so it is a copy of the // original depth map. minLevels[0] = CopySingleChannelDepthMap(depthMap); maxLevels[0] = minLevels[0]; // The subsequent level take maximum from neighborhood 2^i. // This is just a simple single-pass construction. int offset = 1; for (int i = 1; i < LevelCount; i++) { minLevels[i] = ConstructLevel(offset, i, Math.Min, 1.0f, minLevels[i - 1]); maxLevels[i] = ConstructLevel(offset, i, Math.Max, 0.0f, maxLevels[i - 1]); offset *= 2; } }
private void loadDepthMapButton_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "Open depth map"; ofd.Filter = "PNG Files|*.png" + "|PFM Files|*.pfm" + "|Bitmap Files|*.bmp" + "|Gif Files|*.gif" + "|JPEG Files|*.jpg" + "|TIFF Files|*.tif" + "|All Image types|*.png;*.pfm;*.bmp;*.gif;*.jpg;*.tif"; ofd.FilterIndex = 7; ofd.FileName = ""; if (ofd.ShowDialog() != DialogResult.OK) { return; } if (depthMap != null) { depthMap.Dispose(); } if (ofd.FileName.EndsWith(".pfm")) { depthMap = PortableFloatMap.LoadImage(ofd.FileName); } else { Bitmap depthMapLdr = (Bitmap)Image.FromFile(ofd.FileName); depthMap = depthMapLdr.ToFloatMap(); depthMapLdr.Dispose(); } }
private static void DisplayInfo(FloatMapImage image) { Console.WriteLine("Portable float-map"); Console.WriteLine("Pixel format: {0}", image.PixelFormat); Console.WriteLine("Width: {0}, height: {1}", image.Width, image.Height); Console.WriteLine("Scale: {0}", image.Scale); }
private FloatMapImage ConstructLevel(int offset, int i, Func <float, float, float> func, float defaultValue, FloatMapImage prevLevel) { var level = new FloatMapImage((uint)Width, (uint)Height, PixelFormat.Greyscale); var current = level.Image; var prev = prevLevel.Image; for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { bool withinWidth = x + offset < Width; bool withinHeight = y + offset < Height; float topLeft = prev[x, y, 0]; //if (topLeft == UndefinedValue) topLeft = defaultValue; float bottomLeft = withinHeight ? prev[x, y + offset, 0] : defaultValue; //if (bottomLeft == UndefinedValue) bottomLeft = defaultValue; float topRight = withinWidth ? prev[x + offset, y, 0] : defaultValue; //if (topRight == UndefinedValue) topRight = defaultValue; float bottomRight = (withinWidth && withinHeight) ? prev[x + offset, y + offset, 0] : defaultValue; //if (bottomRight == UndefinedValue) bottomRight = defaultValue; current[x, y, 0] = func(func(topLeft, bottomLeft), func(topRight, bottomRight)); } } return(level); }
private FloatMapImage GetDepthTexture() { // allocate 32-bit unit unmanaged array to grab the depth buffer IntPtr depthBufferUInt32Ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UInt32)) * TextureSize.Width * TextureSize.Height); GL.BindTexture(TextureTarget.Texture2D, DepthTexture); GL.GetTexImage(TextureTarget.Texture2D, 0, OpenTK.Graphics.OpenGL.PixelFormat.DepthComponent, PixelType.UnsignedInt, depthBufferUInt32Ptr); GL.BindTexture(TextureTarget.Texture2D, 0); FloatMapImage depthImage = new FloatMapImage((uint)TextureSize.Width, (uint)TextureSize.Height, BokehLab.FloatMap.PixelFormat.Greyscale); var image = depthImage.Image; unsafe { int inputStride = TextureSize.Width; float conversionFactor = 1 / (float)UInt32.MaxValue; for (int y = 0; y < TextureSize.Height; y++) { UInt32 *inputRow = (UInt32 *)depthBufferUInt32Ptr + (y * inputStride); for (int x = 0; x < TextureSize.Width; x++) { image[x, y, 0] = inputRow[x] * conversionFactor; } } } return(depthImage); }
public void MakeCriterionImages() { FloatMapImage origImage = ((Bitmap)Bitmap.FromFile("chessRGB.jpg")).ToFloatMap(); HybridSpreadingFilter.FilterSelectionCriterion criterion = new HybridSpreadingFilter.FilterSelectionCriterion() { Threshold = CRITERION_THRESHOLD }; criterion.OriginalImage = origImage; criterion.OriginalImageSAT = origImage.Integrate(); int width = (int)origImage.Width; int height = (int)origImage.Height; FloatMapImage criterionImage = new FloatMapImage(origImage.Width, origImage.Height, PixelFormat.Greyscale); float[, ,] sat = criterion.OriginalImageSAT.Image; int minPsfRadius = 1; int maxPsfRadius = 100; int step = 10; for (int psfRadius = minPsfRadius; psfRadius < maxPsfRadius; psfRadius += step) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { criterionImage.Image[x, y, 0] = criterion.SelectFilter(x, y, psfRadius); } } criterionImage.ToBitmap().Save(string.Format("chessRGB_criterion_{0:000}.png", psfRadius), System.Drawing.Imaging.ImageFormat.Png); } }
private void buttonSave_Click(object sender, EventArgs e) { FloatMapImage hdrImageToSave = outputHdrImage; Bitmap ldrImageToSave = outputLdrImage; if ((outputLdrImage == null) || (outputHdrImage == null)) { hdrImageToSave = inputHdrImage; ldrImageToSave = inputLdrImage; } SaveFileDialog sfd = new SaveFileDialog(); sfd.Title = "Save output file"; sfd.Filter = "PNG Files|*.png|PFM Files|*.pfm|JPEG Files|*.jpg"; sfd.AddExtension = true; sfd.FileName = ""; if (sfd.ShowDialog() != DialogResult.OK) { return; } if (sfd.FileName.EndsWith(".pfm")) { PortableFloatMap.SaveImage(hdrImageToSave, sfd.FileName); } else if (sfd.FileName.EndsWith(".png")) { ldrImageToSave.Save(sfd.FileName, System.Drawing.Imaging.ImageFormat.Png); } else if (sfd.FileName.EndsWith(".jpg")) { ldrImageToSave.Save(sfd.FileName, System.Drawing.Imaging.ImageFormat.Jpeg); } }
private void Spread() { FloatMapImage color = GetColorTexture(); FloatMapImage depth = GetDepthTexture(); spreaded = SpreadFrame(color, depth).ToBitmap(true); LoadSpreadedImageTexture(spreaded); }
public void TestCreatingSAT() { FloatMapImage origImage = ((Bitmap)Bitmap.FromFile("chessRGB.jpg")).ToFloatMap(); FloatMapImage sat = origImage.Integrate(); sat.ToBitmap(true).Save("chessRGB_sat.png", System.Drawing.Imaging.ImageFormat.Png); FloatMapImage differentiatedSat = sat.Differentiate(); differentiatedSat.ToBitmap(true).Save("chessRGB_satDiff.png", System.Drawing.Imaging.ImageFormat.Png); }
private void Splat(FloatMapImage senzor, float lightIntensity, Vector2d intersectionPixelPoint) { int x = (int)intersectionPixelPoint.X; int y = (int)intersectionPixelPoint.Y; if ((x >= 0) && (x < senzor.Width) && (y >= 0) && (y < senzor.Height)) { senzor.Image[x, y, 0] += lightIntensity; } }
private FloatMapImage CopySingleChannelDepthMap(FloatMapImage depthMap) { if (depthMap.PixelFormat == PixelFormat.Greyscale) { return((FloatMapImage)depthMap.Clone()); } else { return(depthMap.ExtractChannel(0)); } }
private void RenderImage(bool preview) { if (!initialized) { return; } rayTracer.SampleCount = (int)sampleCountNumeric.Value; rayTracer.Camera.Sensor.Width = (double)senzorWidthNumeric.Value; Cursor = Cursors.WaitCursor; Stopwatch stopwatch = Stopwatch.StartNew(); Size outputImageSize = (specificOutputSizeCheckBox.Checked) ? new Size((int)outputSizeXNumeric.Value, (int)outputSizeYNumeric.Value) : pictureBox1.Size; if (preview) { Size previewSize = new Size(outputImageSize.Width / 4, outputImageSize.Height / 4); int sampleCount = rayTracer.SampleCount; outputImage = rayTracer.RenderImagePreview(outputImageSize, new Rectangle( new Point( (outputImageSize.Width - previewSize.Width) / 2, (outputImageSize.Height - previewSize.Height) / 2), previewSize), null); rayTracer.SampleCount = 64; Size focusWindowSize = new Size(40, 40); outputImage = rayTracer.RenderImagePreview(outputImageSize, new Rectangle( new Point( (outputImageSize.Width - focusWindowSize.Width) / 2, (outputImageSize.Height - focusWindowSize.Height) / 2), focusWindowSize), outputImage); rayTracer.SampleCount = sampleCount; } else { outputImage = rayTracer.RenderImage(outputImageSize); } stopwatch.Stop(); ShowImage(); elapsedTimeToolStripStatusLabel.Text = string.Format("{0} ms", stopwatch.ElapsedMilliseconds); Cursor = Cursors.Default; }
protected override void Filter(FloatMapImage inputImage, FloatMapImage spreadingTable, FloatMapImage normalizationTable) { Spread(inputImage, spreadingTable, normalizationTable); //spreadingTable.ToBitmap(true).Save("spreading-diffs.png"); //normalizationTable.ToBitmap(true).Save("normalization-diffs.png"); IntegrateHorizontally(spreadingTable, normalizationTable); //spreadingTable.ToBitmap(true).Save("spreading-horiz.png"); //normalizationTable.ToBitmap(true).Save("normalization-horiz.png"); }
public static FloatMapImage CreateTestImage() { FloatMapImage image = new FloatMapImage(5, 7, BokehLab.FloatMap.PixelFormat.Greyscale); for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { image.Image[x, y, 0] = (x + 1) + (10 * y) + 0.5f; } } return image; }
public void TrySimpleHeightfield1x1WithPerpendicularRay() { FloatMapImage data = new FloatMapImage(1, 1, PixelFormat.Greyscale); data.Image[0, 0, 0] = 0.5f; HeightField heightfield = new HeightField(new[] { data }); Vector3 start = new Vector3(0.1f, 0.1f, 0.25f); Vector3 end = new Vector3(0.1f, 0.1f, 0.75f); IntersectAndReport(heightfield, start, end); }
public void MakeUnthresholdedCriterionImages() { FloatMapImage origImage = ((Bitmap)Bitmap.FromFile("chessRGB.jpg")).ToFloatMap(); HybridSpreadingFilter.FilterSelectionCriterion criterion = new HybridSpreadingFilter.FilterSelectionCriterion() { Threshold = CRITERION_THRESHOLD }; criterion.OriginalImage = origImage; criterion.OriginalImageSAT = origImage.Integrate(); int width = (int)origImage.Width; int height = (int)origImage.Height; FloatMapImage criterionImage = new FloatMapImage(origImage.Width, origImage.Height, PixelFormat.Greyscale); FloatMapImage diffImage = new FloatMapImage(origImage.Width, origImage.Height, PixelFormat.Greyscale); float[, ,] sat = criterion.OriginalImageSAT.Image; int minPsfRadius = 1; int maxPsfRadius = 100; int step = 10; for (int psfRadius = minPsfRadius; psfRadius < maxPsfRadius; psfRadius += step) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { float sourceIntensity = origImage.Image[x, y, 0]; int left = MathHelper.Clamp <int>(x - psfRadius - 1, 0, width - 1); int right = MathHelper.Clamp <int>(x + psfRadius, 0, width - 1); int top = MathHelper.Clamp <int>(y - psfRadius - 1, 0, height - 1); int bottom = MathHelper.Clamp <int>(y + psfRadius, 0, height - 1); float psfArea = (right - left) * (bottom - top); float psfSum = sat[right, bottom, 0] + sat[left, top, 0] - sat[left, bottom, 0] - sat[right, top, 0]; // average over neighborhood of the current pixel within the PSF radius // (except the current pixel itself) float averageOverPsf = (psfSum - sourceIntensity) / (psfArea - 1); //criterionImage.Image[x, y, 0] = (sourceIntensity > averageOverPsf) ? 1 : 0; diffImage.Image[x, y, 0] = sourceIntensity - averageOverPsf; //diffImage.Image[x, y, 0] = Math.Abs(sourceIntensity - averageOverPsf); //criterionImage.Image[x, y, 0] = criterion.SelectFilter(x, y, psfRadius); } } //criterionImage.ToBitmap().Save(string.Format("chessRGB_criterion_{0:000}.png", psfRadius), System.Drawing.Imaging.ImageFormat.Png); diffImage.ToBitmap(false).Save(string.Format("chessRGB_diff_nonabs_{0:000}.png", psfRadius), System.Drawing.Imaging.ImageFormat.Png); } }
private static void Normalize(FloatMapImage spreadingTable, FloatMapImage normalizationTable, FloatMapImage outputImage) { //Stopwatch sw = new Stopwatch(); //sw.Reset(); //sw.Start(); outputImage = spreadingTable.DivideBy(normalizationTable, outputImage, true); //normalizationTable.ToBitmap(true).Save("normalization.png"); //spreadingTable.ToBitmap(true).Save("unnormalized.png"); //Console.WriteLine("Normalizing to output image: {0} ms", sw.ElapsedMilliseconds); }
private void OpenLayerImage(string fileName) { if (fileName.EndsWith(".pfm")) { layerImage = PortableFloatMap.LoadImage(fileName); } else { Bitmap layerBitmap = (Bitmap)Bitmap.FromFile(fileName); layerImage = layerBitmap.ToFloatMap(); } rayTracer.Scene.Layer.Image = layerImage; }
private static void Composite(string fileA, string fileB, string outputFile) { FloatMapImage imageA = LoadFile(fileA); Console.WriteLine(fileA); DisplayInfo(imageA); FloatMapImage imageB = LoadFile(fileB); Console.WriteLine(fileB); DisplayInfo(imageB); SaveFile(imageA.Over(imageB), outputFile); }
public static FloatMapImage CreateTestImage() { FloatMapImage image = new FloatMapImage(5, 7, BokehLab.FloatMap.PixelFormat.Greyscale); for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { image.Image[x, y, 0] = (x + 1) + (10 * y) + 0.5f; } } return(image); }
private void clearDepthmapButton_Click(object sender, EventArgs e) { if (depthMap != null) { depthMap.Dispose(); depthMap = null; } if (imageTypeComboBox.SelectedItem.ToString() == "Depth map") { pictureBox1.Image.Dispose(); pictureBox1.Image = null; } }
private void buttonLoad_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "Open Image File"; ofd.Filter = "PNG Files|*.png" + "|PFM Files|*.pfm" + "|Bitmap Files|*.bmp" + "|Gif Files|*.gif" + "|JPEG Files|*.jpg" + "|TIFF Files|*.tif" + "|All Image types|*.png;*.pfm;*.bmp;*.gif;*.jpg;*.tif"; ofd.FilterIndex = 7; ofd.FileName = ""; if (ofd.ShowDialog() != DialogResult.OK) { return; } if (ofd.FileName.EndsWith(".pfm")) { if (inputHdrImage != null) { inputHdrImage.Dispose(); } inputHdrImage = PortableFloatMap.LoadImage(ofd.FileName); ReplaceLdrImage(ref inputLdrImage, inputHdrImage.ToBitmap(ToneMappingEnabled)); } else { ReplaceLdrImage(ref inputLdrImage, (Bitmap)Image.FromFile(ofd.FileName)); if (inputHdrImage != null) { inputHdrImage.Dispose(); } inputHdrImage = inputLdrImage.ToFloatMap(); } imageTypeComboBox.SelectedIndex = 0; // TODO: select original better updatePictureBoxImage(); if (outputHdrImage != null) { outputHdrImage.Dispose(); } outputHdrImage = null; ReplaceLdrImage(ref outputLdrImage, null); imageSizeLabel.Text = String.Format("{0}x{1}", inputHdrImage.Width, inputHdrImage.Height); }
private FloatMapImage GetBlurMap(uint width, uint height) { FloatMapImage blurMap = new FloatMapImage(width, height, PixelFormat.Greyscale); var blurMapImage = blurMap.Image; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { blurMapImage[x, y, 0] = Blur.GetPSFRadius(x, y); } } return(blurMap); }
protected void Spread(FloatMapImage inputImage, FloatMapImage spreadingTable, FloatMapImage normalizationTable) { //Stopwatch sw = new Stopwatch(); //sw.Reset(); //sw.Start(); uint bands = inputImage.TotalChannelsCount; uint width = inputImage.Width; uint height = inputImage.Height; float[, ,] origImage = inputImage.Image; float[, ,] spreadingImage = spreadingTable.Image; float[, ,] normalizationImage = normalizationTable.Image; int tableWidth = (int)spreadingTable.Width; int tableHeight = (int)spreadingTable.Height; if (SpreadOneRoundedPSF) { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { float radius = Blur.GetPSFRadius(x, y); SpreadPSF(x, y, (int)radius, 1.0f, origImage, spreadingImage, normalizationImage, tableWidth, tableHeight, bands); } } } else { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { float radius = Blur.GetPSFRadius(x, y); // spread PSFs of a non-integer radius using two weighted // PSFs of integer size close to the original radius int smallerRadius = (int)radius; int biggerRadius = smallerRadius + 1; float weight = biggerRadius - radius; SpreadPSF(x, y, smallerRadius, weight, origImage, spreadingImage, normalizationImage, tableWidth, tableHeight, bands); SpreadPSF(x, y, biggerRadius, 1 - weight, origImage, spreadingImage, normalizationImage, tableWidth, tableHeight, bands); } } } //Console.WriteLine("Phase 1, spreading: {0} ms", sw.ElapsedMilliseconds); }
private static void SaveFile(FloatMapImage image, string filename) { if (filename.ToLower().EndsWith(".pfm")) { image.SaveImage(filename); } else if (filename.ToLower().EndsWith(".png")) { image.ToBitmap().Save(filename, ImageFormat.Png); } else { throw new ArgumentException(String.Format("Unknown file format: {0}", filename)); } }
public void TrySimpleHeightfield2x2() { FloatMapImage data = new FloatMapImage(2, 2, PixelFormat.Greyscale); data.Image[0, 0, 0] = 0.5f; data.Image[0, 1, 0] = 0.5f; data.Image[1, 0, 0] = 0.5f; data.Image[1, 1, 0] = 0.5f; HeightField heightfield = new HeightField(new[] { data }); Vector3 start = new Vector3(0.5f, 1.5f, 0.0f); Vector3 end = new Vector3(2, 2, 1); IntersectAndReport(heightfield, start, end); }
protected override void Filter(FloatMapImage inputImage, FloatMapImage spreadingTable, FloatMapImage normalizationTable) { criterion.OriginalImage = inputImage; criterion.OriginalImageSAT = inputImage.Integrate(); // spread rectangles activeFilterIndex = 0; Spread(inputImage, spreadingTable, normalizationTable); IntegrateVertically(spreadingTable, normalizationTable); // spread perimeter PSFs activeFilterIndex = 1; Spread(inputImage, spreadingTable, normalizationTable); IntegrateHorizontally(spreadingTable, normalizationTable); }
private BlurMap CreateBlurFunction(FloatMapImage depthMap) { BlurMap blur; if (depthMap != null) { thinLensBlur.DepthMap = depthMap; blur = thinLensBlur; } else { int maxBlurRadius = (int)blurRadiusNumeric.Value; blur = new ConstantBlur(maxBlurRadius - 1); } return(blur); }
private static void ReadAndWriteTestImage(string filename) { Console.WriteLine("Writing a test image."); FloatMapImage image = CreateTestImage(); DisplayInfo(image); PrintImageContents(image); PortableFloatMap.SaveImage(image, filename); Console.WriteLine(); Console.WriteLine("Reading a test image."); FloatMapImage loadedImage = PortableFloatMap.LoadImage(filename); DisplayInfo(loadedImage); PrintImageContents(loadedImage); }
private static void ReadAndWriteExistingImage(string filename) { Console.WriteLine("Reading an existing image."); FloatMapImage image = PortableFloatMap.LoadImage(filename); DisplayInfo(image); Console.WriteLine(); Console.WriteLine("Writing a copy of an existing image."); string copyFilename = filename + ".out"; PortableFloatMap.SaveImage(image, copyFilename); Console.WriteLine("Reading a copy of an existing image."); FloatMapImage loadedImage = PortableFloatMap.LoadImage(copyFilename); DisplayInfo(loadedImage); }
private FloatMapImage GetColorTexture() { // pixel format: unsinged int //Bitmap bmp = new Bitmap(TextureSize.Width, TextureSize.Height); //System.Drawing.Imaging.BitmapData data = // bmp.LockBits(new System.Drawing.Rectangle(0, 0, TextureSize.Width, TextureSize.Height), // System.Drawing.Imaging.ImageLockMode.WriteOnly, // System.Drawing.Imaging.PixelFormat.Format24bppRgb); //GL.BindTexture(TextureTarget.Texture2D, ColorTexture); //GL.GetTexImage(TextureTarget.Texture2D, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgr, PixelType.UnsignedByte, data.Scan0); //GL.BindTexture(TextureTarget.Texture2D, 0); //bmp.UnlockBits(data); ////bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); //return bmp.ToFloatMap(); int bands = 3; // RGB IntPtr colorTextureFloatPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(float)) * bands * TextureSize.Width * TextureSize.Height); GL.BindTexture(TextureTarget.Texture2D, ColorTexture); GL.GetTexImage(TextureTarget.Texture2D, 0, OpenTK.Graphics.OpenGL.PixelFormat.Rgb, PixelType.Float, colorTextureFloatPtr); GL.BindTexture(TextureTarget.Texture2D, 0); FloatMapImage colorImage = new FloatMapImage((uint)TextureSize.Width, (uint)TextureSize.Height, BokehLab.FloatMap.PixelFormat.RGB); var image = colorImage.Image; unsafe { int inputStride = bands * TextureSize.Width; for (int y = 0; y < TextureSize.Height; y++) { float *inputRow = (float *)colorTextureFloatPtr + (y * inputStride); int xIndex = 0; for (int x = 0; x < TextureSize.Width; x++) { for (int band = 0; band < bands; band++) { image[x, y, band] = inputRow[xIndex]; xIndex++; } } } } return(colorImage); }
private static void PrintImageContents(FloatMapImage image) { for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { Console.Write("["); for (int band = 0; band < image.ColorChannelsCount; band++) { Console.Write("{0}", String.Format(CultureInfo.CreateSpecificCulture("en-US"), "{0}", image.Image[x, y, band])); if (band < image.ColorChannelsCount - 1) { Console.Write(", "); } } Console.Write("]"); if (x < image.Width - 1) { Console.Write(", "); } } Console.WriteLine(); } }