graphics recognition

Permabanned
Joined
23 Apr 2014
Posts
23,553
Location
Hertfordshire
Parse the "SourceFolder" for all .png files(might be a different format?) and output 2 column result to excel file ParsedImages.xlsx in same folder.

Filename, distance

Code:
using ClosedXML.Excel;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;

namespace ImageProcessor
{
    class Program
    {
        private static string SourceFolder = @"C:\TempPath";

        private class PixelData
        {
            public int x { get; set; }
            public int y { get; set; }
            public Color pixel { get; set; }
        }

        static void Main(string[] args)
        {
            ParseFolder();

        }


        static void ParseFolder()
        {
            DirectoryInfo d = new DirectoryInfo(SourceFolder);
            FileInfo[] Files = d.GetFiles("*.png");
            double distance;
            int row = 1;
            using (var workbook = new XLWorkbook())
            {
                var worksheet = workbook.Worksheets.Add("Parsed Images");

                foreach (FileInfo file in Files)
                {
                    distance = ParseImage(file.Name);
                    worksheet.Cell($"A{row}").Value = file.Name;
                    worksheet.Cell($"B{row}").Value = distance;
                    row++;
                }
                workbook.SaveAs($"{SourceFolder}\\ParsedImages.xlsx");
            }
        }

        static double ParseImage(string fileName)
        {
            double distance;
            List<PixelData> data = new List<PixelData>();

            Bitmap img = new Bitmap($"{SourceFolder}\\{fileName}");
            for (int x = 0; x < img.Width; x++)
            {
                for (int y = 0; y < img.Height; y++)
                {
                    Color pixel = img.GetPixel(x, y);

                    var newDataPoint = new PixelData
                    {
                        x = x,
                        y = y,
                        pixel = pixel
                    };
                    data.Add(newDataPoint);
                }
            }

            var allWhitePixels = data.Where(d => d.pixel.A == 255 && d.pixel.B == 255 && d.pixel.G == 255).OrderBy(d => d.x);
            if (allWhitePixels.Count() > 0)
            {
                Point left = new Point(allWhitePixels.FirstOrDefault().x, allWhitePixels.FirstOrDefault().y);
                Point right = new Point(allWhitePixels.LastOrDefault().x, allWhitePixels.LastOrDefault().y);
                distance = Math.Sqrt(Math.Pow(right.X - left.X, 2) + Math.Pow(right.Y - left.Y, 2));
                Console.WriteLine($"Parsing:{fileName}:distance:{distance}");
            }
            else
            {
                Console.WriteLine($"Parsing Failed:{fileName}");
                distance = 0;
            }

            return distance;
           
        }
    }
}
 
Soldato
Joined
28 Oct 2006
Posts
12,456
Location
Sufferlandria
That's a nice solution.
You could maybe make it a little more efficient by not adding the black pixels to the list:

Code:
using ClosedXML.Excel;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;

namespace ImageProcessor
{
   class Program
    {
        private static string SourceFolder = @"C:\TempPath";

        private class PixelData
        {
            public int x { get; set; }
            public int y { get; set; }
        }

        static void Main(string[] args)
        {
            ParseFolder();
        }

        static void ParseFolder()
        {
            DirectoryInfo d = new DirectoryInfo(SourceFolder);
            FileInfo[] Files = d.GetFiles("*.png");
            double distance;
            int row = 1;
            using (var workbook = new XLWorkbook())
            {
                var worksheet = workbook.Worksheets.Add("Parsed Images");

                foreach (FileInfo file in Files)
                {
                    distance = ParseImage(file.Name);
                    worksheet.Cell($"A{row}").Value = file.Name;
                    worksheet.Cell($"B{row}").Value = distance;
                    row++;
                }
                workbook.SaveAs($"{SourceFolder}\\ParsedImages.xlsx");
            }
        }

        static double ParseImage(string fileName)
        {
            double distance;
            List<PixelData> data = new List<PixelData>();

            Bitmap img = new Bitmap($"{SourceFolder}\\{fileName}");
            for (int x = 0; x < img.Width; x++)
            {
                for (int y = 0; y < img.Height; y++)
                {
                    Color pixel = img.GetPixel(x, y);
                    if(pixel.A == 255 && pixel.B == 255 && pixel.G == 255)
                    {
                       var newDataPoint = new PixelData
                       {
                           x = x,
                           y = y
                       };
                       data.Add(newDataPoint);
                    }
                }
            }

            var allWhitePixels = data.OrderBy(d => d.x);
            if (allWhitePixels.Count() > 0)
            {
                Point left = new Point(allWhitePixels.FirstOrDefault().x, allWhitePixels.FirstOrDefault().y);
                Point right = new Point(allWhitePixels.LastOrDefault().x, allWhitePixels.LastOrDefault().y);
                distance = Math.Sqrt(Math.Pow(right.X - left.X, 2) + Math.Pow(right.Y - left.Y, 2));
                Console.WriteLine($"Parsing:{fileName}:distance:{distance}");
            }
            else
            {
                Console.WriteLine($"Parsing Failed:{fileName}");
                distance = 0;
            }

            return distance;
           
        }
    }
}
 
