private static IEnumerable<string> TryDeduceMatchingCandidateSnapshot( ImageWrapper transformedOriginalSnapshot, IEnumerable<string> candidateSnapshots, Func<ImageWrapper, Maybe<ImageWrapper>> candidateTranform ) { var candidateResultList = new ConcurrentBag<Tuple<string, int>>(); using (var originaImageAsLockbit = new LockBitImage(transformedOriginalSnapshot.Image)) { Parallel.ForEach(candidateSnapshots, candidateSnapshot => { var candidateComparisonResult = from loadedCandidateSnapshot in TryLoadImage(candidateSnapshot) from transformedCandidate in candidateTranform.Invoke(loadedCandidateSnapshot) let candidateLockbitImage = new LockBitImage(transformedCandidate.Image) let similarityIndex = SimilarityCalculator.CalculateSimilarityIndex( originaImageAsLockbit, candidateLockbitImage ) select CommonFunctions.ExecThenDispose( () => Tuple.Create<string, int>(candidateSnapshot, similarityIndex), loadedCandidateSnapshot, transformedCandidate, candidateLockbitImage ); candidateComparisonResult.Apply(i => candidateResultList.Add(i)); }); } return from candidateTuple in candidateResultList where candidateTuple.Item2 >= 69 select candidateTuple.Item1; }
/// <summary> /// Calculate the similarity between two images /// </summary> /// <remarks> /// Images that are not the same size will always return a result of 0, as they cannot /// be the same. /// </remarks> /// <param name="original">The original image to compare against</param> /// <param name="candidate">The candidate image to compare with the original</param> /// <returns>An integer, from 0-100 indicating how similar the two images are</returns> public static int CalculateSimilarityIndex(LockBitImage original, LockBitImage candidate) { // Images that are not the same size are immediately discounted if (original.Width != candidate.Width || original.Height != candidate.Height) { return 0; } return (int)(SSIMCalculator.Compute(original, candidate) * 100); }
public GaussianBlurTransformation(Image sourceImage, int radius) { _disposed = false; _sourceImage = new LockBitImage(sourceImage); _radius = radius; }