예제 #1
0
        // Write additional observations besides distance (3D) or first
        // observation (2D), using either the originally added points or
        // the points calculated in Process().

        public virtual void Write(ChannelGrid grid, int channel, float value)
        {
            foreach (Vector2Int p in m_UniqueGridPoints)
            {
                grid.Write(channel, p, value);
            }
        }
예제 #2
0
        public override void Initialize(ChannelGrid grid)
        {
            base.Initialize(grid);

            // 0: point z
            // 1: kernel value (max)
            // 2: dilated z (max)
            m_AuxGrid = new ChannelGrid(3, grid.Width, grid.Height);
            m_Kernels = new List <Point> [c_MaxRadius];

            for (int r = 1; r <= c_MaxRadius; r++)
            {
                int i = r - 1;
                m_Kernels[i] = new List <Point>(r * r * 4);

                for (int x = -r; x <= r; x++)
                {
                    for (int y = -r; y <= r; y++)
                    {
                        float value = 1 - new Vector2(x, y).magnitude / r;

                        if (value > 0)
                        {
                            m_Kernels[i].Add(new Point
                            {
                                x     = x,
                                y     = y,
                                value = value
                            });
                        }
                    }
                }
            }
        }
예제 #3
0
        public override void Initialize(ChannelGrid grid)
        {
            base.Initialize(grid);

            m_Samples = new float[
                Mathf.CeilToInt(grid.Width / 2f),
                Mathf.CeilToInt(grid.Height / 2f)];
        }
예제 #4
0
        public override void Process(ChannelGrid grid, int channel)
        {
            float s = Mathf.Sqrt(Width * Height / (float)m_UniqueGridPoints.Count);

            if (s > 1)
            {
                s *= c_SizeMult;

                foreach (Vector2Int p in m_UniqueGridPoints)
                {
                    int   gx     = p.x;
                    int   gy     = p.y;
                    float v      = grid.Read(channel, gx, gy);
                    float invZ   = 1 - m_AuxGrid.Read(0, gx, gy);
                    var   kernel = m_Kernels[Mathf.Min(Mathf.RoundToInt(s * invZ), c_MaxRadius - 1)];

                    for (int i = 0, n = kernel.Count; i < n; i++)
                    {
                        int x = gx + kernel[i].x;
                        int y = gy + kernel[i].y;

                        if (m_AuxGrid.TryRead(1, x, y, out float k))
                        {
                            m_AuxGrid.Write(1, x, y, Mathf.Max(kernel[i].value, k));
                            m_AuxGrid.Write(2, x, y, Mathf.Max(m_AuxGrid.Read(2, x, y), v));
                            Expand(x, y);
                        }
                    }
                }

                for (int x = m_xMin; x <= m_xMax; x++)
                {
                    for (int y = m_yMin; y <= m_yMax; y++)
                    {
                        if (m_AuxGrid.Read(1, x, y) > c_Threshold)
                        {
                            grid.Write(channel, x, y, m_AuxGrid.Read(2, x, y));
                            m_UniqueGridPoints.Add(new Vector2Int(x, y));
                        }
                    }
                }
            }
        }
예제 #5
0
        public static IDictionary <string, ShapeModifier> CreateModifiers(
            IEncodingSettings settings, ChannelGrid grid)
        {
            var modifiers = new Dictionary <string, ShapeModifier>();

            foreach (string tag in settings.DetectableTags)
            {
                ShapeModifier modifier = settings.GetShapeModifierType(tag) switch
                {
                    ShapeModifierType.Dilation => new ShapeModDilation(),
                    ShapeModifierType.Downsampling => new ShapeModDownsampling(),
                    ShapeModifierType.OrthogonalFill => new ShapeModOrthogonalFill(),
                    ShapeModifierType.DiagonalFill => new ShapeModDiagonalFill(),
                    _ => new ShapeModNone(),
                };
                modifier.Initialize(grid);
                modifiers.Add(tag, modifier);
            }

            return(modifiers);
        }
