Accord.Imaging.UnmanagedImage.Create C# (CSharp) Method

Create() public static method

Allocate new image in unmanaged memory.

Allocate new image with specified attributes in unmanaged memory.

The method supports only Format8bppIndexed, Format16bppGrayScale, Format24bppRgb, Format32bppRgb, Format32bppArgb, Format32bppPArgb, Format48bppRgb, Format64bppArgb and Format64bppPArgb pixel formats. In the case if Format8bppIndexed format is specified, pallete is not not created for the image (supposed that it is 8 bpp grayscale image).

Unsupported pixel format was specified. Invalid image size was specified.
public static Create ( int width, int height, PixelFormat pixelFormat ) : UnmanagedImage
width int Image width.
height int Image height.
pixelFormat PixelFormat Image pixel format.
return UnmanagedImage
        public static UnmanagedImage Create(int width, int height, PixelFormat pixelFormat)
        {
            int bytesPerPixel = 0;

            // calculate bytes per pixel
            switch (pixelFormat)
            {
                case PixelFormat.Format8bppIndexed:
                    bytesPerPixel = 1;
                    break;
                case PixelFormat.Format16bppGrayScale:
                    bytesPerPixel = 2;
                    break;
                case PixelFormat.Format24bppRgb:
                    bytesPerPixel = 3;
                    break;
                case PixelFormat.Format32bppRgb:
                case PixelFormat.Format32bppArgb:
                case PixelFormat.Format32bppPArgb:
                    bytesPerPixel = 4;
                    break;
                case PixelFormat.Format48bppRgb:
                    bytesPerPixel = 6;
                    break;
                case PixelFormat.Format64bppArgb:
                case PixelFormat.Format64bppPArgb:
                    bytesPerPixel = 8;
                    break;
                default:
                    throw new UnsupportedImageFormatException("Can not create image with specified pixel format.");
            }

            // check image size
            if ((width <= 0) || (height <= 0))
            {
                throw new InvalidImagePropertiesException("Invalid image size specified.");
            }

            // calculate stride
            int stride = width * bytesPerPixel;

            if (stride % 4 != 0)
            {
                stride += (4 - (stride % 4));
            }

            // allocate memory for the image
            IntPtr imageData = System.Runtime.InteropServices.Marshal.AllocHGlobal(stride * height);
            Accord.SystemTools.SetUnmanagedMemory(imageData, 0, stride * height);
            System.GC.AddMemoryPressure(stride * height);

            UnmanagedImage image = new UnmanagedImage(imageData, width, height, stride, pixelFormat);
            image.mustBeDisposed = true;

            return image;
        }

Usage Example

