/// <summary>
        /// Creates a morphological structuring element of type
        /// 'arbitrary'.
        /// </summary>
        /// <remarks>
        /// <paramref name="nhood"/> is a matrix containing 1s and 0s.
        /// The locations of 1s define the neighborhood for the
        /// morphological operator. The origin of
        /// <paramref name="nhood"/> is its center element.
        /// </remarks>
        /// <param name="nhood"></param>
        /// <returns>
        /// The created <see cref="StructuringElement"/>.
        /// </returns>
        public static StructuringElement CreateArbitrary(Matrix nhood)
        {
            StructuringElement se = new StructuringElement();

            se.nhood = nhood;

            /*int height = nhood.Height;
             * int width = nhood.Width;
             *
             * if (neighborhood.All && height > 1 && width > 1)
             * {
             *      // The structuring element has an all-ones neighborhood.
             *      // Decide if the SE should be decomposed.
             *
             *      int advantage = (height * width) / (height + width);
             *
             *      // Heuristic: if the theoretical computation advantage is
             *      // minimum a factor of 2, then we assume that the overhead cost
             *      // is worth to execute dilation or erosion twice.
             *      if (advantage >= 2) {
             *              Matrix sed1 = Matrix.Ones(height, 1);
             *              Matrix sed2 = Matrix.Ones(1, width);
             *
             *              // TODO: add SEDs to queue
             *      }
             * }*/

            return(se);
        }
        /// <summary>
        /// Creates a morphological structuring element of type
        /// 'octagon'.
        /// </summary>
        /// <example>
        /// StructuringElement.CreateOctagon(3);
        /// Neighborhood =
        ///       |- 3 -|
        /// 0,0,1,1,1,0,0  -
        /// 0,1,1,1,1,1,0  3
        /// 1,1,1,1,1,1,1  |
        /// 1,1,1,1,1,1,1  -
        /// 1,1,1,1,1,1,1
        /// 0,1,1,1,1,1,0
        /// 0,0,1,1,1,0,0
        /// </example>
        /// <param name="radius">
        /// Specifies the distance from the origin to the border.
        /// </param>
        /// <returns>
        /// The created <see cref="StructuringElement"/>.
        /// </returns>
        public static StructuringElement CreateOctagon(byte radius)
        {
            int    length = 2 * radius + 1;
            Matrix rr     = new Matrix(length, length);
            Matrix cc     = new Matrix(length, length);

            byte idx_off = 0;

            //rr.BeginLoadData();
            //cc.BeginLoadData();

            for (int r = 0; r < length; r++)
            {
                idx_off = radius;

                while (idx_off > 0)
                {
                    rr[radius - idx_off, r] = idx_off;
                    rr[radius + idx_off, r] = idx_off;

                    cc[r, radius - idx_off] = idx_off;
                    cc[r, radius + idx_off] = idx_off;

                    idx_off--;
                }
            }

            //rr.EndLoadData();
            //cc.EndLoadData();

            byte k = (byte)(radius / 3);

            Matrix oct = rr + cc;

            oct = (oct <= (radius + k));

            Console.WriteLine(rr.ToString());
            Console.WriteLine(cc.ToString());
            Console.WriteLine(oct.ToString());

            StructuringElement se = new StructuringElement();

            se.nhood = oct;

            return(se);
        }
        /// <summary>
        /// Creates a morphological structuring element of type
        /// 'diamond'.
        /// </summary>
        /// <example>
        /// StructuringElement.CreateDiamond(4);
        /// Neighborhood =
        ///         |-- 4 --|
        /// 0,0,0,0,1,0,0,0,0  -
        /// 0,0,0,1,1,1,0,0,0  |
        /// 0,0,1,1,1,1,1,0,0  4
        /// 0,1,1,1,1,1,1,1,0  |
        /// 1,1,1,1,1,1,1,1,1  -
        /// 0,1,1,1,1,1,1,1,0
        /// 0,0,1,1,1,1,1,0,0
        /// 0,0,0,1,1,1,0,0,0
        /// 0,0,0,0,1,0,0,0,0
        /// </example>
        /// <param name="radius">
        /// Specifies the distance from the origin to the border.
        /// </param>
        /// <returns>
        /// The created <see cref="StructuringElement"/>.
        /// </returns>
        public static StructuringElement CreateDiamond(byte radius)
        {
            int    length = 2 * radius + 1;
            Matrix rr     = new Matrix(length, length);
            Matrix cc     = new Matrix(length, length);

            byte idx_off = 0;

            //rr.BeginLoadData();
            //cc.BeginLoadData();

            for (int r = 0; r < length; r++)
            {
                idx_off = radius;

                while (idx_off > 0)
                {
                    rr[radius - idx_off, r] = idx_off;
                    rr[radius + idx_off, r] = idx_off;

                    cc[r, radius - idx_off] = idx_off;
                    cc[r, radius + idx_off] = idx_off;

                    idx_off--;
                }
            }

            //rr.EndLoadData();
            //cc.EndLoadData();

            Matrix diamond = rr + cc;

            diamond = (diamond <= radius);

            Console.WriteLine(rr.ToString());
            Console.WriteLine(cc.ToString());
            Console.WriteLine(diamond.ToString());

            StructuringElement se = new StructuringElement();

            se.nhood = diamond;

            return(se);
        }
        /*public static StructuringElement CreateLine (ushort length,
         *                                           byte angle)
         * {
         *      float theta = (float)((angle * System.Math.PI) / 180.0);
         *      double sin_theta = System.Math.Sin(theta);
         *      double cos_theta = System.Math.Cos(theta);
         *      int x2 = (int)System.Math.Round((length / 2) * cos_theta);
         *      int y2 = -(int)System.Math.Round((length / 2) * sin_theta);
         *
         *      int x1 = -x2;
         *      int y1 = -y2;
         *
         *      int dx = System.Math.Abs(x2 - x1);
         *      int dy = System.Math.Abs(y2 - y1);
         *
         *      StructuringElement se = new StructuringElement();
         *      //se.nhood = pair;
         *      return se;
         * }*/

        /// <summary>
        /// Creates a morphological structuring element of type
        /// 'periodic line' with 2 * <paramref name="el"/> + 1 elements
        /// which have a logical '1' value.
        /// </summary>
        /// <example>
        /// StructuringElement.CreatePeriodicLine(2, 2, 1);
        /// Neighborhood =
        /// 1,0,0,0,0,0,0,0,0
        /// 0,0,1,0,0,0,0,0,0
        /// 0,0,0,0,1,0,0,0,0
        /// 0,0,0,0,0,0,1,0,0
        /// 0,0,0,0,0,0,0,0,1
        /// </example>
        /// <param name="el">
        /// The SE will have 2 * el + 1 elements which have a logical
        /// '1' value.
        /// </param>
        /// <param name="xOff">
        /// The column offset between two '1' elements.
        /// </param>
        /// <param name="yOff">
        /// The row offset between two '1' elements.
        /// </param>
        /// <returns>
        /// The created <see cref="StructuringElement"/>.
        /// </returns>
        public static StructuringElement CreatePeriodicLine(ushort el,
                                                            short xOff,
                                                            short yOff)
        {
            int    length = 2 * el + 1;
            int    colMax = 0;
            int    rowMax = 0;
            Matrix idx    = new Matrix(length, 2);

            for (int i = 0; i < length; i++)
            {
                byte c = (byte)((i - el) * xOff);
                byte r = (byte)((i - el) * yOff);
                idx[0, i] = c;
                idx[1, i] = r;

                colMax = (c > colMax) ? c : colMax;
                rowMax = (r > rowMax) ? r : rowMax;
            }

            int cols = 2 * colMax + 1;
            int rows = 2 * rowMax + 1;

            Matrix nhood = new Matrix(rows, cols);

            for (int r = 0; r < length; r++)
            {
                int x = idx[0, r] + colMax;
                int y = idx[1, r] + rowMax;
                nhood[x, y] = 1;
            }

            Console.WriteLine(nhood.ToString());

            StructuringElement se = new StructuringElement();

            se.nhood = nhood;
            return(se);
        }
        /// <summary>
        /// Creates a morphological structuring element of type 'pair'
        /// with 2 elements which have a logical '1' value. One of
        /// these 2 elements is the origin in the center of the SE,
        /// the other one is positioned with <paramref name="xOff"/>
        /// and <paramref name="yOff"/> relatively to the origin.
        /// </summary>
        /// <example>
        /// StructuringElement.CreatePair(-2, -3);
        /// Neighborhood =
        /// 1,0,0,0,0
        /// 0,0,0,0,0
        /// 0,0,0,0,0
        /// 0,0,1,0,0
        /// 0,0,0,0,0
        /// 0,0,0,0,0
        /// 0,0,0,0,0
        /// </example>
        /// <param name="xOff">
        /// The column offset between the origin and the second element
        /// </param>
        /// <param name="yOff">
        /// The row offset between the origin and the second element.
        /// </param>
        /// <returns></returns>
        public static StructuringElement CreatePair(short xOff,
                                                    short yOff)
        {
            int xAbsOff = System.Math.Abs(xOff);
            int yAbsOff = System.Math.Abs(yOff);

            int width  = xAbsOff * 2 + 1;
            int height = yAbsOff * 2 + 1;

            Matrix pair = new Matrix(height, width);

            //pair.BeginLoadData ();
            pair [xAbsOff, yAbsOff] = 1;             //origin
            pair [xAbsOff + xOff, yAbsOff + yOff] = 1;
            //pair.EndLoadData ();

            Console.WriteLine(pair.ToString());

            StructuringElement se = new StructuringElement();

            se.nhood = pair;
            return(se);
        }