ChiSquaredImageComparison.cs

Chi Squared Image Comparison (Work In Progress)

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
public class ChiSquaredImageComparison
{
private readonly int[] _expectedHistogram = new int[256];
private readonly ConcurrentDictionary<string, float> _finalDistList = new ConcurrentDictionary<string, float>();
private ConcurrentDictionary<string, int[]> _observedHistograms = new ConcurrentDictionary<string, int[]>();
private volatile float c, p, t, s1, s2;
private volatile int ExpectedLength;
private volatile int ExpectedMetric;
private volatile int XYExpectedLength;
public void SetExpectedHistogram(string path)
{
try
{
using (var org = new Bitmap(path))
{
using (var img = new MemoryBitmap(org))
{
XYExpectedLength = img.Height * img.Width;
for (var y = 0; y < img.Height; y++)
for (var x = 0; x < img.Width; x++)
{
var pixel = img.GetPixel(x, y);
_expectedHistogram[(pixel.R + pixel.G + pixel.B) / 3]++;
}
}
}
}
catch
{
}
ExpectedLength = _expectedHistogram.Sum(e => e);
ExpectedMetric = _expectedHistogram.Count(e => e > 0);
}
public void BuildHistograms(EnumBase.IEnumBase[] paths)
{
if (File.Exists(LocalSettings.ProgramDir + "C_JPG_HISTOGRAM.bin"))
{
var file = LoadFromFile(LocalSettings.ProgramDir + "C_JPG_HISTOGRAM.bin");
_observedHistograms = new ConcurrentDictionary<string, int[]>(file);
var list1 = paths.Select(e => e.PathString).ToList();
var list2 = file.Select(e => e.Key).ToList();
var list3 = list1.Except(list2).ToArray();
foreach (var e in list3)
try
{
using (var org = new Bitmap(e))
{
var observedHistogram = new int[256];
using (var img = new MemoryBitmap(org))
{
c++;
p = c / t * 100f;
for (var y = 0; y < img.Height; y++)
for (var x = 0; x < img.Width; x++)
{
var pixel = img.GetPixel(x, y);
observedHistogram[(pixel.R + pixel.G + pixel.B) / 3]++;
}
if (!_observedHistograms.ContainsKey(e))
_observedHistograms.TryAdd(e, observedHistogram);
}
}
}
catch
{
}
}
else
{
t = paths.Length;
paths.AsParallel().WithDegreeOfParallelism(8).ForAll(i =>
{
try
{
using (var org = new Bitmap(i.PathString))
{
var observedHistogram = new int[256];
using (var img = new MemoryBitmap(org))
{
c++;
p = c / t * 100f;
for (var y = 0; y < img.Height; y++)
for (var x = 0; x < img.Width; x++)
{
var pixel = img.GetPixel(x, y);
observedHistogram[(pixel.R + pixel.G + pixel.B) / 3]++;
}
_observedHistograms.TryAdd(i.PathString, observedHistogram);
}
}
}
catch
{
}
});
}
var kpa = _observedHistograms.ToArray();
SaveToFile(kpa, LocalSettings.ProgramDir + "C_JPG_HISTOGRAM.bin");
}
public void SaveToFile(KeyValuePair<string, int[]>[] kpa, string path)
{
using (var wrtr = new Writer(path))
{
foreach (var i in kpa)
{
var k = i.Key;
var v = i.Value;
wrtr.WriteString(k);
wrtr.WriteInts(v);
}
}
}
public KeyValuePair<string, int[]>[] LoadFromFile(string path)
{
var kpd = new Dictionary<string, int[]>();
using (var reader = new Reader(path))
{
while (true)
try
{
var k = reader.ReadString();
var v = reader.ReadInts();
kpd.Add(k, v);
}
catch
{
return kpd.ToArray();
}
}
return kpd.ToArray();
}
public ConcurrentDictionary<string, float> HistogramChiSquared(EnumBase.IEnumBase[] paths)
{
t = paths.Length;
paths.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount - 2).ForAll(i =>
{
try
{
using (var org = new Bitmap(i.PathString))
{
var observedHistogram = new int[256];
using (var img = new MemoryBitmap(org))
{
c++;
p = c / t * 100f;
var XYObservedLength = img.Height * img.Width;
if (XYObservedLength != XYExpectedLength)
{
s1++;
return;
}
for (var y = 0; y < img.Height; y++)
for (var x = 0; x < img.Width; x++)
{
var pixel = img.GetPixel(x, y);
observedHistogram[(pixel.R + pixel.G + pixel.B) / 3]++;
}
var observedLength = observedHistogram.Sum(e => e);
if (observedLength > ExpectedLength)
{
s2++;
return;
}
var ChiSqrd = 0.0f;
for (var j = 0; j < 256; j++)
if (_expectedHistogram[j] + observedHistogram[j] != 0)
ChiSqrd += (float) Math.Pow(_expectedHistogram[j] - observedHistogram[j], 2) / (_expectedHistogram[j] + observedHistogram[j]);
var fp = Math.Abs(ChiSqrd / ExpectedLength * 100f);
if (fp >= 0 && fp < 15)
_finalDistList.TryAdd(i.PathString, fp);
}
}
}
catch
{
}
});
return _finalDistList;
}
public ConcurrentDictionary<string, float> LoadedHistogramChiSquared()
{
var file = LoadFromFile(LocalSettings.ProgramDir + "C_JPG_HISTOGRAM.bin");
t = file.Length;
file.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount - 2).ForAll(i =>
{
try
{
c++;
p = c / t * 100f;
var d = 0.0f;
for (var j = 0; j < 256; j++)
{
var e = _expectedHistogram[j];
var o = i.Value[j];
if (e + o != 0)
d += (float) Math.Pow(e - o, 2) / (e + o);
}
var dd = d / 100;
if (dd >= 0 && dd < 500)
_finalDistList.TryAdd(i.Key, dd);
}
catch
{
}
});
var srt = _finalDistList.OrderBy(x => x.Value);
return _finalDistList;
}
public ConcurrentDictionary<string, float> LoadedHistogramIntersection()
{
var file = LoadFromFile(LocalSettings.ProgramDir + "C_JPG_HISTOGRAM.bin");
t = file.Length;
file.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount - 2).ForAll(i =>
{
try
{
c++;
p = c / t * 100f;
var d = 0.0f;
for (var j = 0; j < 256; j++)
{
var e = _expectedHistogram[j];
var o = i.Value[j];
d += e + o - Math.Abs(e - o);
}
var observedLength = i.Value.Sum(e => e);
var dd = 0.5f * d / Math.Max(ExpectedLength, observedLength);
if (d >= 0 && d < 5)
_finalDistList.TryAdd(i.Key, d);
}
catch
{
}
});
var srt = _finalDistList.OrderBy(x => x.Value);
return _finalDistList;
}
}
using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; public class ChiSquaredImageComparison { private readonly int[] _expectedHistogram = new int[256]; private readonly ConcurrentDictionary<string, float> _finalDistList = new ConcurrentDictionary<string, float>(); private ConcurrentDictionary<string, int[]> _observedHistograms = new ConcurrentDictionary<string, int[]>(); private volatile float c, p, t, s1, s2; private volatile int ExpectedLength; private volatile int ExpectedMetric; private volatile int XYExpectedLength; public void SetExpectedHistogram(string path) { try { using (var org = new Bitmap(path)) { using (var img = new MemoryBitmap(org)) { XYExpectedLength = img.Height * img.Width; for (var y = 0; y < img.Height; y++) for (var x = 0; x < img.Width; x++) { var pixel = img.GetPixel(x, y); _expectedHistogram[(pixel.R + pixel.G + pixel.B) / 3]++; } } } } catch { } ExpectedLength = _expectedHistogram.Sum(e => e); ExpectedMetric = _expectedHistogram.Count(e => e > 0); } public void BuildHistograms(EnumBase.IEnumBase[] paths) { if (File.Exists(LocalSettings.ProgramDir + "C_JPG_HISTOGRAM.bin")) { var file = LoadFromFile(LocalSettings.ProgramDir + "C_JPG_HISTOGRAM.bin"); _observedHistograms = new ConcurrentDictionary<string, int[]>(file); var list1 = paths.Select(e => e.PathString).ToList(); var list2 = file.Select(e => e.Key).ToList(); var list3 = list1.Except(list2).ToArray(); foreach (var e in list3) try { using (var org = new Bitmap(e)) { var observedHistogram = new int[256]; using (var img = new MemoryBitmap(org)) { c++; p = c / t * 100f; for (var y = 0; y < img.Height; y++) for (var x = 0; x < img.Width; x++) { var pixel = img.GetPixel(x, y); observedHistogram[(pixel.R + pixel.G + pixel.B) / 3]++; } if (!_observedHistograms.ContainsKey(e)) _observedHistograms.TryAdd(e, observedHistogram); } } } catch { } } else { t = paths.Length; paths.AsParallel().WithDegreeOfParallelism(8).ForAll(i => { try { using (var org = new Bitmap(i.PathString)) { var observedHistogram = new int[256]; using (var img = new MemoryBitmap(org)) { c++; p = c / t * 100f; for (var y = 0; y < img.Height; y++) for (var x = 0; x < img.Width; x++) { var pixel = img.GetPixel(x, y); observedHistogram[(pixel.R + pixel.G + pixel.B) / 3]++; } _observedHistograms.TryAdd(i.PathString, observedHistogram); } } } catch { } }); } var kpa = _observedHistograms.ToArray(); SaveToFile(kpa, LocalSettings.ProgramDir + "C_JPG_HISTOGRAM.bin"); } public void SaveToFile(KeyValuePair<string, int[]>[] kpa, string path) { using (var wrtr = new Writer(path)) { foreach (var i in kpa) { var k = i.Key; var v = i.Value; wrtr.WriteString(k); wrtr.WriteInts(v); } } } public KeyValuePair<string, int[]>[] LoadFromFile(string path) { var kpd = new Dictionary<string, int[]>(); using (var reader = new Reader(path)) { while (true) try { var k = reader.ReadString(); var v = reader.ReadInts(); kpd.Add(k, v); } catch { return kpd.ToArray(); } } return kpd.ToArray(); } public ConcurrentDictionary<string, float> HistogramChiSquared(EnumBase.IEnumBase[] paths) { t = paths.Length; paths.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount - 2).ForAll(i => { try { using (var org = new Bitmap(i.PathString)) { var observedHistogram = new int[256]; using (var img = new MemoryBitmap(org)) { c++; p = c / t * 100f; var XYObservedLength = img.Height * img.Width; if (XYObservedLength != XYExpectedLength) { s1++; return; } for (var y = 0; y < img.Height; y++) for (var x = 0; x < img.Width; x++) { var pixel = img.GetPixel(x, y); observedHistogram[(pixel.R + pixel.G + pixel.B) / 3]++; } var observedLength = observedHistogram.Sum(e => e); if (observedLength > ExpectedLength) { s2++; return; } var ChiSqrd = 0.0f; for (var j = 0; j < 256; j++) if (_expectedHistogram[j] + observedHistogram[j] != 0) ChiSqrd += (float) Math.Pow(_expectedHistogram[j] - observedHistogram[j], 2) / (_expectedHistogram[j] + observedHistogram[j]); var fp = Math.Abs(ChiSqrd / ExpectedLength * 100f); if (fp >= 0 && fp < 15) _finalDistList.TryAdd(i.PathString, fp); } } } catch { } }); return _finalDistList; } public ConcurrentDictionary<string, float> LoadedHistogramChiSquared() { var file = LoadFromFile(LocalSettings.ProgramDir + "C_JPG_HISTOGRAM.bin"); t = file.Length; file.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount - 2).ForAll(i => { try { c++; p = c / t * 100f; var d = 0.0f; for (var j = 0; j < 256; j++) { var e = _expectedHistogram[j]; var o = i.Value[j]; if (e + o != 0) d += (float) Math.Pow(e - o, 2) / (e + o); } var dd = d / 100; if (dd >= 0 && dd < 500) _finalDistList.TryAdd(i.Key, dd); } catch { } }); var srt = _finalDistList.OrderBy(x => x.Value); return _finalDistList; } public ConcurrentDictionary<string, float> LoadedHistogramIntersection() { var file = LoadFromFile(LocalSettings.ProgramDir + "C_JPG_HISTOGRAM.bin"); t = file.Length; file.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount - 2).ForAll(i => { try { c++; p = c / t * 100f; var d = 0.0f; for (var j = 0; j < 256; j++) { var e = _expectedHistogram[j]; var o = i.Value[j]; d += e + o - Math.Abs(e - o); } var observedLength = i.Value.Sum(e => e); var dd = 0.5f * d / Math.Max(ExpectedLength, observedLength); if (d >= 0 && d < 5) _finalDistList.TryAdd(i.Key, d); } catch { } }); var srt = _finalDistList.OrderBy(x => x.Value); return _finalDistList; } }
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
public class ChiSquaredImageComparison
{
    private readonly int[]                               _expectedHistogram  = new int[256];
    private readonly ConcurrentDictionary<string, float> _finalDistList      = new ConcurrentDictionary<string, float>();
    private          ConcurrentDictionary<string, int[]> _observedHistograms = new ConcurrentDictionary<string, int[]>();
    private volatile float                               c, p, t, s1, s2;
    private volatile int                                 ExpectedLength;
    private volatile int                                 ExpectedMetric;
    private volatile int                                 XYExpectedLength;
    public void SetExpectedHistogram(string path)
    {
        try
        {
            using (var org = new Bitmap(path))
            {
                using (var img = new MemoryBitmap(org))
                {
                    XYExpectedLength = img.Height * img.Width;
                    for (var y = 0; y < img.Height; y++)
                    for (var x = 0; x < img.Width; x++)
                    {
                        var pixel = img.GetPixel(x, y);
                        _expectedHistogram[(pixel.R + pixel.G + pixel.B) / 3]++;
                    }
                }
            }
        }
        catch
        {
        }
        ExpectedLength = _expectedHistogram.Sum(e => e);
        ExpectedMetric = _expectedHistogram.Count(e => e > 0);
    }
    public void BuildHistograms(EnumBase.IEnumBase[] paths)
    {
        if (File.Exists(LocalSettings.ProgramDir + "C_JPG_HISTOGRAM.bin"))
        {
            var file = LoadFromFile(LocalSettings.ProgramDir + "C_JPG_HISTOGRAM.bin");
            _observedHistograms = new ConcurrentDictionary<string, int[]>(file);
            var list1 = paths.Select(e => e.PathString).ToList();
            var list2 = file.Select(e => e.Key).ToList();
            var list3 = list1.Except(list2).ToArray();
            foreach (var e in list3)
                try
                {
                    using (var org = new Bitmap(e))
                    {
                        var observedHistogram = new int[256];
                        using (var img = new MemoryBitmap(org))
                        {
                            c++;
                            p = c / t * 100f;
                            for (var y = 0; y < img.Height; y++)
                            for (var x = 0; x < img.Width; x++)
                            {
                                var pixel = img.GetPixel(x, y);
                                observedHistogram[(pixel.R + pixel.G + pixel.B) / 3]++;
                            }
                            if (!_observedHistograms.ContainsKey(e))
                                _observedHistograms.TryAdd(e, observedHistogram);
                        }
                    }
                }
                catch
                {
                }
        }
        else
        {
            t = paths.Length;
            paths.AsParallel().WithDegreeOfParallelism(8).ForAll(i =>
            {
                try
                {
                    using (var org = new Bitmap(i.PathString))
                    {
                        var observedHistogram = new int[256];
                        using (var img = new MemoryBitmap(org))
                        {
                            c++;
                            p = c / t * 100f;
                            for (var y = 0; y < img.Height; y++)
                            for (var x = 0; x < img.Width; x++)
                            {
                                var pixel = img.GetPixel(x, y);
                                observedHistogram[(pixel.R + pixel.G + pixel.B) / 3]++;
                            }
                            _observedHistograms.TryAdd(i.PathString, observedHistogram);
                        }
                    }
                }
                catch
                {
                }
            });
        }
        var kpa = _observedHistograms.ToArray();
        SaveToFile(kpa, LocalSettings.ProgramDir + "C_JPG_HISTOGRAM.bin");
    }
    public void SaveToFile(KeyValuePair<string, int[]>[] kpa, string path)
    {
        using (var wrtr = new Writer(path))
        {
            foreach (var i in kpa)
            {
                var k = i.Key;
                var v = i.Value;
                wrtr.WriteString(k);
                wrtr.WriteInts(v);
            }
        }
    }
    public KeyValuePair<string, int[]>[] LoadFromFile(string path)
    {
        var kpd = new Dictionary<string, int[]>();
        using (var reader = new Reader(path))
        {
            while (true)
                try
                {
                    var k = reader.ReadString();
                    var v = reader.ReadInts();
                    kpd.Add(k, v);
                }
                catch
                {
                    return kpd.ToArray();
                }
        }
        return kpd.ToArray();
    }
    public ConcurrentDictionary<string, float> HistogramChiSquared(EnumBase.IEnumBase[] paths)
    {
        t = paths.Length;
        paths.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount - 2).ForAll(i =>
        {
            try
            {
                using (var org = new Bitmap(i.PathString))
                {
                    var observedHistogram = new int[256];
                    using (var img = new MemoryBitmap(org))
                    {
                        c++;
                        p = c / t * 100f;
                        var XYObservedLength = img.Height * img.Width;
                        if (XYObservedLength != XYExpectedLength)
                        {
                            s1++;
                            return;
                        }
                        for (var y = 0; y < img.Height; y++)
                        for (var x = 0; x < img.Width; x++)
                        {
                            var pixel = img.GetPixel(x, y);
                            observedHistogram[(pixel.R + pixel.G + pixel.B) / 3]++;
                        }
                        var observedLength = observedHistogram.Sum(e => e);
                        if (observedLength > ExpectedLength)
                        {
                            s2++;
                            return;
                        }
                        var ChiSqrd = 0.0f;
                        for (var j = 0; j < 256; j++)
                            if (_expectedHistogram[j] + observedHistogram[j] != 0)
                                ChiSqrd += (float) Math.Pow(_expectedHistogram[j] - observedHistogram[j], 2) / (_expectedHistogram[j] + observedHistogram[j]);
                        var fp = Math.Abs(ChiSqrd / ExpectedLength * 100f);
                        if (fp >= 0 && fp < 15)
                            _finalDistList.TryAdd(i.PathString, fp);
                    }
                }
            }
            catch
            {
            }
        });
        return _finalDistList;
    }
    public ConcurrentDictionary<string, float> LoadedHistogramChiSquared()
    {
        var file = LoadFromFile(LocalSettings.ProgramDir + "C_JPG_HISTOGRAM.bin");
        t = file.Length;
        file.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount - 2).ForAll(i =>
        {
            try
            {
                c++;
                p = c / t * 100f;
                var d = 0.0f;
                for (var j = 0; j < 256; j++)
                {
                    var e = _expectedHistogram[j];
                    var o = i.Value[j];
                    if (e + o != 0)
                        d += (float) Math.Pow(e - o, 2) / (e + o);
                }
                var dd = d / 100;
                if (dd >= 0 && dd < 500)
                    _finalDistList.TryAdd(i.Key, dd);
            }
            catch
            {
            }
        });
        var srt = _finalDistList.OrderBy(x => x.Value);
        return _finalDistList;
    }
    public ConcurrentDictionary<string, float> LoadedHistogramIntersection()
    {
        var file = LoadFromFile(LocalSettings.ProgramDir + "C_JPG_HISTOGRAM.bin");
        t = file.Length;
        file.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount - 2).ForAll(i =>
        {
            try
            {
                c++;
                p = c / t * 100f;
                var d = 0.0f;
                for (var j = 0; j < 256; j++)
                {
                    var e = _expectedHistogram[j];
                    var o = i.Value[j];
                    d += e + o - Math.Abs(e - o);
                }
                var observedLength = i.Value.Sum(e => e);
                var dd             = 0.5f * d / Math.Max(ExpectedLength, observedLength);
                if (d >= 0 && d < 5)
                    _finalDistList.TryAdd(i.Key, d);
            }
            catch
            {
            }
        });
        var srt = _finalDistList.OrderBy(x => x.Value);
        return _finalDistList;
    }
}

2 thoughts on “ChiSquaredImageComparison.cs”

Leave a Reply

Your email address will not be published. Required fields are marked *