Cleaned up main
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMonitor_002ECoreCLR_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fmm00_003F_002Econfig_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F8056cd3f452fefb9834f05cdb275b762dd41f27b7766cd71174e78592dc495b_003FMonitor_002ECoreCLR_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APixelTypeInfo_002Ecs_002Fl_003AC_0021_003FUsers_003Fairon_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fc3cfdca1fb93eb6df5e51a81da5df646adfab8b862fd1a07ee5d247b49c5179_003FPixelTypeInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASafeFileHandle_002EUnix_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fmm00_003F_002Econfig_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F9cf5f68d759deefc91b9c48c5ac3dd27708bb7dc38d0c485661fff5ce15b82_003FSafeFileHandle_002EUnix_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASafeFileHandle_002EWindows_002Ecs_002Fl_003AC_0021_003FUsers_003Fairon_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F261ea83c988816e3d8fe76b15b7ac6c10af64b8f9e739854f83c137c8ba9_003FSafeFileHandle_002EWindows_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003AC_0021_003FUsers_003Fairon_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F2c8e7ca976f350cba9836d5565dac56b11e0b56656fa786460eb1395857a6fa_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AVector3_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fmm00_003F_002Econfig_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F6edafe13d8727aa238b865f5dc91dbc984b5abfbc60bece3744f6311c2c_003FVector3_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue"><AssemblyExplorer>
|
||||
|
||||
@@ -7,9 +7,7 @@ public class Program {
|
||||
private const float MAX = 1f;
|
||||
private const float MIN = 0f;
|
||||
private static readonly int MAX_THREADS = Environment.ProcessorCount - 2;
|
||||
private const bool outputMasks = true;
|
||||
private const bool outputSDFs = true;
|
||||
private const bool outputGradients = true;
|
||||
private static bool debug = true;
|
||||
static readonly ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = MAX_THREADS };
|
||||
static List<Image> Images = new();
|
||||
static List<MaskData> ImageMasks = new();
|
||||
@@ -25,14 +23,17 @@ public class Program {
|
||||
public static void Main(string[] args) {
|
||||
Console.WriteLine("Reading images...");
|
||||
|
||||
/*
|
||||
if(debug) {
|
||||
if (!Directory.Exists("Debug")) Directory.CreateDirectory("Debug");
|
||||
Console.WriteLine("Debug mode enabled.");
|
||||
}
|
||||
|
||||
var imagesPath = "images";
|
||||
for (int i = 0; i < 8; i++) {
|
||||
var pixels = ImageUtil.LoadImage<Vector3>($"./{imagesPath}{Path.DirectorySeparatorChar}{i + 1:00}.png");
|
||||
Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1)));
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
var pixels = ImageUtil.LoadImage<Vector3>($"./sphereempty.png");
|
||||
Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1)));
|
||||
pixels = ImageUtil.LoadImage<Vector3>($"./spherehalf.png");
|
||||
@@ -41,6 +42,7 @@ public class Program {
|
||||
Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1)));
|
||||
pixels = ImageUtil.LoadImage<Vector3>($"./spherefull.png");
|
||||
Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1)));
|
||||
*/
|
||||
|
||||
//check if all the images in Images are the same resolution
|
||||
if (Images.Select(img => (img.Width, img.Height)).Distinct().Count() > 1) {
|
||||
@@ -48,52 +50,42 @@ public class Program {
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
for (int i = 1; i < Images.Count; i++) {
|
||||
for (int x = 0; x < Images[i].Width; x++) {
|
||||
for (int y = 0; y < Images[i].Height; y++) {
|
||||
Images[i].Pixels[x, y].X = MathF.Min(Images[i - 1].Pixels[x, y].X + Images[i].Pixels[x, y].X, MAX);
|
||||
Images[i].Pixels[x, y].Y = MathF.Min(Images[i - 1].Pixels[x, y].Y + Images[i].Pixels[x, y].X, MAX);
|
||||
Images[i].Pixels[x, y].Z = MathF.Min(Images[i - 1].Pixels[x, y].Z + Images[i].Pixels[x, y].X, MAX);
|
||||
}
|
||||
}
|
||||
Images[i].Pixels.SaveImage($"./Sum{i}.png");
|
||||
}
|
||||
|
||||
Console.WriteLine("Creating masks...");
|
||||
//for each image pair, create a mask
|
||||
width = (uint)Images[0].Width;
|
||||
height = (uint)Images[0].Height;
|
||||
for (int i = 0; i < Images.Count; i++) {
|
||||
ImageMasks.Add(new(SelfMask(Images[i].Pixels, width, height), Images[i], new()));
|
||||
if (i < Images.Count - 1) {
|
||||
Console.WriteLine($"Creating mask {i}...");
|
||||
var mask = GetABMask(Images[i].Pixels, Images[i + 1].Pixels, width, height);
|
||||
|
||||
Console.WriteLine("Creating masks...");
|
||||
for (int i = 0; i < Images.Count; i++) { //for each image pair, create a mask
|
||||
var selfMask = SelfMask(Images[i].Pixels);
|
||||
ImageMasks.Add(new(selfMask, Images[i], new()));
|
||||
if (debug) selfMask.SaveImage($"Debug/selfMask{i}.png");
|
||||
if (i >= Images.Count - 1) continue;
|
||||
ConsoleUpdateLine($"Creating mask {i}...");
|
||||
var mask = GetABMask(Images[i].Pixels, Images[i + 1].Pixels);
|
||||
TransitionMasks.Add(new(mask, Images[i], Images[i + 1]));
|
||||
}
|
||||
if (debug) mask.SaveImage($"Debug/mask{i}.png");
|
||||
}
|
||||
|
||||
Console.WriteLine("Edge detecting masks...");
|
||||
//EdgeDetect all masks
|
||||
foreach (var t in ImageMasks) EdgeDetect(t);
|
||||
|
||||
if (outputMasks) {
|
||||
Console.WriteLine("Writing masks...");
|
||||
for (int i = 0; i < TransitionMasks.Count; i++) ImageMasks[i].Mask.SaveImage($"mask{i}.png");
|
||||
Console.WriteLine("\nEdge detecting masks...");
|
||||
foreach (var mask in ImageMasks) {
|
||||
ConsoleUpdateLine($"Edge detecting mask {ImageMasks.IndexOf(mask)}...");
|
||||
EdgeDetect(mask);
|
||||
}
|
||||
if (debug) for (int i = 0; i < TransitionMasks.Count; i++) ImageMasks[i].Mask.SaveImage($"Debug/mask{i}.png");
|
||||
|
||||
Console.WriteLine("Creating SDFs...");
|
||||
for (var i = 0; i < ImageMasks.Count; i++) {
|
||||
var mask = ImageMasks[i];
|
||||
SDFs.Add(SDF(mask));
|
||||
if (outputSDFs) SDFs[i].SDF.SaveImage($"sdf{i}.png");
|
||||
if (debug) SDFs[i].SDF.SaveImage($"Debug/sdf{i}.png");
|
||||
}
|
||||
|
||||
Console.WriteLine("Creating gradients...");
|
||||
for (var i = 0; i < TransitionMasks.Count; i++) {
|
||||
Console.WriteLine($"Generating gradient {i}...");
|
||||
ConsoleUpdateLine($"Generating gradient {i}...");
|
||||
var gradientData = Gradient(TransitionMasks[i], SDFs[i], SDFs[i + 1]);
|
||||
Gradients.Add(gradientData);
|
||||
if (outputGradients) gradientData.SaveImage($"gradient{i}.png");
|
||||
if (debug) gradientData.SaveImage($"Debug/gradient{i}.png");
|
||||
}
|
||||
|
||||
// generate final image
|
||||
@@ -124,8 +116,6 @@ public class Program {
|
||||
}
|
||||
|
||||
private static void EdgeDetect(MaskData maskData) {
|
||||
uint width = (uint)maskData.Image.Width;
|
||||
uint height = (uint)maskData.Image.Height;
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
Console.WriteLine("Running edge detection...");
|
||||
@@ -143,8 +133,6 @@ public class Program {
|
||||
}
|
||||
|
||||
static Vector3[,] Gradient(TransitionMaskData mask, SDFData sdfA, SDFData sdfB) {
|
||||
uint width = (uint)mask.ImageA.Width;
|
||||
uint height = (uint)mask.ImageA.Height;
|
||||
int iterCount = 0;
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
@@ -179,43 +167,13 @@ public class Program {
|
||||
}
|
||||
|
||||
static SDFData SDF(MaskData mask) {
|
||||
var width = (uint)mask.Mask.GetLength(0);
|
||||
var height = (uint)mask.Mask.GetLength(1);
|
||||
float AbsMax = MIN;
|
||||
int iterCount = 0;
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
/*Parallel.For(0, width * height, parallelOptions, (i) =>
|
||||
{
|
||||
//convert 1D index to 2D index
|
||||
var x = (int)(i % width);
|
||||
var y = (int)(i / width);
|
||||
Vector2 p = new(x / (float)width, y / (float)height); //get the pixel position as a Vector2
|
||||
|
||||
float minDist = MAX + 1; //initialize the minimum distance to the maximum possible value
|
||||
|
||||
//loop through all the pixels in the mask
|
||||
foreach (var edge in mask.Edges) {
|
||||
Vector2 edgeNorm = new(edge.X / (float)width, edge.Y / (float)height);
|
||||
float dist = Vector2.DistanceSquared(p, edgeNorm);
|
||||
if (dist < minDist) minDist = dist;
|
||||
}
|
||||
|
||||
if (minDist > MAX)
|
||||
minDist = MAX;
|
||||
|
||||
temp[x, y] = new(minDist);
|
||||
if (minDist > AbsMax) AbsMax = minDist;
|
||||
iterCount++;
|
||||
if (iterCount % (width * height / 100) == 0) {
|
||||
ConsoleUpdateLine(
|
||||
$"Progress: {iterCount / (float)(width * height):P}% | {iterCount / (sw.Elapsed.TotalSeconds):N0} pixels/s");
|
||||
}
|
||||
});*/
|
||||
kernels.Sdf(mask.Edges.ToArray(), (int)width, (int)height, out var temp);
|
||||
|
||||
Console.WriteLine(
|
||||
$"\nSDF Generation Time: {sw.Elapsed.TotalSeconds:N4}s ({iterCount / sw.Elapsed.TotalSeconds:N0} pixels/s)");
|
||||
Console.WriteLine($"\nSDF Generation Time: {sw.Elapsed.TotalSeconds:N4}s ({iterCount / sw.Elapsed.TotalSeconds:N0} pixels/s)");
|
||||
|
||||
return new(temp);
|
||||
}
|
||||
@@ -224,12 +182,12 @@ public class Program {
|
||||
private static float EuclideanDistance(Vector2 a, Vector2 b) =>
|
||||
MathF.Sqrt(MathF.Pow(a.X - b.X, 2) + MathF.Pow(a.Y - b.Y, 2));
|
||||
|
||||
static Vector3[,] GetABMask(Vector3[,] A, Vector3[,] B, uint resX, uint resY) {
|
||||
static Vector3[,] GetABMask(Vector3[,] A, Vector3[,] B) {
|
||||
kernels.ABMask(A, B, out var temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
static Vector3[,] SelfMask(Vector3[,] A, uint resX, uint resY) {
|
||||
static Vector3[,] SelfMask(Vector3[,] A) {
|
||||
kernels.SelfMask(A, out var temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
@@ -25,11 +25,13 @@ public partial class SdfKernels {
|
||||
using Accelerator accelerator = device.CreateAccelerator(gpuContext);
|
||||
Console.WriteLine($"{GetInfoString(accelerator)}");
|
||||
}
|
||||
|
||||
Console.WriteLine("Reading available accelerators (OpenCL only)...");
|
||||
foreach (var device in gpuContext.GetCLDevices()) {
|
||||
using Accelerator accelerator = device.CreateAccelerator(gpuContext);
|
||||
Console.WriteLine($"{GetInfoString(accelerator)}");
|
||||
}
|
||||
|
||||
Console.WriteLine("Reading available accelerators (CPU only)...");
|
||||
foreach (var device in gpuContext.GetCPUDevices()) {
|
||||
using Accelerator accelerator = device.CreateAccelerator(gpuContext);
|
||||
@@ -128,7 +130,7 @@ public partial class SdfKernels {
|
||||
sdf = buffer.GetAsArray2D();
|
||||
}
|
||||
|
||||
public void Gradient(ref Vector3[,] mask, ref Vector3[,] sdfa, ref Vector3[,] sdfb, out Vector3[,] gradient) {
|
||||
public void Gradient(Vector3[,] mask, Vector3[,] sdfa, Vector3[,] sdfb, out Vector3[,] gradient) {
|
||||
var dev = gpuContext.GetPreferredDevice(preferCPU:false);
|
||||
int width = mask.GetLength(0);
|
||||
int height = mask.GetLength(1);
|
||||
|
||||
Reference in New Issue
Block a user