예제 #1
0
        public FloatImage Convolve(FloatImage k)
        {
            var kw  = k.Width;
            var kh  = k.Height;
            var kxs = kw >> 1;
            var kys = kh >> 1;

            var   r     = new FloatImage(_Width, _Height);
            float total = k.Sum();

            for (var dy = 0; dy < _Height; dy++)
            {
                for (var dx = 0; dx < _Width; dx++)
                {
                    var v   = 0f;
                    var sum = 0f;
                    for (var ky = 0; ky < kh; ky++)
                    {
                        var sy = dy + ky - kys;
                        if (sy < 0 || _Height <= sy)
                        {
                            continue;
                        }

                        for (var kx = 0; kx < kh; kx++)
                        {
                            var sx = dx + kx - kxs;
                            if (sx < 0 || _Width <= sx)
                            {
                                continue;
                            }
                            var sv = this[sx, sy];
                            var kv = k[kx, ky];
                            v   += sv * kv;
                            sum += kv;
                        }
                    }

                    r[dx, dy] = total == sum ? v : (v * total / sum);
                }
            }

            return(r);
        }
예제 #2
0
        public void Test(int seed, int width)
        {
            _Output.WriteLine("Vector<float>.Count: {0}", Vector <float> .Count);
            _Output.WriteLine("Vector.IsHardwareAccelerated: {0}", Vector.IsHardwareAccelerated);

            var r = new Random(seed);

            var src = new ByteImage(1280, 720);

            r.NextBytes(src.Array);

            var ker = new FloatImage(width, 10);
            var sum = 0f;

            for (var i = 0; i < ker.Array.Length; i++)
            {
                sum += ker.Array[i] = (float)r.NextDouble();
            }
            ker.MultiplyInplace(1 / sum);

            var wrapper = new ByteImageWrapper(src);

            var sw = new Stopwatch();

            sw.Start();
            var expected = ByteImageOperations <ByteImageWrapper> .ConvolveSingle(wrapper, ker, ker.Width, ker.Height);

            sw.Stop();
            _Output.WriteLine("interface: " + sw.ElapsedMilliseconds + "ms");

            sw.Reset();
            sw.Start();
            var actual = new ByteImageOperations <ByteImageWrapper>().Convolve(wrapper, ker);

            sw.Stop();
            _Output.WriteLine("Vector<float>: " + sw.ElapsedMilliseconds + "ms");

            for (var i = 0; i < expected.Array.Length; i++)
            {
                Assert.Equal(
                    0,
                    (expected.Array[i] - actual.Array[i]) / expected.Array[i], 4);
            }
        }
예제 #3
0
        internal static FloatImage ConvolveSingle(T image, FloatImage kernel, int kernelWidth, int kernelHeight)
        {
            var kernelXRadius = kernel.Width >> 1;
            var kernelYRadius = kernelHeight >> 1;

            var   r     = new FloatImage(image.Width, image.Height);
            float total = kernel.Sum();

            for (var dy = 0; dy < image.Height; dy++)
            {
                for (var dx = 0; dx < image.Width; dx++)
                {
                    var v   = 0f;
                    var sum = 0f;
                    for (var ky = 0; ky < kernelHeight; ky++)
                    {
                        var sy = dy + ky - kernelYRadius;
                        if (sy < 0 || image.Height <= sy)
                        {
                            continue;
                        }

                        for (var kx = 0; kx < kernelWidth; kx++)
                        {
                            var sx = dx + kx - kernelXRadius;
                            if (sx < 0 || image.Width <= sx)
                            {
                                continue;
                            }

                            var sv = image[sx, sy];
                            var kv = kernel[kx, ky];
                            v   += sv * kv;
                            sum += kv;
                        }
                    }

                    r[dx, dy] = total == sum ? v : (v * total / sum);
                }
            }

            return(r);
        }
예제 #4
0
        public void MultiplyInplaceTest(int width)
        {
            _Output.WriteLine("Vector<float>.Count: {0}", Vector <float> .Count);
            _Output.WriteLine("Vector.IsHardwareAccelerated: {0}", Vector.IsHardwareAccelerated);

            var src = new FloatImage(width, 1);

            for (var i = 0; i < src.Array.Length; i++)
            {
                src.Array[i] = i + 1;
            }

            src.MultiplyInplace(2);

            for (var i = 0; i < src.Array.Length; i++)
            {
                Assert.Equal(src.Array[i], 2 * (i + 1), 7);
            }
        }
예제 #5
0
파일: FloatImage.cs 프로젝트: zmarty/phash
        public FloatImage Resize(int w, int h)
        {
            // TODO:bilinearにする

            var r  = new FloatImage(w, h);
            var xr = w / (float)_Width;
            var yr = h / (float)_Height;

            for (var sy = 0; sy < _Height; sy++)
            {
                var dy = (int)Math.Max(0, Math.Min(sy * yr, h - 1));
                for (var sx = 0; sx < _Width; sx++)
                {
                    var dx = (int)Math.Max(0, Math.Min(sx * xr, w - 1));

                    r[dx, dy] += this[sx, sy];
                }
            }

            return(r);
        }
예제 #6
0
 FloatImage IByteImageOperations.Convolve(IByteImageWrapper image, FloatImage kernel)
 => Convolve((T)image, kernel);
예제 #7
0
 public FloatImage Blur(double sigma)
 => Convolve(FloatImage.CreateGaussian(3, sigma));
예제 #8
0
 public Projections(int regionWidth, int regionHeight, int lineCount)
 {
     Region        = new Imaging.FloatImage(regionWidth, regionHeight);
     PixelsPerLine = new int[lineCount];
 }