private double Similarity(ref NativeStructures.Digest digest1, ref NativeStructures.Digest digest2)
        {
            double result;

            NativeFunctions.ph_crosscorr(ref digest1, ref digest2, out result);
            return(1f - result);
        }
        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);
        }
 private bool Hash(String imagePath, out NativeStructures.Digest hash)
 {
     return(NativeFunctions.ph_image_digest(imagePath, 1.0, 1.0, out hash) != -1);
 }