/// <summary> /// compute dct robust image hash /// </summary> /// <param name="image">An image to compute DCT hash.</param> /// <returns>hash of type ulong</returns> public static ulong ComputeDctHash(IByteImage image) { var img = image.Convolve(new FloatImage(7, 7, 1)); var resized = img.Resize(32, 32); var C = CreateDctMatrix(32); var Ctransp = C.Transpose(); var dctImage = C.Multiply(resized).Multiply(Ctransp); var sum = 0f; for (var y = 0; y < 8; y++) { for (var x = 0; x < 8; x++) { sum += dctImage[x, y]; } } var median = sum / 64f; var r = 0ul; for (var y = 0; y < 8; y++) { for (var x = 0; x < 8; x++) { r |= dctImage[x, y] > median ? (1ul << (x + 8 * y)) : 0; } } return(r); }
/// <summary> /// compare 2 images /// </summary> /// <param name="imA">CImg object of first image</param> /// <param name="imB">CImg object of second image</param> /// <param name="pcc">double value for peak of cross correlation</param> /// <param name="sigma">double value for the deviation of gaussian filter</param> /// <param name="gamma">double value for gamma correction of images</param> /// <param name="numberOfAngles">int number for the number of angles of radon projections</param> /// <param name="threshold">double value for the threshold</param> /// <returns>false for different images, 1 true for same image,</returns> public static bool CompareImages(IByteImage imA, IByteImage imB, out float pcc, float sigma = DEFAULT_SIGMA, float gamma = DEFAULT_GAMMA, int numberOfAngles = DEFAULT_NUMBER_OF_ANGLES, float threshold = DEFAULT_THRESHOLD) { var digestA = ComputeDigest(imA, sigma, gamma, numberOfAngles); var digestB = ComputeDigest(imB, sigma, gamma, numberOfAngles); pcc = GetCrossCorrelation(digestA, digestB); return(pcc > threshold); }
/// <summary> /// Compute the image digest for an image given the input image /// </summary> /// <param name="image">CImg object representing an input image</param> /// <param name="sigma">double value for the deviation for a gaussian filter function</param> /// <param name="gamma">double value for gamma correction on the input image</param> /// <param name="numberOfAngles">int value for the number of angles to consider.</param> /// <returns></returns> public static Digest ComputeDigest(IByteImage image, float sigma = DEFAULT_SIGMA, float gamma = DEFAULT_GAMMA, int numberOfAngles = DEFAULT_NUMBER_OF_ANGLES) { var blurred = image.Blur(sigma); blurred.DivideInplace(blurred.Max()); blurred.ApplyGamma(gamma); var projs = FindRadonProjections(blurred, numberOfAngles); var features = ComputeFeatureVector(projs); return(ComputeDct(features)); }
/// <summary> /// compute dct robust image hash /// </summary> /// <param name="image">An image to compute DCT hash.</param> /// <returns>hash of type ulong</returns> public static ulong ComputeDctHash(IByteImage image) { var img = image.Convolve(new FloatImage(7, 7, 1)); var resized = img.Resize(32, 32); var coeff = _DctMatrix ?? (_DctMatrix = CreateDctMatrix(32)); var dctImage = coeff.MatrixMultiply(resized).MatrixMultiply(coeff, isTransposed: true); var median = GetMedianOf64(dctImage); var r = 0ul; for (var y = 0; y < 8; y++) { for (var x = 0; x < 8; x++) { r |= dctImage[x + 1, y + 1] > median ? (1ul << (x + 8 * y)) : 0; } } return(r); }
public GenericByteImageWrapper(IByteImage image) { _Image = image; }
public static FloatImage Convolve(this IByteImage image, FloatImage kernel) => image.Wrap().Convolve(kernel);
internal static IByteImageWrapper Wrap(this IByteImage image) => image as IByteImageWrapper ?? (image as IByteImageWrapperProvider)?.GetWrapper() ?? new GenericByteImageWrapper(image);
public static FloatImage Blur(this IByteImage image, float sigma) => image.Convolve(FloatImage.CreateGaussian(3, sigma));