示例#1
0
        public void KernelTest1()
        {
            double[,] expected =
            {
                {     2.1693514414478006E-34,  2.4546349229561677E-22,    -1.5279500064746295E-21 },
                { -0.00000069069240704724283,      0.9210609940028851, -0.00000012799017494227224 },
                {    -7.7578659683414284E-22, -4.1079449607342235E-22,     3.2663608516186217E-34 }
            };

            double[,] actual = Gabor.Kernel2D(sigma: 0.1, theta: 0.2, lambda: 0.3, psi: 0.4, gamma: 0.5);

            Assert.AreEqual(actual.GetLength(0), expected.GetLength(0));
            Assert.AreEqual(actual.GetLength(1), expected.GetLength(1));

            for (int i = 0; i < actual.GetLength(0); i++)
            {
                for (int j = 0; j < actual.GetLength(1); j++)
                {
                    double e = expected[i, j];
                    double a = actual[i, j];

                    Assert.AreEqual(e, a, System.Math.Abs(e * 1e-10));
                }
            }
        }
示例#2
0
        public void KernelTest2()
        {
            double[,] expected =
            {
                {  1.42405394857622E-52, -1.55301965707389E-39, -5.91718738982049E-28,  6.74066784260594E-19,  9.45212732580885E-13, -1.54728187127383E-07,  1.35216035740648E-05 },
                {  2.44396261647309E-27,  6.22350869845861E-18, -2.53179283832159E-10,  4.71970195306204E-06,      0.01750857512698,   -0.0562293027375883, -0.000676655483164679 },
                { -1.18923149745881E-11,  3.26086352470611E-05,   -0.0380349460494781,    -0.653643620863612,    0.0705347070196069,  1.49826805190377E-06, -8.02838283000017E-11 },
                {  -0.00143882468734695,    0.0594224852404454,   0.00675479754684435, -2.97718145336781E-05,  8.09821092370491E-11,  1.01520928946922E-17, -3.06243455885214E-27 },
                { -2.89102012691001E-05,  2.93060843736615E-09,  4.32869511491687E-12, -4.97862860483868E-19, -4.04134720949385E-28,  4.26508052356691E-39, -1.65106988580208E-53 }
            };

            double[,] actual = Gabor.Kernel2D(sigma: 1, theta: 2, lambda: 3, psi: 4, gamma: 5);

            Assert.AreEqual(actual.GetLength(0), expected.GetLength(0));
            Assert.AreEqual(actual.GetLength(1), expected.GetLength(1));

            for (int i = 0; i < actual.GetLength(0); i++)
            {
                for (int j = 0; j < actual.GetLength(1); j++)
                {
                    double e = expected[i, j];
                    double a = actual[i, j];

                    Assert.AreEqual(e, a, System.Math.Abs(e * 1e-10));
                }
            }
        }
示例#3
0
        /// <summary>
        ///   Process the filter on the specified image.
        /// </summary>
        ///
        /// <param name="sourceData">Source image data.</param>
        /// <param name="destinationData">Destination image data.</param>
        ///
        protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
        {
            // check image format
            if ((sourceData.PixelFormat != PixelFormat.Format8bppIndexed) &&
                (sourceData.PixelFormat != PixelFormat.Format24bppRgb))
            {
                throw new UnsupportedImageFormatException("Unsupported image format.");
            }

            if (sourceData.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                sourceData = Grayscale.CommonAlgorithms.BT709.Apply(sourceData);
            }

            if (recompute)
            {
                recompute = false;
                kernel    = Gabor.Kernel2D(size: size,
                                           lambda: lambda,
                                           theta: theta,
                                           psi: psi,
                                           sigma: sigma,
                                           gamma: gamma,
                                           normalized: true,
                                           function: GaborKernelKind.Imaginary);
            }

            int kernelHeight = kernel.GetLength(0);
            int kernelWidth  = kernel.GetLength(1);

            int centerX = kernelHeight / 2;
            int centerY = kernelWidth / 2;

            int width  = sourceData.Width;
            int height = sourceData.Height;

            int srcStride = sourceData.Stride;
            int srcOffset = srcStride - width;

            byte *src = (byte *)sourceData.ImageData.ToPointer();


            int[,] response = new int[height, width];

            int max = int.MinValue;
            int min = int.MaxValue;

            // for each image row
            for (int y = 0; y < height; y++)
            {
                // for each pixel in the row
                for (int x = 0; x < width; x++, src++)
                {
                    double sum = 0;

                    // for each kernel row
                    for (int i = 0; i < kernelHeight; i++)
                    {
                        int ir = i - centerY;
                        int t  = y + ir;

                        // skip row
                        if (t < 0)
                        {
                            continue;
                        }

                        // break
                        if (t >= height)
                        {
                            break;
                        }

                        int col = ir * srcStride;

                        // for each kernel value in the row
                        for (int j = 0; j < kernelWidth; j++)
                        {
                            int jr = j - centerX;
                            t = x + jr;

                            // skip column
                            if (t < 0)
                            {
                                continue;
                            }

                            if (t < width)
                            {
                                double k = kernel[i, j];
                                sum += k * src[col + jr];
                            }
                        }

                        int v = response[y, x] = (int)sum;

                        if (v > max)
                        {
                            max = v;
                        }
                        if (v < min)
                        {
                            min = v;
                        }
                    }
                }

                src += srcOffset;
            }


            byte *dst       = (byte *)destinationData.ImageData.ToPointer();
            int   pixelSize = System.Drawing.Image.GetPixelFormatSize(destinationData.PixelFormat) / 8;
            int   dstStride = destinationData.Stride;
            int   dstOffset = dstStride - width * pixelSize;

            if (destinationData.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                // for each image row
                for (int y = 0; y < height; y++)
                {
                    // for each pixel in the row
                    for (int x = 0; x < width; x++, dst++)
                    {
                        *dst = (byte)((255 * (response[y, x] - min)) / (max - min));
                    }

                    dst += dstOffset;
                }
            }
            else
            {
                // for each image row
                for (int y = 0; y < height; y++)
                {
                    // for each pixel in the row
                    for (int x = 0; x < width; x++, dst += pixelSize)
                    {
                        int v = response[y, x];

                        if (v > 0)
                        {
                            dst[RGB.R] = (byte)((255 * v) / max);
                        }
                        else // (v <= 0)
                        {
                            dst[RGB.B] = (byte)((255 * v) / min);
                        }
                    }

                    dst += dstOffset;
                }
            }
        }