예제 #6
0
        public override void Process(ChannelGrid grid, int channel)
        {
            if (Width > Height)
            {
                int   cx    = (m_xMin + m_xMax) / 2;
                float value = 0;

                for (int x = m_xMin + 1; x <= cx; x++)
                {
                    for (int y = m_yMin; y <= m_yMax; y++)
                    {
                        float v = grid.Read(channel, x, y);

                        if (v == 0)
                        {
                            int xp = x - 1;
                            v = grid.Read(channel, xp, y);

                            if (y > m_yMin)
                            {
                                v = Mathf.Max(v, grid.Read(channel, xp, y - 1));
                            }
                            if (y < m_yMax)
                            {
                                v = Mathf.Max(v, grid.Read(channel, xp, y + 1));
                            }

                            if (v > 0)
                            {
                                grid.Write(channel, x, y, v);
                                m_UniqueGridPoints.Add(new Vector2Int(x, y));
                                value = v;
                            }
                        }
                        else
                        {
                            grid.Write(channel, x, y, Mathf.Max(value, v));
                        }
                    }
                }

                value = 0;

                for (int x = m_xMax - 1; x > cx; x--)
                {
                    for (int y = m_yMin; y <= m_yMax; y++)
                    {
                        float v = grid.Read(channel, x, y);

                        if (v == 0)
                        {
                            int xp = x + 1;
                            v = grid.Read(channel, xp, y);

                            if (y > m_yMin)
                            {
                                v = Mathf.Max(v, grid.Read(channel, xp, y - 1));
                            }
                            if (y < m_yMax)
                            {
                                v = Mathf.Max(v, grid.Read(channel, xp, y + 1));
                            }

                            if (v > 0)
                            {
                                grid.Write(channel, x, y, v);
                                m_UniqueGridPoints.Add(new Vector2Int(x, y));
                                value = v;
                            }
                        }
                        else
                        {
                            grid.Write(channel, x, y, Mathf.Max(value, v));
                        }
                    }
                }
            }
            else
            {
                int   cy    = (m_yMin + m_yMax) / 2;
                float value = 0;

                for (int y = m_yMin + 1; y <= cy; y++)
                {
                    for (int x = m_xMin; x <= m_xMax; x++)
                    {
                        float v = grid.Read(channel, x, y);

                        if (v == 0)
                        {
                            int yp = y - 1;
                            v = grid.Read(channel, x, yp);

                            if (x > m_xMin)
                            {
                                v = Mathf.Max(v, grid.Read(channel, x - 1, yp));
                            }
                            if (x < m_xMax)
                            {
                                v = Mathf.Max(v, grid.Read(channel, x + 1, yp));
                            }

                            if (v > 0)
                            {
                                grid.Write(channel, x, y, v);
                                m_UniqueGridPoints.Add(new Vector2Int(x, y));
                                value = v;
                            }
                        }
                        else
                        {
                            grid.Write(channel, x, y, Mathf.Max(value, v));
                        }
                    }
                }

                value = 0;

                for (int y = m_yMax - 1; y > cy; y--)
                {
                    for (int x = m_xMin; x <= m_xMax; x++)
                    {
                        float v = grid.Read(channel, x, y);

                        if (v == 0)
                        {
                            int yp = y + 1;
                            v = grid.Read(channel, x, yp);

                            if (x > m_xMin)
                            {
                                v = Mathf.Max(v, grid.Read(channel, x - 1, yp));
                            }
                            if (x < m_xMax)
                            {
                                v = Mathf.Max(v, grid.Read(channel, x + 1, yp));
                            }

                            if (v > 0)
                            {
                                grid.Write(channel, x, y, v);
                                m_UniqueGridPoints.Add(new Vector2Int(x, y));
                                value = v;
                            }
                        }
                        else
                        {
                            grid.Write(channel, x, y, Mathf.Max(value, v));
                        }
                    }
                }
            }
        }
