coenm / imagehash Goto Github PK
View Code? Open in Web Editor NEWLibrary containing perceptual hash algorithms using the ImageSharp library
License: MIT License
Library containing perceptual hash algorithms using the ImageSharp library
License: MIT License
When using the perceptual hash, there are always 32 bits set in the output.
Is that normal?
I downloaded ImageHash-develop.zip from GitHub and opened the ImageHash.sln in VS 2019. It would not build, complaining about missing files from the .git folder (which did not exist). I then downloaded it with GitHub Desktop. This version built OK.
I was able to get the ImageHash solution from the zip file to build by copying the .git folder from the GitHub Desktop version to it.
Expected result: You should be able to build and run ImageHash from the GitHub zip download.
I'm currently using another pHash library, and I receive better results with it compared to this one.
Are there any differences between them?
DifferenceHash always fail, and also PerceptualHash fails very often (9/10) . I get images from a folder and, in a foreach statement, use this code:
ulong imageHash;
//this fails also if instantiated outside foreach of course
DifferenceHash DiffHashAlgorithm = new DifferenceHash();
using (FileStream stream = File.OpenRead(MyFile.FullPath))
{
imageHash = DiffHashAlgorithm.Hash(stream);
}
Both algorythms give the same error:
Exception message:
Image cannot be loaded. Available decoders:
StackTrace:
in SixLabors.ImageSharp.Image.Load[TPixel](Configuration config, Stream stream, IImageFormat& format) in CoenM.ImageHash.ImageHashExtensions.Hash(IImageHash hashImplementation, Stream stream)
The readme examples are out of date which would confuse some people including me the latest version of the hash functions use a sixlabors image class with specific format.
The example just shows hashAlgorithm.Hash(stream)
But you need to do hashAlgorithm.Hash(SixLabors.ImageSharp.Image.Load<SixLabors.ImageSharp.PixelFormats.Rgba32>(stream))
Hi,
does anyone encounter strange hash value differences when using the PerceptualHash hash function? We made some tests from Net5 to Net6 and the values produced differ. The stream and data behind stayed the same. We computed quickly a md5 hash for both stream variants (net5 and net6) and the values stayed the same.
Regards
Map labels to headers like
Unless I'm using it wrong, there appears to be a memory leak in CoenM.ImageHash.HashAlgorithms.PerceptualHash. I'm attempting to generate hashes for approximately 45000 images. I get a System.OutOfMemoryException at approximately 28000 images. My code, with a bunch of database and Winforms code removed, looks like this:
`
using IH = CoenM.ImageHash.HashAlgorithms;
using IS6 = SixLabors.ImageSharp;
namespace SqlEntityFramework {
public partial class Form1: Form {
IH.PerceptualHash PHash { get; set; } = new IH.PerceptualHash();
static byte[] GetByteArray(Bitmap bitmap) {
using (var mStream = new MemoryStream()) {
bitmap.Save(mStream, ImageFormat.Bmp);
byte[] imageData = mStream.ToArray();
return imageData;
}
}
private void processImagesButton_ClickAsync(object sender, EventArgs e) {
try {
var imageFolderDI = new DirectoryInfo(@"D:\Images");
var files = imageFolderDI.GetFiles();
for (int i = 0; i < files.Length; i++) {
var imageFI = files[i];
long phash;
using (var image = new Bitmap(imageFI.FullName)) {
byte[] imageData = GetByteArray(image);
using (var image = new Bitmap(imageFI.FullName)) {
byte[] imageData = GetByteArray(image);
/* *********************
* comment out this using clause and I process all 45000 images
* uncomment and I run out of memory at 28411 images
using (var image6 = IS6.Image.Load(imageData)) {
phash = (long) PHash.Hash(image6);
image6.Dispose();
}
****************** */
// save phash to DB ...
}
// Tried adding this clause, but still get an out-of-memory exception after 17701 iterations
if ((i % 30) == 0) {
PHash = new IH.PerceptualHash();
}
}
} catch (Exception e1) { // e is a System.OutOfMemoryException exception. Call stack is empty
Console.WriteLine($"Exception processing images: {e1.Message}");
}
}
}
}
`
I'm pretty sure the leak isn't in my code, since it processes all 45000 images when the /*** using () { } ***/ clause is commented out. I'm building and running it in Visual Studio 2019 v16.8.0 with x86 configuration.
FWIW, I rebooted my Win 10 PC (16 GB memory) and tried recreating PerceptualHash() every 30 iterations. That appeared to make the memory problem occur about 10000 iterations earlier. I suspect the problem is in SixLabors.ImageSharp.Image.Mutate()? The call stack is nearly empty empty when I break in the catch clause:
SqlEntityFramework.exe!SqlEntityFramework.Form1.processImagesButton_ClickAsync(object sender, System.EventArgs e) Line 111 C#
[Resuming Async Method]
[External Code]
SqlEntityFramework.exe!SqlEntityFramework.Program.Main() Line 16 C#
The exception trace looks like:
at System.Buffers.DefaultArrayPool1.Rent(Int32 minimumLength) at SixLabors.ImageSharp.Memory.ArrayPoolMemoryAllocator.Allocate[T](Int32 length, AllocationOptions options) at SixLabors.ImageSharp.Memory.MemoryGroup
1.Allocate(MemoryAllocator allocator, Int64 totalLength, Int32 bufferAlignment, AllocationOptions options)
at SixLabors.ImageSharp.Memory.MemoryAllocatorExtensions.Allocate2D[T](MemoryAllocator memoryAllocator, Int32 width, Int32 height, AllocationOptions options)
at SixLabors.ImageSharp.ImageFrame1..ctor(Configuration configuration, Int32 width, Int32 height, TPixel backgroundColor, ImageFrameMetadata metadata) at SixLabors.ImageSharp.ImageFrameCollection
1..ctor(Image1 parent, Int32 width, Int32 height, TPixel backgroundColor) at SixLabors.ImageSharp.Image
1..ctor(Configuration configuration, Int32 width, Int32 height, ImageMetadata metadata)
at SixLabors.ImageSharp.Formats.Bmp.BmpDecoderCore.Decode[TPixel](BufferedReadStream stream, CancellationToken cancellationToken)
at SixLabors.ImageSharp.Formats.ImageDecoderUtilities.Decode[TPixel](IImageDecoderInternals decoder, Configuration configuration, Stream stream, Func3 largeImageExceptionFactory) at SixLabors.ImageSharp.Formats.ImageDecoderUtilities.Decode[TPixel](IImageDecoderInternals decoder, Configuration configuration, Stream stream) at SixLabors.ImageSharp.Formats.Bmp.BmpDecoder.Decode[TPixel](Configuration configuration, Stream stream) at SixLabors.ImageSharp.Image.Decode[TPixel](Stream stream, Configuration config) at SixLabors.ImageSharp.Image.<>c__DisplayClass133_0
1.b__0(Stream s)
at SixLabors.ImageSharp.Image.WithSeekableStream[T](Configuration configuration, Stream stream, Func`2 action)
at SixLabors.ImageSharp.Image.Load[TPixel](Configuration configuration, Stream stream, IImageFormat& format)
at SixLabors.ImageSharp.Image.Load[TPixel](Configuration configuration, Byte[] data)
at SixLabors.ImageSharp.Image.Load(Byte[] data)
at SqlEntityFramework.Helpers.ToIS6Image(Byte[] byteArray) in D:\CSharp\SqlEntityFramework\SqlEntityFramework\Helpers.cs:line 35
at SqlEntityFramework.Form1.AddImageToDB(SHA256 sha256, PixEmailEntities dbContext, FileInfo imageFI) in D:\CSharp\SqlEntityFramework\SqlEntityFramework\Form1.cs:line 64
at SqlEntityFramework.Form1.<processImagesButton_ClickAsync>d__24.MoveNext() in D:\CSharp\SqlEntityFramework\SqlEntityFramework\Form1.cs:line 91
Expected Result: You should be able to create at least 1000000 hashes
Hi,
I'm sampling a portion of my display and wanting to create a perceptual hash from the resulting Bitmap but can't seem to find a way to do it... all examples require loading an image from disk which I ideally do not want to use as it requires me to first save the image to disk which is slow.
Is there a simple way or method to create a hash directly from bitmap?
System.AggregateException: One or more errors occurred. (One or more errors occurred. (Specified argument was out of the range of valid values.)) ---> System.AggregateException: One or more errors occurred. (Specified argument was out of the range of valid values.) ---> System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
at at System.Span`1.Slice(Int32 start, Int32 length)
at at SixLabors.Memory.ArrayPoolMemoryAllocator.Buffer`1.GetSpan()
at at System.Memory`1.get_Span()
at at SixLabors.ImageSharp.Memory.Buffer2D`1.get_Span()
at at SixLabors.ImageSharp.Memory.Buffer2D`1.get_Item(Int32 x, Int32 y)
at at SixLabors.ImageSharp.Image`1.get_Item(Int32 x, Int32 y)
at at CoenM.ImageHash.HashAlgorithms.PerceptualHash.Hash(Image`1 image)
at rcs.Core.Processor.<>c__DisplayClass3_2.<GuessAngle>b__1(Int32 i) in D:\GitHub\rcs\rcs\Core\Processor.cs:75
at at System.Threading.Tasks.Parallel.<>c__DisplayClass19_0`1.<ForWorker>b__1(RangeWorker& currentWorker, Int32 timeout, Boolean& replicationDelegateYieldedBeforeCompletion)
at at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw(Exception source)
at at System.Threading.Tasks.Parallel.<>c__DisplayClass19_0`1.<ForWorker>b__1(RangeWorker& currentWorker, Int32 timeout, Boolean& replicationDelegateYieldedBeforeCompletion)
at at System.Threading.Tasks.TaskReplicator.Replica`1.ExecuteAction(Boolean& yieldedBeforeCompletion)
at at System.Threading.Tasks.TaskReplicator.Replica.Execute()
--- End of inner exception stack trace ---
at at System.Threading.Tasks.TaskReplicator.Run[TState](ReplicatableUserAction`1 action, ParallelOptions options, Boolean stopOnFirstFailure)
at at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 localInit, Action`1 localFinally)
at at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw(Exception source)
at at System.Threading.Tasks.Parallel.ThrowSingleCancellationExceptionOrOtherException(ICollection exceptions, CancellationToken cancelToken, Exception otherException)
at at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 localInit, Action`1 localFinally)
at at System.Threading.Tasks.Parallel.For(Int32 fromInclusive, Int32 toExclusive, Action`1 body)
at rcs.Core.Processor.GuessAngle(String path, Int32 count) in D:\GitHub\rcs\rcs\Core\Processor.cs:72
at rcs.Program.<>c.<<Main>b__1_1>d.MoveNext() in D:\GitHub\rcs\rcs\Program.cs:78
--- End of inner exception stack trace ---
at at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at at System.Threading.Tasks.Task.Wait()
at rcs.Program.<>c.<<Main>b__1_0>d.MoveNext() in D:\GitHub\rcs\rcs\Program.cs:121
at at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.<ThrowAsync>b__7_1(Object state)
at at System.Threading.QueueUserWorkItemCallbackDefaultContext.<>c.<.cctor>b__5_0(Object state)
at at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at at System.Threading.QueueUserWorkItemCallbackDefaultContext.ExecuteWorkItem()
at at System.Threading.ThreadPoolWorkQueue.Dispatch()
at at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
at at System.Span`1.Slice(Int32 start, Int32 length)
at at SixLabors.Memory.ArrayPoolMemoryAllocator.Buffer`1.GetSpan()
at at System.Memory`1.get_Span()
at at SixLabors.ImageSharp.Memory.Buffer2D`1.get_Span()
at at SixLabors.ImageSharp.Memory.Buffer2D`1.get_Item(Int32 x, Int32 y)
at at SixLabors.ImageSharp.Image`1.get_Item(Int32 x, Int32 y)
at at CoenM.ImageHash.HashAlgorithms.PerceptualHash.Hash(Image`1 image)
at rcs.Core.Processor.<>c__DisplayClass3_1.<GuessAngle>b__1(Int32 i) in D:\GitHub\rcs\rcs\Core\Processor.cs:93
at at System.Threading.Tasks.Parallel.<>c__DisplayClass19_0`1.<ForWorker>b__1(RangeWorker& currentWorker, Int32 timeout, Boolean& replicationDelegateYieldedBeforeCompletion)
at at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw(Exception source)
at at System.Threading.Tasks.Parallel.<>c__DisplayClass19_0`1.<ForWorker>b__1(RangeWorker& currentWorker, Int32 timeout, Boolean& replicationDelegateYieldedBeforeCompletion)
at at System.Threading.Tasks.TaskReplicator.Replica`1.ExecuteAction(Boolean& yieldedBeforeCompletion)
at at System.Threading.Tasks.TaskReplicator.Replica.Execute()
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.