public int Detect(String imagePath, out double similarity)
        {
            similarity = 1.0;
            NativeStructures.Digest imageDigest;
            if (Hash(imagePath, out imageDigest))
            {
                int bestCardID = -1;

                foreach (ReferenceCardRadialHash hash in _hashes)
                {
                    NativeStructures.Digest cardDigest = new NativeStructures.Digest();
                    double newSimilarity = 1.0;

                    unsafe
                    {
                        fixed (byte* ptr = hash.Hash)
                        {
                            cardDigest.coeffs = (IntPtr)ptr;
                            cardDigest.size = hash.Hash.Length;
                            newSimilarity = Similarity(ref imageDigest, ref cardDigest);
                        }
                    }

                    if (newSimilarity < similarity)
                    {
                        similarity = newSimilarity;
                        bestCardID = hash.ID;
                    }
                }
                return bestCardID;
            }
            return -1;
        }
示例#2
0
        /// <summary>
        /// Compare two image hashes and return a value between 0 and 1.
        /// 0 meaning the two hashes (and therefore underlying images) are the same,
        /// and 1 meaning they are totally different.
        /// </summary>
        /// <param name="hash1"></param>
        /// <param name="hash2"></param>
        /// <returns></returns>
        public static double CompareHashes(ImageHash hash1, ImageHash hash2)
        {
            if (hash1.Algorithm != hash2.Algorithm)
            {
                throw new ArgumentException("Both hashes must use the same algorithm!");
            }
            double result;

            switch (hash1.Algorithm)
            {
            case HashAlgorithm.DCT:
                int rawHammingResult =
                    NativeFunctions.ph_hamming_distance(((DCTHash)hash1).Hash, ((DCTHash)hash2).Hash);
                result = NormalizeThreshold(HashAlgorithm.DCT, rawHammingResult);
                break;

            case HashAlgorithm.Radial:
                NativeStructures.Digest digest1 = ((RadialHash)hash1).Digest;
                NativeStructures.Digest digest2 = ((RadialHash)hash2).Digest;

                double rawCrossCorrResult;
                NativeFunctions.ph_crosscorr(ref digest1, ref digest2, out rawCrossCorrResult);
                result = NormalizeThreshold(HashAlgorithm.Radial, rawCrossCorrResult);
                break;

            case HashAlgorithm.MH:
                MHHash mhHash1 = (MHHash)hash1;
                MHHash mhHash2 = (MHHash)hash2;

                double rawHamming2Result =
                    NativeFunctions.ph_hammingdistance2(mhHash1.BytesPtr, mhHash1.ByteCount, mhHash2.BytesPtr, mhHash2.ByteCount);
                result = NormalizeThreshold(HashAlgorithm.MH, rawHamming2Result);
                break;

            default:
                throw new NotImplementedException();
            }
            return(result);
        }
示例#3
0
 public static extern int ph_crosscorr(ref NativeStructures.Digest x, ref NativeStructures.Digest y, out double pcc, double threshold = 0.90);
示例#4
0
 public static extern int ph_image_digest(string file, double sigma, double gamma, out NativeStructures.Digest digest, int N = 180);
示例#5
0
 public RadialHash(NativeStructures.Digest digest)
 {
     this.Digest = digest;
 }