Example #1
0
        /// <summary>
        ///   Constructs a new Integral image from a Bitmap image.
        /// </summary>
        ///
        /// <param name="image">The source image from where the integral image should be computed.</param>
        /// <param name="channel">The image channel to consider in the computations. Default is 0.</param>
        /// <param name="computeTilted"><c>True</c> to compute the tilted version of the integral image,
        ///   <c>false</c> otherwise. Default is false.</param>
        ///
        /// <returns>
        ///   The <see cref="IntegralImage2"/> representation of
        ///   the <paramref name="image">source image</paramref>.</returns>
        ///
        public static IntegralImage2 FromBitmap(Bitmap image, int channel, bool computeTilted)
        {
            // check image format
            if (!(image.PixelFormat == PixelFormat.Format8bppIndexed ||
                  image.PixelFormat == PixelFormat.Format24bppRgb ||
                  image.PixelFormat == PixelFormat.Format32bppArgb ||
                  image.PixelFormat == PixelFormat.Format32bppRgb))
            {
                throw new UnsupportedImageFormatException("Only grayscale, 24 and 32 bpp RGB images are supported.");
            }


            // lock source image
            BitmapData imageData = image.LockBits(
                new Rectangle(0, 0, image.Width, image.Height),
                ImageLockMode.ReadOnly, image.PixelFormat);

            // process the image
            IntegralImage2 im = FromBitmap(imageData, channel, computeTilted);

            // unlock image
            image.UnlockBits(imageData);

            return(im);
        }
Example #2
0
        /// <summary>
        ///   Constructs a new Integral image from an unmanaged image.
        /// </summary>
        ///
        /// <param name="image">The source image from where the integral image should be computed.</param>
        /// <param name="channel">The image channel to consider in the computations. Default is 0.</param>
        /// <param name="computeTilted"><c>True</c> to compute the tilted version of the integral image,
        ///   <c>false</c> otherwise. Default is false.</param>
        ///
        /// <returns>
        ///   The <see cref="IntegralImage2"/> representation of
        ///   the <paramref name="image">source image</paramref>.</returns>
        ///
        public static IntegralImage2 FromBitmap(UnmanagedImage image, int channel, bool computeTilted)
        {
            // check image format
            if (!(image.PixelFormat == PixelFormat.Format8bppIndexed ||
                  image.PixelFormat == PixelFormat.Format24bppRgb ||
                  image.PixelFormat == PixelFormat.Format32bppArgb ||
                  image.PixelFormat == PixelFormat.Format32bppRgb))
            {
                throw new UnsupportedImageFormatException("Only grayscale, 24 and 32 bpp RGB images are supported.");
            }

            int pixelSize = System.Drawing.Image.GetPixelFormatSize(image.PixelFormat) / 8;

            // get source image size
            int width  = image.Width;
            int height = image.Height;
            int stride = image.Stride;
            int offset = stride - width * pixelSize;

            // create integral image
            IntegralImage2 im   = new IntegralImage2(width, height, computeTilted);
            long *         nSum = im.nSum;
            long *         sSum = im.sSum;
            long *         tSum = im.tSum;

            int nWidth = im.nWidth;
            int tWidth = im.tWidth;

            if (image.PixelFormat == PixelFormat.Format8bppIndexed && channel != 0)
            {
                throw new ArgumentException("Only the first channel is available for 8 bpp images.", "channel");
            }

            byte *srcStart = (byte *)image.ImageData.ToPointer() + channel;

            // do the job
            byte *src = srcStart;

            // for each line
            for (int y = 1; y <= height; y++)
            {
                int yy = nWidth * (y);
                int y1 = nWidth * (y - 1);

                // for each pixel
                for (int x = 1; x <= width; x++, src += pixelSize)
                {
                    long p1 = *src;
                    long p2 = p1 * p1;

                    int r = yy + (x);
                    int a = yy + (x - 1);
                    int b = y1 + (x);
                    int c = y1 + (x - 1);

                    nSum[r] = p1 + nSum[a] + nSum[b] - nSum[c];
                    sSum[r] = p2 + sSum[a] + sSum[b] - sSum[c];
                }
                src += offset;
            }


            if (computeTilted)
            {
                src = srcStart;

                // Left-to-right, top-to-bottom pass
                for (int y = 1; y <= height; y++, src += offset)
                {
                    int yy = tWidth * (y);
                    int y1 = tWidth * (y - 1);

                    for (int x = 2; x < width + 2; x++, src += pixelSize)
                    {
                        int a = y1 + (x - 1);
                        int b = yy + (x - 1);
                        int c = y1 + (x - 2);
                        int r = yy + (x);

                        tSum[r] = *src + tSum[a] + tSum[b] - tSum[c];
                    }
                }

                {
                    int yy = tWidth * (height);
                    int y1 = tWidth * (height + 1);

                    for (int x = 2; x < width + 2; x++, src += pixelSize)
                    {
                        int a = yy + (x - 1);
                        int c = yy + (x - 2);
                        int b = y1 + (x - 1);
                        int r = y1 + (x);

                        tSum[r] = tSum[a] + tSum[b] - tSum[c];
                    }
                }


                // Right-to-left, bottom-to-top pass
                for (int y = height; y >= 0; y--)
                {
                    int yy = tWidth * (y);
                    int y1 = tWidth * (y + 1);

                    for (int x = width + 1; x >= 1; x--)
                    {
                        int r = yy + (x);
                        int b = y1 + (x - 1);

                        tSum[r] += tSum[b];
                    }
                }

                for (int y = height + 1; y >= 0; y--)
                {
                    int yy = tWidth * (y);

                    for (int x = width + 1; x >= 2; x--)
                    {
                        int r = yy + (x);
                        int b = yy + (x - 2);

                        tSum[r] -= tSum[b];
                    }
                }
            }


            return(im);
        }