void CCR_Should_Match_Exactly(Tuple <Digest, Digest> ccrComparisonOne, Tuple <Digest, Digest> ccrComparisonTwo) { var ccrOne = ImagePhash.GetCrossCorrelation(ccrComparisonOne.Item1, ccrComparisonOne.Item2); var ccrTwo = ImagePhash.GetCrossCorrelation(ccrComparisonTwo.Item1, ccrComparisonTwo.Item2); Assert.True(Math.Abs(ccrOne - ccrTwo) < ExactThreshhold); }
static Digest HashImage(Stream stream, float sigma, float gamma, int angles) { using var bitmap = (Bitmap)Image.FromStream(stream); var image = bitmap.ToLuminanceImage(); return(ImagePhash.ComputeDigest(image, sigma, gamma, angles)); }
static void MonitorScreenshotsByAdb() { var outDir = @"t:\Data\Gumball\Screenshots"; var device = "emulator-5554"; //using (var client = new AdbClient("emulator-5554")) if (true) { var hashes = new Dictionary <Shipwreck.Phash.Digest, int>(new DigestComparer()); Shipwreck.Phash.Digest prevHash = null; for (var i = 0; ; i++) { var screenshot = AdbScreenCapture(device); var hash = ComputeDigest(screenshot); //var isOther = prevHash == null || Shipwreck.Phash.ImagePhash.GetCrossCorrelation(prevHash, hash) < 1; var isOther = prevHash == null || hashes.Keys.All(_hash => ImagePhash.GetCrossCorrelation(_hash, hash) < 1); if (isOther) { screenshot.Save(System.IO.Path.Combine(outDir, $"{DateTime.UtcNow:yyMMdd.HHmmss}.png")); } //System.IO.File.WriteAllBytes(System.IO.Path.Combine(outDir, $"{DateTime.UtcNow:yyMMdd.HHmmss}.png"), stream.ToArray()); Console.WriteLine($"{i:d4} {hash} - {(isOther ? "saved" : "skipped")}"); prevHash = hash; hashes[hash] = (hashes.ContainsKey(hash) ? hashes[hash] : 0) + 1; System.Threading.Thread.Sleep(TimeSpan.FromSeconds(0.1)); } } }
private string Compare(Digest hash, double minSimilarity = 0) { Dictionary <string, double> similarities = new Dictionary <string, double>(); foreach (var x in hashes) { var correlation = ImagePhash.GetCrossCorrelation(hash.Coefficents, x.Value); if (correlation >= 1.0) { Console.WriteLine($"Detected '{x.Key}' with a similarity of {correlation}"); return(x.Key); } similarities.Add(x.Key, correlation); } var sim = similarities.OrderByDescending(x => x.Value).First(); if (sim.Value >= minSimilarity) { Console.WriteLine($"Detected '{sim.Key}' with a similarity of {sim.Value}"); return(sim.Key); } else { Console.WriteLine($"Failed to find a Pokemon that satisfies the minimum similarity of {minSimilarity}."); return(null); } }
private static List <KeyValuePair <string, double> > CrossCorrelateDigests(Dictionary <string, Digest> hashes, Digest againstHash) { return(hashes .Select(kv => new KeyValuePair <string, double>(kv.Key, ImagePhash.GetCrossCorrelation(againstHash, kv.Value))) .OrderBy(_ => _.Value) .ToList()); }
// Multithreaded hashing of all images in a folder public static (ConcurrentDictionary <string, Digest> filePathsToHashes, ConcurrentDictionary <Digest, HashSet <string> > hashesToFiles) GetHashes(string dirPath, string searchPattern) { var filePathsToHashes = new ConcurrentDictionary <string, Digest>(); var hashesToFiles = new ConcurrentDictionary <Digest, HashSet <string> >(); var files = Directory.GetFiles(dirPath, searchPattern); Parallel.ForEach(files, (currentFile) => { var bitmap = (Bitmap)Image.FromFile(currentFile); var hash = ImagePhash.ComputeDigest(bitmap.ToLuminanceImage()); filePathsToHashes[currentFile] = hash; HashSet <string> currentFilesForHash; lock (hashesToFiles) { if (!hashesToFiles.TryGetValue(hash, out currentFilesForHash)) { currentFilesForHash = new HashSet <string>(); hashesToFiles[hash] = currentFilesForHash; } } lock (currentFilesForHash) { currentFilesForHash.Add(currentFile); } }); return(filePathsToHashes, hashesToFiles); }
static void Main(string[] args) { if (args.Length > 0) { var bitmap = (Bitmap)Image.FromFile(args[0]); var hash = ImagePhash.ComputeDigest(bitmap.ToLuminanceImage()).ToString(); Console.WriteLine("Hash:"); Console.WriteLine(hash); return; } Console.WriteLine("Enter a path to the directory of Pokemon that you want to hash:"); var dirName = Console.ReadLine(); var files = Directory.GetFiles(dirName); var hashes = new ConcurrentDictionary <string, string>(); Parallel.ForEach(files, (x) => { Console.WriteLine("Processing " + x); var bitmap = (Bitmap)Image.FromFile(x); var hash = ImagePhash.ComputeDigest(bitmap.ToLuminanceImage()).ToString(); hashes.AddOrUpdate(Path.GetFileNameWithoutExtension(x), hash, (k, v) => v); }); File.WriteAllText("poke.json", JsonConvert.SerializeObject(hashes)); }
private void ProcessFiles(IEnumerable <string> fs) { var files = fs.Select(f => Path.GetFullPath(f).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar)).ToList(); List <FileDigests> digests = new List <FileDigests>(); List <CCR> results = new List <CCR>(); var totalTimerId = _PerformanceTracker?.StartTimer("Total"); for (int iteration = 0; iteration < _Iterations; iteration++) { var digestIterationTimerId = _PerformanceTracker?.StartTimer("Digest Iteration"); digests = files.AsParallel().Select(f => { var digestTimerId = _PerformanceTracker?.StartTimer("Digest"); var digest = new FileDigests(f); _PerformanceTracker?.EndTimer(digestTimerId.GetValueOrDefault(), "Digest"); return(digest); }).ToList(); _PerformanceTracker?.EndTimer(digestIterationTimerId.GetValueOrDefault(), "Digest Iteration"); results = digests.SelectMany((d1, i) => digests.Skip(i).Select((d2, j) => new CCR { i = i, j = j + i, m = ImagePhash.GetCrossCorrelation(d1.BitmapSourceHash, d2.BitmapSourceHash) })).OrderBy(v => v.m).ToList(); } _PerformanceTracker?.EndTimer(totalTimerId.GetValueOrDefault(), "Total"); var bd = GetCommonPath(files); var perfReport = _PerformanceTracker?.GenerateReport(); _Output?.Invoke(bd, digests, results, perfReport); }
private void btnpHash_Click(object sender, EventArgs e) { try { var bitmapPrvaSlika = img1; var hashPrvaSlika = ImagePhash.ComputeDigest(bitmapPrvaSlika.ToLuminanceImage()); var bitmapDrugaSlika = img2; var hashDrugaSlika = ImagePhash.ComputeDigest(bitmapDrugaSlika.ToLuminanceImage()); var score = ImagePhash.GetCrossCorrelation(hashPrvaSlika, hashDrugaSlika); byte[] hashPrvaSlikaBytes = Encoding.ASCII.GetBytes(hashPrvaSlika.ToString()); byte[] hashDrugaSlikaBytes = Encoding.ASCII.GetBytes(hashDrugaSlika.ToString()); var prvaBitArray = new BitArray(hashPrvaSlikaBytes); var drugaBitArray = new BitArray(hashDrugaSlikaBytes); string prvaBytes = DohvatiBitove(prvaBitArray); string drugaBytes = DohvatiBitove(drugaBitArray); label1.Text = prvaBytes; label2.Text = drugaBytes; var slicnost = ImagePhash.GetCrossCorrelation(hashPrvaSlika, hashDrugaSlika) * 100; razlika(prvaBytes, drugaBytes); label5.Text = "Sličnost je: " + ((int)slicnost).ToString() + "%"; } catch (Exception) { MessageBox.Show("Treba prvo učitati slike!", "Upozorenje!", MessageBoxButtons.OK, MessageBoxIcon.Warning); } }
// Applies cropping and hashes all frames in range in a folder and returns the hashes in a dictionary public static Dictionary <int, Digest> CropAndPhashFolder(string?path, Rectangle cropPercentage, int startFrame, int endFrame, CancellationTokenSource cts, Action <double> onProgress, Action onFinished) { ConcurrentDictionary <int, Digest> frameHashes = new(); int doneFrames = 0; // Hashes frames in parallel to the max amount of concurrent tasks the user defined. Holds a cancellation token so it can be stopped Parallel.For(startFrame, endFrame, new ParallelOptions { CancellationToken = cts.Token }, i => { // Crops and hashes the current frame Bitmap currentFrame = new(Path.Join(path, $"{i}.jpg")); currentFrame = CropImage(currentFrame, cropPercentage); Digest currentFrameHash = ImagePhash.ComputeDigest(currentFrame.ToLuminanceImage()); // Stores the hash at the frame number frameHashes[i] = currentFrameHash; // Clears the current frame from memory and notifies the caller of its progress currentFrame.Dispose(); doneFrames += 1; double percentage = doneFrames / (double)endFrame * 100d; onProgress(percentage); }); onFinished(); return(new Dictionary <int, Digest>(frameHashes)); }
private void ComputeAndSaveAllHashes() { var bldr = new StringBuilder(); bldr.AppendLine(Path.GetFileName(_options.ImageFile)); var imageHash = ComputeHashOfImageFile(_options.ImageFile, new AverageHash()); bldr.AppendLine($"CoenM Average Hash: {imageHash:X16}"); imageHash = ComputeHashOfImageFile(_options.ImageFile, new DifferenceHash()); bldr.AppendLine($"CoenM Difference Hash: {imageHash:X16}"); imageHash = ComputeHashOfImageFile(_options.ImageFile, new PerceptualHash()); bldr.AppendLine($"CoenM Perceptual Hash: {imageHash:X16}"); // We don't try to handle Alpha-only B&W PNG image files with these hashes. using (var bitmap = (System.Drawing.Bitmap)System.Drawing.Image.FromFile(_options.ImageFile)) { var hashDigest = ImagePhash.ComputeDigest(bitmap.ToLuminanceImage()); bldr.AppendLine($"Shipwreck Perceptual Hash: {hashDigest?.ToString()}"); var hashString = bldr.ToString(); if (String.IsNullOrEmpty(_options.OutputFile)) { Console.Out.WriteLine(hashString); } else { File.WriteAllText(_options.OutputFile, hashString, Encoding.UTF8); } } }
// Compares an entire dictiory against a single image and returns a dictionary of similarity public static Dictionary <int, float[]> GetHashDictSimilarity(Dictionary <int, Digest> hashDict, Bitmap[] references) { Digest[] referenceHashes = new Digest[references.Length]; // Calculated hashes of reference images for (int i = 0; i < references.Length; i++) { referenceHashes[i] = ImagePhash.ComputeDigest(references[i].ToLuminanceImage()); } ConcurrentDictionary <int, float[]> frameSimilarities = new(); // Gets similarity of all frames in parallel Parallel.ForEach(hashDict, hash => { frameSimilarities[hash.Key] = new float[referenceHashes.Length]; // Calculated hashes of reference images for (int i = 0; i < referenceHashes.Length; i++) { float score = ImagePhash.GetCrossCorrelation(hash.Value, referenceHashes[i]); frameSimilarities[hash.Key][i] = score; } }); return(new Dictionary <int, float[]>(frameSimilarities)); }
public string GetPokemon(Stream image) { var bitmap = (Bitmap)Image.FromStream(image); var hash = ImagePhash.ComputeDigest(bitmap.ToLuminanceImage()); return(Compare(hash)); }
public void Digest_Should_Match_Bitmap_Exactly() { var rawBitmapDataDigest = ImagePhash.ComputeDigest(Images.StainedGlassBlurred.Bitmap.ToRawBitmapData().ToLuminanceImage()); var bitmapDigest = ImagePhash.ComputeDigest(Images.StainedGlassBlurred.Bitmap.ToLuminanceImage()); Digest_Should_Match_Exactly(rawBitmapDataDigest, bitmapDigest); }
static Task <CompareResult> Compare( IReadOnlyDictionary <string, object> context, Stream received, Stream verified, float threshold, float sigma, float gamma, int angles) { if (context.GetPhashCompareSettings(out var innerSettings)) { threshold = innerSettings.Threshold; sigma = innerSettings.Sigma; gamma = innerSettings.Gamma; angles = innerSettings.Angles; } var hash1 = HashImage(received, sigma, gamma, angles); var hash2 = HashImage(verified, sigma, gamma, angles); var score = ImagePhash.GetCrossCorrelation(hash1, hash2); var compare = score > threshold; if (compare) { return(Task.FromResult(CompareResult.Equal)); } return(Task.FromResult(CompareResult.NotEqual($"diff > threshold. threshold: {threshold}, score: {score}"))); }
public Digest PHash_Digest() { using var image = Image.FromStream(_imageStream); var luminanceImage = ((Bitmap)image).ToLuminanceImage(); return(ImagePhash.ComputeDigest(luminanceImage)); }
public ulong PHash_Dct() { using var image = Image.FromStream(_imageStream); var luminanceImage = ((Bitmap)image).ToLuminanceImage(); return(ImagePhash.ComputeDctHash(luminanceImage)); }
Digest ComputeImageHash(FileStream stream) { using (var bitmap = (Bitmap)Image.FromStream(stream)) { var hash = ImagePhash.ComputeDigest(bitmap.ToLuminanceImage()); return(hash); } }
static bool CompareImages(Stream stream1, Stream stream2) { var hash1 = HashImage(stream1); var hash2 = HashImage(stream2); var score = ImagePhash.GetCrossCorrelation(hash1, hash2); return(score > .999); }
private async void CheckForDuplicates() { SetBusy("Detecting duplicates..."); ProgressIndeterminate = false; ProgressMin = 0; ProgressMax = Frames.Count; ProgressValue = 0; await Task.Run(() => { Digest currentReference = null; int progress = 0; Parallel.For(0, Frames.Count, i => { lock (BusyMessage) { BusyMessage = $"Computing phash {(progress + 1).ToString("#,###")} of {Frames.Count.ToString("#,###")}"; progress++; ProgressValue = progress; } Frames[i].PHash = HashHelper.GetPHash(Frames[i].FullPath); }); ProgressValue = 0; for (int i = 0; i < Frames.Count; i++) { BusyMessage = $"Checking image {(i + 1).ToString("#,###")} of {Frames.Count.ToString("#,###")}"; ProgressValue = i; //Frames[i].PHash = HashHelper.GetPHash(Frames[i].FullPath); if (i == 0) { currentReference = Frames[i].PHash; } else { var score = ImagePhash.GetCrossCorrelation(currentReference, Frames[i].PHash); if (score > 0.8) { Frames[i].IsDuplicate = true; } else { currentReference = Frames[i].PHash; } } } }); ProgressIndeterminate = true; SetFree(); }
public static Digest GetPHash(string path) { using (Image image = Image.FromFile(path)) using (Bitmap bmp = new Bitmap(image)) { Digest hash = ImagePhash.ComputeDigest(bmp.ToLuminanceImage()); return(hash); } }
// Hashes bitmap images and returns their similarity using Phash public static float CompareBitmapPhash(Bitmap image1, Bitmap image2) { Digest hash1 = ImagePhash.ComputeDigest(image1.ToLuminanceImage()); Digest hash2 = ImagePhash.ComputeDigest(image2.ToLuminanceImage()); float score = ImagePhash.GetCrossCorrelation(hash1, hash2); return(score); }
public void Left_Bottom_Area_Should_Match_Original_Digest_Exactly() { var originalImage = Images.StainedGlassBlurred.Bitmap.ToRawBitmapData(); var rawBitmapDataDigestBlurred = ImagePhash.ComputeDigest(originalImage.ToLuminanceImage()); var trimArea = new Rectangle(60, 0, originalImage.PixelWidth, originalImage.PixelHeight); var rawBitmapDataDigestLeftBottom = ImagePhash.ComputeDigest(Images.StainedGlassLeftBottom.Bitmap.ToRawBitmapData().ToLuminanceImage(trimArea)); Area_Should_Match_Original_Digest_Exactly(rawBitmapDataDigestBlurred, rawBitmapDataDigestLeftBottom); }
public void Right_Top_Area_Should_Match_Original_Digest_Exactly() { var originalImage = Images.StainedGlassBlurred.Bitmap.ToRawBitmapData(); var rawBitmapDataDigestBlurred = ImagePhash.ComputeDigest(originalImage.ToLuminanceImage()); var trimArea = new Rectangle(0, 80, originalImage.PixelWidth, originalImage.PixelHeight); var rawBitmapDataDigestRightTop = ImagePhash.ComputeDigest(Images.StainedGlassRightTop.Bitmap.ToRawBitmapData().ToLuminanceImage(trimArea)); Area_Should_Match_Original_Digest_Exactly(rawBitmapDataDigestBlurred, rawBitmapDataDigestRightTop); }
public void CCR_Should_Match_Bitmap_Exactly() { var rawBitmapDataDigestBlurred = ImagePhash.ComputeDigest(Images.StainedGlassBlurred.Bitmap.ToRawBitmapData().ToLuminanceImage()); var rawBitmapDataDigestCompressed = ImagePhash.ComputeDigest(Images.StainedGlassCompressed.Bitmap.ToRawBitmapData().ToLuminanceImage()); var bitmapDigestBlurred = ImagePhash.ComputeDigest(Images.StainedGlassBlurred.Bitmap.ToLuminanceImage()); var bitmapDigestCompressed = ImagePhash.ComputeDigest(Images.StainedGlassCompressed.Bitmap.ToLuminanceImage()); CCR_Should_Match_Exactly( new Tuple <Digest, Digest>(rawBitmapDataDigestBlurred, rawBitmapDataDigestCompressed), new Tuple <Digest, Digest>(bitmapDigestBlurred, bitmapDigestCompressed)); }
private void ComputeShipwreckDigests(out Digest digest1, out Digest digest2) { using (var bitmap1 = (System.Drawing.Bitmap)System.Drawing.Image.FromFile(_options.Image1)) { digest1 = ImagePhash.ComputeDigest(bitmap1.ToLuminanceImage()); } using (var bitmap2 = (System.Drawing.Bitmap)System.Drawing.Image.FromFile(_options.Image2)) { digest2 = ImagePhash.ComputeDigest(bitmap2.ToLuminanceImage()); } }
public string GetPokemon(byte[] image) { Bitmap bitmap; using (var stream = new MemoryStream(image)) bitmap = (Bitmap)Image.FromStream(stream); var hash = ImagePhash.ComputeDigest(bitmap.ToLuminanceImage()); return(Compare(hash)); }
public PhashedImage(string filePath) { this.FilePath = filePath; this.FileSize = new FileInfo(filePath).Length; using (var bitmap = (Bitmap)Image.FromFile(filePath)) { this.PixelCount = bitmap.Width * bitmap.Height; this.Phash = ImagePhash.ComputeDigest(bitmap.ToLuminanceImage()); } }
public static void ComputeCorrelation() { Camera camera = Camera.main; Texture2D texture = CaptureScreenshot(camera, 1000, 1000); File.WriteAllBytes(@"C:\Users\oginiaux\Downloads\trace\original.jpg", texture.EncodeToJPG()); Digest original = ImagePhash.ComputeDigest(ToLuminanceImage(texture)); Digest modified = ImagePhash.ComputeDigest(ToLuminanceImage(CaptureScreenshot(camera, 1000, 1000))); float correlation = ImagePhash.GetCrossCorrelation(original, modified); Debug.Log("Correlation = " + correlation); }
internal int Run() { try { var startTime = DateTime.Now; switch (_options.Type) { case HashType.Average: ComputeAndSaveImageHash(new AverageHash()); break; case HashType.Difference: ComputeAndSaveImageHash(new DifferenceHash()); break; case HashType.Perceptual: default: ComputeAndSaveImageHash(new PerceptualHash()); break; case HashType.All: ComputeAndSaveAllHashes(); break; case HashType.Shipwreck: var bitmap = (System.Drawing.Bitmap)System.Drawing.Image.FromFile(_options.ImageFile); var hash = ImagePhash.ComputeDigest(bitmap.ToLuminanceImage()); if (String.IsNullOrEmpty(_options.OutputFile)) { Console.Out.WriteLine(hash.ToString()); } else { File.WriteAllText(_options.OutputFile, hash?.ToString(), Encoding.ASCII); } break; } var endTime = DateTime.Now; Console.WriteLine("Computing hash took {0}", endTime - startTime); return(0); } catch (Exception e) { Console.WriteLine(e); Console.WriteLine(e.StackTrace); } return(1); }