Exemple #1
0
        /// <summary>
        /// Compute the dct of a given vector
        /// </summary>
        /// <param name="featureVector">vector of input series</param>
        /// <returns>the dct of R</returns>
        internal static Digest ComputeDct(float[] featureVector)
        {
            int N = featureVector.Length;

            float[] R = featureVector;

            float[] coefficients = new float[Digest.LENGTH];
            float   max          = 0f;
            float   min          = 0f;
            float   div2n        = MathF.PI / (2 * N);
            float   divSq        = 1 / MathF.Sqrt(N);

            for (int k = 0; k < Digest.LENGTH; k++)
            {
                float sum = 0f;
                for (int n = 0; n < N; n++)
                {
                    sum += R[n] * MathF.Cos((2 * n + 1) * k * div2n);
                }

                float v = coefficients[k] = sum * divSq * (k == 0 ? 1 : SQRT_TWO);
                max = Math.Max(max, v);
                min = Math.Min(min, v);
            }

            return(NormalizeDigest(coefficients, max, min));
        }
Exemple #2
0
        private static float GetCrossCorrelationCore(float[] x, float[] y)
        {
            float max = 0f;

            for (int d = 0; d < x.Length; d++)
            {
                float v;
                v   = GetCrossCorrelationForOffset(x, y, d);
                max = Math.Max(max, v);
            }

            return(MathF.Sqrt(max));
        }
Exemple #3
0
        /// <summary>
        /// return dct matrix, C Return DCT matrix of square size, <paramref name="size" />
        /// </summary>
        /// <param name="size">int denoting the size of the square matrix to create.</param>
        /// <returns>size <paramref name="size" />x<paramref name="size" /> containing the dct matrix</returns>
        internal static FloatImage CreateDctMatrix(int size)
        {
            FloatImage ret = new FloatImage(size, size, 1 / (float)Math.Sqrt(size));

            float c1  = MathF.Sqrt(2f / size);
            float rad = MathF.PI / 2 / size;

            for (int x = 0; x < size; x++)
            {
                for (int y = 1; y < size; y++)
                {
                    ret[x, y] = c1 * MathF.Cos(rad * y * (2 * x + 1));
                }
            }

            return(ret);
        }
Exemple #4
0
        internal static FloatImage CreateMHKernel(float alpha, float level)
        {
            int sigma = (int)(4 * MathF.Pow(alpha, level));

            FloatImage kernel = new FloatImage(2 * sigma + 1, 2 * sigma + 1);

            for (int y = 0; y < kernel.Width; y++)
            {
                for (int x = 0; x < kernel.Height; x++)
                {
                    float xpos = MathF.Pow(alpha, -level) * (x - sigma);
                    float ypos = MathF.Pow(alpha, -level) * (y - sigma);
                    float A    = xpos * xpos + ypos * ypos;
                    kernel[x, y] = (float)((2 - A) * MathF.Exp(-A / 2));
                }
            }
            return(kernel);
        }
Exemple #5
0
        /// <summary>
        /// compute the feature vector from a radon projection map.
        /// </summary>
        /// <param name="projections">Projections struct</param>
        /// <returns>Features struct</returns>
        internal static float[] ComputeFeatureVector(Projections projections)
        {
            FloatImage map = projections.Region;

            int[] ppl = projections.PixelsPerLine;
            int   N   = ppl.Length;
            int   D   = map.Height;

            float[] fv = new float[N];

            float sum     = 0f;
            float sum_sqd = 0f;

            for (int k = 0; k < N; k++)
            {
                float line_sum     = 0f;
                float line_sum_sqd = 0f;
                int   nb_pixels    = ppl[k];
                for (int i = 0; i < D; i++)
                {
                    line_sum     += map[k, i];
                    line_sum_sqd += map[k, i] * map[k, i];
                }
                fv[k]    = (float)(nb_pixels > 0 ? (line_sum_sqd / nb_pixels) - (line_sum * line_sum) / (nb_pixels * nb_pixels) : 0);
                sum     += fv[k];
                sum_sqd += fv[k] * fv[k];
            }
            float mean = sum / N;
            float var  = 1 / MathF.Sqrt((sum_sqd / N) - (sum * sum) / (N * N));

            for (int i = 0; i < N; i++)
            {
                fv[i] = (fv[i] - mean) * var;
            }

            return(fv);
        }
Exemple #6
0
        /// <summary>
        /// Find radon projections of N lines running through the image center for lines angled 0 to 180 degrees from horizontal.
        /// </summary>
        /// <param name="img">CImg src image</param>
        /// <param name="numberOfLines">int number of angled lines to consider.</param>
        /// <returns>Projections struct</returns>
        internal static Projections FindRadonProjections(FloatImage img, int numberOfLines)
        {
            int   width    = img.Width;
            int   height   = img.Height;
            int   D        = (width > height) ? width : height;
            float x_center = width / 2f;
            float y_center = height / 2f;
            int   x_off    = (int)MathF.Floor(x_center + GetRoundingFactor(x_center));
            int   y_off    = (int)MathF.Floor(y_center + GetRoundingFactor(y_center));

            Projections projs = new Projections(numberOfLines, D, numberOfLines);

            FloatImage radonMap = projs.Region;

            int[] ppl = projs.PixelsPerLine;

            for (int k = 0; k < numberOfLines / 4 + 1; k++)
            {
                float theta = k * MathF.PI / numberOfLines;
                float alpha = MathF.Tan(theta);
                for (int x = 0; x < D; x++)
                {
                    float y  = alpha * (x - x_off);
                    int   yd = (int)MathF.Floor(y + GetRoundingFactor(y));
                    if ((yd + y_off >= 0) && (yd + y_off < height) && (x < width))
                    {
                        radonMap[k, x] = img[x, yd + y_off];
                        ppl[k]        += 1;
                    }
                    if ((yd + x_off >= 0) && (yd + x_off < width) && (k != numberOfLines / 4) && (x < height))
                    {
                        radonMap[numberOfLines / 2 - k, x] = img[yd + x_off, x];
                        ppl[numberOfLines / 2 - k]        += 1;
                    }
                }
            }
            int j = 0;

            for (int k = 3 * numberOfLines / 4; k < numberOfLines; k++)
            {
                float theta = k * MathF.PI / numberOfLines;
                float alpha = MathF.Tan(theta);
                for (int x = 0; x < D; x++)
                {
                    float y  = alpha * (x - x_off);
                    int   yd = (int)MathF.Floor(y + GetRoundingFactor(y));
                    if ((yd + y_off >= 0) && (yd + y_off < height) && (x < width))
                    {
                        radonMap[k, x] = img[x, yd + y_off];
                        ppl[k]        += 1;
                    }
                    if ((y_off - yd >= 0) && (y_off - yd < width) && (2 * y_off - x >= 0) && (2 * y_off - x < height) && (k != 3 * numberOfLines / 4))
                    {
                        radonMap[k - j, x] = img[-yd + y_off, -(x - y_off) + y_off];
                        ppl[k - j]        += 1;
                    }
                }
                j += 2;
            }

            return(projs);
        }
Exemple #7
0
 private static byte ToByte(this float f)
 => (byte)Math.Max(byte.MinValue, Math.Min(MathF.Round(f), byte.MaxValue));