예제 #7
0
        public override void Process(ChannelGrid grid, int channel)
        {
            int cx = (m_xMin + m_xMax) / 2;
            int cy = (m_yMin + m_yMax) / 2;

            float value = 0;

            for (int x = m_xMin; x <= cx; x++)
            {
                int xp = Mathf.Max(m_xMin, x - 1);

                for (int y = m_yMin; y <= cy; y++)
                {
                    float v = grid.Read(channel, x, y);

                    if (v == 0)
                    {
                        int yp = Mathf.Max(m_yMin, y - 1);

                        v = Mathf.Max(
                            grid.Read(channel, xp, y),
                            grid.Read(channel, x, yp),
                            grid.Read(channel, xp, yp));

                        if (v > 0)
                        {
                            grid.Write(channel, x, y, v);
                            m_UniqueGridPoints.Add(new Vector2Int(x, y));
                            value = v;
                        }
                    }
                    else
                    {
                        grid.Write(channel, x, y, Mathf.Max(value, v));
                    }
                }
            }

            value = 0;

            for (int x = m_xMax; x > cx; x--)
            {
                int xp = Mathf.Min(m_xMax, x + 1);

                for (int y = m_yMin; y <= cy; y++)
                {
                    float v = grid.Read(channel, x, y);

                    if (v == 0)
                    {
                        int yp = Mathf.Max(m_yMin, y - 1);

                        v = Mathf.Max(
                            grid.Read(channel, xp, y),
                            grid.Read(channel, x, yp),
                            grid.Read(channel, xp, yp));

                        if (v > 0)
                        {
                            grid.Write(channel, x, y, v);
                            m_UniqueGridPoints.Add(new Vector2Int(x, y));
                            value = v;
                        }
                    }
                    else
                    {
                        grid.Write(channel, x, y, Mathf.Max(value, v));
                    }
                }
            }

            value = 0;

            for (int x = m_xMin; x <= cx; x++)
            {
                int xp = Mathf.Max(m_xMin, x - 1);

                for (int y = m_yMax; y > cy; y--)
                {
                    float v = grid.Read(channel, x, y);

                    if (v == 0)
                    {
                        int yp = Mathf.Min(m_yMax, y + 1);

                        v = Mathf.Max(
                            grid.Read(channel, xp, y),
                            grid.Read(channel, x, yp),
                            grid.Read(channel, xp, yp));

                        if (v > 0)
                        {
                            grid.Write(channel, x, y, v);
                            m_UniqueGridPoints.Add(new Vector2Int(x, y));
                            value = v;
                        }
                    }
                    else
                    {
                        grid.Write(channel, x, y, Mathf.Max(value, v));
                    }
                }
            }

            value = 0;

            for (int x = m_xMax; x > cx; x--)
            {
                int xp = Mathf.Min(m_xMax, x + 1);

                for (int y = m_yMax; y > cy; y--)
                {
                    float v = grid.Read(channel, x, y);

                    if (v == 0)
                    {
                        int yp = Mathf.Min(m_yMax, y + 1);

                        v = Mathf.Max(
                            grid.Read(channel, xp, y),
                            grid.Read(channel, x, yp),
                            grid.Read(channel, xp, yp));

                        if (v > 0)
                        {
                            grid.Write(channel, x, y, v);
                            m_UniqueGridPoints.Add(new Vector2Int(x, y));
                            value = v;
                        }
                    }
                    else
                    {
                        grid.Write(channel, x, y, Mathf.Max(value, v));
                    }
                }
            }
        }
예제 #8
0
 public virtual void Process(ChannelGrid grid, int channel)
 {
 }
예제 #9
0
 public virtual void Initialize(ChannelGrid grid)
 {
     // TODO Capacity? https://stackoverflow.com/a/23071206
     m_UniqueGridPoints = new HashSet <Vector2Int>();
 }
예제 #10
0
        public override void Process(ChannelGrid grid, int channel)
        {
            // Side length of squares around points required for filling w * h,
            // *if* points were distributed evenly. We're adding some value
            // to this below for preventing gaps.
            int   w = Width;
            int   h = Height;
            float s = Mathf.Sqrt(w * h / (float)m_UniqueGridPoints.Count);

            if (s > 1)
            {
                int size = Mathf.RoundToInt(s) + 2; // TBD add. value

                // Bottom/left offset (padding).
                int xPad = m_xMin - (size - w % size) / 2;
                int yPad = m_yMin - (size - h % size) / 2;

                int nx = 0, ny = 0;
                foreach (Vector2Int p in m_UniqueGridPoints)
                {
                    int sx = (p.x - xPad) / size;
                    int sy = (p.y - yPad) / size;
                    nx = Mathf.Max(nx, sx);
                    ny = Mathf.Max(ny, sy);
                    // For 3D, we sample the max (closest) value.
                    // For 2D, point values are identical anyway.
                    m_Samples[sx, sy] = Mathf.Max(m_Samples[sx, sy], grid.Read(channel, p));
                }

                // Replace grid points with squares (size x size).
                m_UniqueGridPoints.Clear();

                for (int sx = 0; sx <= nx; sx++)
                {
                    for (int sy = 0; sy <= ny; sy++)
                    {
                        float value = m_Samples[sx, sy];

                        if (value > 0)
                        {
                            int gx = xPad + sx * size;
                            int gy = yPad + sy * size;

                            for (int x = 0; x < size; x++)
                            {
                                for (int y = 0; y < size; y++)
                                {
                                    Vector2Int p = new Vector2Int(gx + x, gy + y);
                                    if (grid.TryRead(channel, p, out float prev))
                                    {
                                        // 3D: storing max value for distance channel (closest).
                                        // TODO
                                        // 2D: neighbouring down-sampled areas might overlap and
                                        // their max value isn't necessarily what we want to observe?
                                        grid.Write(channel, p, Mathf.Max(prev, value));
                                        m_UniqueGridPoints.Add(p);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            // else: keep original points.
        }