Cleaned up main

This commit is contained in:
Samuele Lorefice
2025-04-03 18:38:56 +02:00
parent db54b80b5a
commit 3b319da80b
3 changed files with 38 additions and 77 deletions

View File

@@ -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_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_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_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_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/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">&lt;AssemblyExplorer&gt; <s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue">&lt;AssemblyExplorer&gt;

View File

@@ -7,9 +7,7 @@ public class Program {
private const float MAX = 1f; private const float MAX = 1f;
private const float MIN = 0f; private const float MIN = 0f;
private static readonly int MAX_THREADS = Environment.ProcessorCount - 2; private static readonly int MAX_THREADS = Environment.ProcessorCount - 2;
private const bool outputMasks = true; private static bool debug = true;
private const bool outputSDFs = true;
private const bool outputGradients = true;
static readonly ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = MAX_THREADS }; static readonly ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = MAX_THREADS };
static List<Image> Images = new(); static List<Image> Images = new();
static List<MaskData> ImageMasks = new(); static List<MaskData> ImageMasks = new();
@@ -24,15 +22,18 @@ public class Program {
public static void Main(string[] args) { public static void Main(string[] args) {
Console.WriteLine("Reading images..."); Console.WriteLine("Reading images...");
/* if(debug) {
if (!Directory.Exists("Debug")) Directory.CreateDirectory("Debug");
Console.WriteLine("Debug mode enabled.");
}
var imagesPath = "images"; var imagesPath = "images";
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
var pixels = ImageUtil.LoadImage<Vector3>($"./{imagesPath}{Path.DirectorySeparatorChar}{i + 1:00}.png"); var pixels = ImageUtil.LoadImage<Vector3>($"./{imagesPath}{Path.DirectorySeparatorChar}{i + 1:00}.png");
Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1))); Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1)));
} }
*/ /*
var pixels = ImageUtil.LoadImage<Vector3>($"./sphereempty.png"); var pixels = ImageUtil.LoadImage<Vector3>($"./sphereempty.png");
Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1))); Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1)));
pixels = ImageUtil.LoadImage<Vector3>($"./spherehalf.png"); pixels = ImageUtil.LoadImage<Vector3>($"./spherehalf.png");
@@ -41,59 +42,50 @@ public class Program {
Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1))); Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1)));
pixels = ImageUtil.LoadImage<Vector3>($"./spherefull.png"); pixels = ImageUtil.LoadImage<Vector3>($"./spherefull.png");
Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1))); Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1)));
*/
//check if all the images in Images are the same resolution //check if all the images in Images are the same resolution
if (Images.Select(img => (img.Width, img.Height)).Distinct().Count() > 1) { if (Images.Select(img => (img.Width, img.Height)).Distinct().Count() > 1) {
Console.WriteLine("Error: Not all images have the same resolution."); Console.WriteLine("Error: Not all images have the same resolution.");
Environment.Exit(1); 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; width = (uint)Images[0].Width;
height = (uint)Images[0].Height; 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())); Console.WriteLine("Creating masks...");
if (i < Images.Count - 1) { for (int i = 0; i < Images.Count; i++) { //for each image pair, create a mask
Console.WriteLine($"Creating mask {i}..."); var selfMask = SelfMask(Images[i].Pixels);
var mask = GetABMask(Images[i].Pixels, Images[i + 1].Pixels, width, height); ImageMasks.Add(new(selfMask, Images[i], new()));
TransitionMasks.Add(new(mask, Images[i], Images[i + 1])); 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 //EdgeDetect all masks
foreach (var t in ImageMasks) EdgeDetect(t); Console.WriteLine("\nEdge detecting masks...");
foreach (var mask in ImageMasks) {
if (outputMasks) { ConsoleUpdateLine($"Edge detecting mask {ImageMasks.IndexOf(mask)}...");
Console.WriteLine("Writing masks..."); EdgeDetect(mask);
for (int i = 0; i < TransitionMasks.Count; i++) ImageMasks[i].Mask.SaveImage($"mask{i}.png");
} }
if (debug) for (int i = 0; i < TransitionMasks.Count; i++) ImageMasks[i].Mask.SaveImage($"Debug/mask{i}.png");
Console.WriteLine("Creating SDFs..."); Console.WriteLine("Creating SDFs...");
for (var i = 0; i < ImageMasks.Count; i++) { for (var i = 0; i < ImageMasks.Count; i++) {
var mask = ImageMasks[i]; var mask = ImageMasks[i];
SDFs.Add(SDF(mask)); 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..."); Console.WriteLine("Creating gradients...");
for (var i = 0; i < TransitionMasks.Count; i++) { 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]); var gradientData = Gradient(TransitionMasks[i], SDFs[i], SDFs[i + 1]);
Gradients.Add(gradientData); Gradients.Add(gradientData);
if (outputGradients) gradientData.SaveImage($"gradient{i}.png"); if (debug) gradientData.SaveImage($"Debug/gradient{i}.png");
} }
// generate final image // generate final image
@@ -124,8 +116,6 @@ public class Program {
} }
private static void EdgeDetect(MaskData maskData) { private static void EdgeDetect(MaskData maskData) {
uint width = (uint)maskData.Image.Width;
uint height = (uint)maskData.Image.Height;
var sw = new Stopwatch(); var sw = new Stopwatch();
sw.Start(); sw.Start();
Console.WriteLine("Running edge detection..."); Console.WriteLine("Running edge detection...");
@@ -143,8 +133,6 @@ public class Program {
} }
static Vector3[,] Gradient(TransitionMaskData mask, SDFData sdfA, SDFData sdfB) { static Vector3[,] Gradient(TransitionMaskData mask, SDFData sdfA, SDFData sdfB) {
uint width = (uint)mask.ImageA.Width;
uint height = (uint)mask.ImageA.Height;
int iterCount = 0; int iterCount = 0;
var sw = new Stopwatch(); var sw = new Stopwatch();
sw.Start(); sw.Start();
@@ -179,43 +167,13 @@ public class Program {
} }
static SDFData SDF(MaskData mask) { 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; int iterCount = 0;
var sw = new Stopwatch(); var sw = new Stopwatch();
sw.Start(); 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); kernels.Sdf(mask.Edges.ToArray(), (int)width, (int)height, out var temp);
Console.WriteLine( Console.WriteLine($"\nSDF Generation Time: {sw.Elapsed.TotalSeconds:N4}s ({iterCount / sw.Elapsed.TotalSeconds:N0} pixels/s)");
$"\nSDF Generation Time: {sw.Elapsed.TotalSeconds:N4}s ({iterCount / sw.Elapsed.TotalSeconds:N0} pixels/s)");
return new(temp); return new(temp);
} }
@@ -224,12 +182,12 @@ public class Program {
private static float EuclideanDistance(Vector2 a, Vector2 b) => private static float EuclideanDistance(Vector2 a, Vector2 b) =>
MathF.Sqrt(MathF.Pow(a.X - b.X, 2) + MathF.Pow(a.Y - b.Y, 2)); 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); kernels.ABMask(A, B, out var temp);
return temp; return temp;
} }
static Vector3[,] SelfMask(Vector3[,] A, uint resX, uint resY) { static Vector3[,] SelfMask(Vector3[,] A) {
kernels.SelfMask(A, out var temp); kernels.SelfMask(A, out var temp);
return temp; return temp;
} }

View File

@@ -25,11 +25,13 @@ public partial class SdfKernels {
using Accelerator accelerator = device.CreateAccelerator(gpuContext); using Accelerator accelerator = device.CreateAccelerator(gpuContext);
Console.WriteLine($"{GetInfoString(accelerator)}"); Console.WriteLine($"{GetInfoString(accelerator)}");
} }
Console.WriteLine("Reading available accelerators (OpenCL only)..."); Console.WriteLine("Reading available accelerators (OpenCL only)...");
foreach (var device in gpuContext.GetCLDevices()) { foreach (var device in gpuContext.GetCLDevices()) {
using Accelerator accelerator = device.CreateAccelerator(gpuContext); using Accelerator accelerator = device.CreateAccelerator(gpuContext);
Console.WriteLine($"{GetInfoString(accelerator)}"); Console.WriteLine($"{GetInfoString(accelerator)}");
} }
Console.WriteLine("Reading available accelerators (CPU only)..."); Console.WriteLine("Reading available accelerators (CPU only)...");
foreach (var device in gpuContext.GetCPUDevices()) { foreach (var device in gpuContext.GetCPUDevices()) {
using Accelerator accelerator = device.CreateAccelerator(gpuContext); using Accelerator accelerator = device.CreateAccelerator(gpuContext);
@@ -128,7 +130,7 @@ public partial class SdfKernels {
sdf = buffer.GetAsArray2D(); 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); var dev = gpuContext.GetPreferredDevice(preferCPU:false);
int width = mask.GetLength(0); int width = mask.GetLength(0);
int height = mask.GetLength(1); int height = mask.GetLength(1);