Soldato
OP
Joined
18 Oct 2012
Posts
8,333
Yeah I left them in in case I wanted to use them but didnt in the end.

Could use a load more images to actually test properly but I expect you could filter out any extreme anomalies in excel anyway.

how many you need? i have thousands :p

the single one i posted is the crack at full opening but the progression goes from a black screen with nothing through to that:

6vuZR6T.png
N1IZXW9.png
Wnb2ALb.png
a9DYf83.png

thats ~every 1k images in a series of 4000.

the crack does jump inside the space of a frame, but hopefully that should line up nicely with the load data from the machine (both the camera and the machine were running the same sampling rate)

fortunately these are very rough samples so i can figure out this analysis before using my good peices, so i should hopefully will be able to tweak the sample preperation and camera settings to get some better images.
 
Soldato
OP
Joined
18 Oct 2012
Posts
8,333
6vuZR6T.png 0
N1IZXW9.png 38.20995
Wnb2ALb.png 114.3547
a9DYf83.png 572.0428

Is spot on from those 4 samples at least. :p

good to know.

i'm currently running it on the full batch, seems to be doing fine at the moment.

currently pretty excited to see how it turns out (yes i'm a massive nerd :p )

edit:

came out beautifully, there's a lot of noise in the chart but that's to be expected as the camera is barely picking up the crack edge but it seems to be doing exactly what the doctor ordered:

j5AGSrC.png

should be able to do a bit of smoothing on that, and some better image capture for future runs.

many thanks guys, this has been a great help!
 
Last edited:
Soldato
OP
Joined
18 Oct 2012
Posts
8,333
so bit of an update to this.

for some reason it seems it doesn't want to run the code any more.

after some messing around i figured out how to fix the missing closedxml reference by installing the nuget closedxml add-in.

but now it's coming up with:
Code:
Error    CS0246    The type or namespace name 'Color' could not be found (are you missing a using directive or an assembly reference?)    ConsoleApp8    C:\Users\wmose\source\repos\ConsoleApp8\Program.cs    18    N/A

any idea what's up?
 
Soldato
OP
Joined
18 Oct 2012
Posts
8,333
ok, so the process as i've been doing so far:

new project in console app.net framework using default settings

paste code

under references- manage nuget packages, search closedxml and install the first one on the list:
Bhgs7bI.png

which after running build solution gives me this:
6zJZupE.png
 
Permabanned
Joined
23 Apr 2014
Posts
23,553
Location
Hertfordshire
Have you got all the code there. Says "Distance" declared but not used, which is not correct.

static double ParseImage(string fileName)
{
double distance;
List<PixelData> data = new List<PixelData>();

Bitmap img = new Bitmap($"{SourceFolder}\\{fileName}");
for (int x = 0; x < img.Width; x++)
{
for (int y = 0; y < img.Height; y++)
{
Color pixel = img.GetPixel(x, y);

var newDataPoint = new PixelData
{
x = x,
y = y,
pixel = pixel
};
data.Add(newDataPoint);
}
}

var allWhitePixels = data.Where(d => d.pixel.A == 255 && d.pixel.B == 255 && d.pixel.G == 255).OrderBy(d => d.x);
if (allWhitePixels.Count() > 0)
{
Point left = new Point(allWhitePixels.FirstOrDefault().x, allWhitePixels.FirstOrDefault().y);
Point right = new Point(allWhitePixels.LastOrDefault().x, allWhitePixels.LastOrDefault().y);
distance = Math.Sqrt(Math.Pow(right.X - left.X, 2) + Math.Pow(right.Y - left.Y, 2));
Console.WriteLine($"Parsing:{fileName}:distance:{distance}");
}
else
{
Console.WriteLine($"Parsing Failed:{fileName}");
distance = 0;
}

return distance;

}
 
Soldato
OP
Joined
18 Oct 2012
Posts
8,333
you are indeed correct, apprently a chunk was missing. that's cleared up the errors.

when running it came up with "code exited with code 0" which i *think* is because the folder's images were .bmp rather than .png.

tried changing the format to .bmp and now it's doing something. saying parsing failed for the early images which i'm guessing is because they contain no white pixels.
 
Soldato
OP
Joined
18 Oct 2012
Posts
8,333
yeah it seems to be running fine with .bmp's, the output is pure black and white.

it seems to return 0 for the failed data points with no crack, which is perfect.

now all i need to do is run it on all the folders.
 
Back
Top Bottom