コード例 #1
0
        /// <summary>
        /// Process image looking for corners.
        /// </summary>
        ///
        /// <param name="image">Source image data to process.</param>
        ///
        /// <returns>Returns list of found corners (X-Y coordinates).</returns>
        ///
        /// <exception cref="UnsupportedImageFormatException">
        ///   The source image has incorrect pixel format.
        /// </exception>
        ///
        public List <IntPoint> ProcessImage(UnmanagedImage image)
        {
            // check image format
            if (
                (image.PixelFormat != PixelFormat.Format8bppIndexed) &&
                (image.PixelFormat != PixelFormat.Format24bppRgb) &&
                (image.PixelFormat != PixelFormat.Format32bppRgb) &&
                (image.PixelFormat != PixelFormat.Format32bppArgb)
                )
            {
                throw new UnsupportedImageFormatException("Unsupported pixel format of the source image.");
            }

            // make sure we have grayscale image
            UnmanagedImage grayImage = null;

            if (image.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                grayImage = image;
            }
            else
            {
                // create temporary grayscale image
                grayImage = Grayscale.CommonAlgorithms.BT709.Apply(image);
            }


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



            // 1. Calculate partial differences
            UnmanagedImage diffx  = UnmanagedImage.Create(width, height, PixelFormat.Format8bppIndexed);
            UnmanagedImage diffy  = UnmanagedImage.Create(width, height, PixelFormat.Format8bppIndexed);
            UnmanagedImage diffxy = UnmanagedImage.Create(width, height, PixelFormat.Format8bppIndexed);

            unsafe
            {
                // Compute dx and dy
                byte *src = (byte *)grayImage.ImageData.ToPointer();
                byte *dx  = (byte *)diffx.ImageData.ToPointer();
                byte *dy  = (byte *)diffy.ImageData.ToPointer();
                byte *dxy = (byte *)diffxy.ImageData.ToPointer();

                // for each line
                for (int y = 0; y < height; y++)
                {
                    // for each pixel
                    for (int x = 0; x < width; x++, src++, dx++, dy++)
                    {
                        // TODO: Place those verifications
                        // outside the innermost loop
                        if (x == 0 || x == width - 1 ||
                            y == 0 || y == height - 1)
                        {
                            *dx = *dy = 0; continue;
                        }

                        int h = -(src[-stride - 1] + src[-1] + src[stride - 1]) +
                                (src[-stride + 1] + src[+1] + src[stride + 1]);
                        *dx = (byte)(h > 255 ? 255 : h < 0 ? 0 : h);

                        int v = -(src[-stride - 1] + src[-stride] + src[-stride + 1]) +
                                (src[+stride - 1] + src[+stride] + src[+stride + 1]);
                        *dy = (byte)(v > 255 ? 255 : v < 0 ? 0 : v);
                    }
                    src += offset;
                    dx  += offset;
                    dy  += offset;
                }


                // Compute dxy
                dx  = (byte *)diffx.ImageData.ToPointer();
                dxy = (byte *)diffxy.ImageData.ToPointer();

                // for each line
                for (int y = 0; y < height; y++)
                {
                    // for each pixel
                    for (int x = 0; x < width; x++, dx++, dxy++)
                    {
                        if (x == 0 || x == width - 1 ||
                            y == 0 || y == height - 1)
                        {
                            *dxy = 0; continue;
                        }

                        int v = -(dx[-stride - 1] + dx[-stride] + dx[-stride + 1]) +
                                (dx[+stride - 1] + dx[+stride] + dx[+stride + 1]);
                        *dxy = (byte)(v > 255 ? 255 : v < 0 ? 0 : v);
                    }
                    dx  += offset;
                    dxy += offset;
                }
            }


            // 2. Smooth the diff images
            if (sigma > 0.0)
            {
                GaussianBlur blur = new GaussianBlur(sigma);
                blur.ApplyInPlace(diffx);
                blur.ApplyInPlace(diffy);
                blur.ApplyInPlace(diffxy);
            }


            // 3. Compute Harris Corner Response
            float[,] H = new float[height, width];

            unsafe
            {
                byte *ptrA = (byte *)diffx.ImageData.ToPointer();
                byte *ptrB = (byte *)diffy.ImageData.ToPointer();
                byte *ptrC = (byte *)diffxy.ImageData.ToPointer();
                float M, A, B, C;

                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        A = *(ptrA++);
                        B = *(ptrB++);
                        C = *(ptrC++);

                        // Harris corner measure
                        M = (A * B - C * C) - (k * ((A + B) * (A + B)));

                        if (M > threshold)
                        {
                            H[y, x] = M;
                        }
                        else
                        {
                            H[y, x] = 0;
                        }
                    }

                    ptrA += offset;
                    ptrB += offset;
                    ptrC += offset;
                }
            }


            // Free resources
            diffx.Dispose();
            diffy.Dispose();
            diffxy.Dispose();

            if (image.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                grayImage.Dispose();
            }


            // 4. Suppress non-maximum points
            List <IntPoint> cornersList = new List <IntPoint>();

            // for each row
            for (int y = r, maxY = height - r; y < maxY; y++)
            {
                // for each pixel
                for (int x = r, maxX = width - r; x < maxX; x++)
                {
                    float currentValue = H[y, x];

                    // for each windows' row
                    for (int i = -r; (currentValue != 0) && (i <= r); i++)
                    {
                        // for each windows' pixel
                        for (int j = -r; j <= r; j++)
                        {
                            if (H[y + i, x + j] > currentValue)
                            {
                                currentValue = 0;
                                break;
                            }
                        }
                    }

                    // check if this point is really interesting
                    if (currentValue != 0)
                    {
                        cornersList.Add(new IntPoint(x, y));
                    }
                }
            }


            return(cornersList);
        }