Beispiel #1
0
        /// <summary>
        /// Any pixel values below threshold will be changed to 0.
        /// Any pixel values above (or equal to) threshold will be changed to 1.
        /// </summary>
        /// <typeparam name="T">Image type to process and return</typeparam>
        /// <param name="image">Image to process</param>
        /// <param name="threshold">Binary threshold</param>
        /// <returns>New image as binary</returns>
        public static T AsImage <T>(T image, byte threshold) where T : Image
        {
            Bitmap binaryBitmap = AsBitmap(image, threshold);

            // Convert to original format
            return((T)ImageFormatting.ToFormat(binaryBitmap, image.RawFormat));
        }
        /// <summary>
        /// Applies localized/adaptive region thresholding to image using Chow & Kaneko method.
        /// </summary>
        /// <typeparam name="T">Image type to process and return</typeparam>
        /// <param name="image">Image to process</param>
        /// <param name="horizontalRegions">Number of horizonal regions to apply</param>
        /// <param name="verticalRegions">Number of veritical regions to apply</param>
        /// <returns>New image with localized threshold applied</returns>
        public static T ApplyChowKanekoMethod <T>(T image, int horizontalRegions, int verticalRegions) where T : Image
        {
            Bitmap bitmap = ImageFormatting.ToBitmap(image);

            ApplyChowKanekoMethodDirect(ref bitmap, horizontalRegions, verticalRegions);

            return((T)ImageFormatting.Convert(bitmap, image.RawFormat));
        }
        /// <summary>
        /// Any pixel values outside the threshold will be changed to min/max.
        /// </summary>
        /// <typeparam name="T">Image type to process and return</typeparam>
        /// <param name="image">Image to process</param>
        /// <param name="minValue">Minimum threshold value</param>
        /// <param name="maxValue">Maximum threshold value</param>
        /// <returns>New image with threshold applied</returns>
        public static T ApplyMinMax <T>(T image, byte minValue, byte maxValue) where T : Image
        {
            Bitmap bitmap = ImageFormatting.ToBitmap(image);

            ApplyMinMaxDirect(ref bitmap, minValue, maxValue);

            return((T)ImageFormatting.Convert(bitmap, image.RawFormat));
        }
        /// <summary>
        /// Applies thresholding to image using Otsu's Method.
        /// Returned image will consist of black (0) and white (255) values only.
        /// </summary>
        /// <typeparam name="T">Image type to process and return</typeparam>
        /// <param name="image">Image to process</param>
        /// <returns>New image with threshold applied</returns>
        public static T ApplyOtsuMethod <T>(T image) where T : Image
        {
            Bitmap bitmap = ImageFormatting.ToBitmap(image);

            ApplyOtsuMethodDirect(ref bitmap);

            return((T)ImageFormatting.Convert(bitmap, image.RawFormat));
        }
        /// <summary>
        /// Any pixel values below threshold will be changed to 0 (black).
        /// Any pixel values above (or equal to) threshold will be changed to 255 (white).
        /// </summary>
        /// <typeparam name="T">Image type to process and return</typeparam>
        /// <param name="image">Image to process</param>
        /// <param name="threshold">Threshold value</param>
        /// <returns>New image with threshold applied</returns>
        public static T Apply <T>(T image, byte threshold) where T : Image
        {
            Bitmap bitmap = ImageFormatting.ToBitmap(image);

            ApplyDirect(ref bitmap, threshold);

            return((T)ImageFormatting.Convert(bitmap, image.RawFormat));
        }
        /// <summary>
        /// Histogram Equalization will enhance general contrast
        /// by distributing grey levels wider and more evenly.
        /// </summary>
        /// <typeparam name="T">Image type to process and return</typeparam>
        /// <param name="image">Image to equalize</param>
        /// <returns>Equalized image</returns>
        public static T HistogramEqualization <T>(T image) where T : Image
        {
            Bitmap bitmap = ImageFormatting.ToBitmap(image);

            HistogramEqualizationDirect(ref bitmap);

            return((T)ImageFormatting.Convert(bitmap, image.RawFormat));
        }
        /// <summary>
        /// Stretches image contrast to specified min/max values.
        /// </summary>
        /// <typeparam name="T">Image type to process and return</typeparam>
        /// <param name="image">Image to process</param>
        /// <param name="min">Minimum contrast value</param>
        /// <param name="max">Maximum contrast value</param>
        /// <returns>Contrast-stretched image</returns>
        public static T Stretch <T>(T image, byte min, byte max) where T : Image
        {
            Bitmap bitmap = ImageFormatting.ToBitmap(image);

            StretchDirect(ref bitmap, min, max);

            return((T)ImageFormatting.Convert(bitmap, image.RawFormat));
        }
        /// <summary>
        /// Inverts image to negative.
        /// </summary>
        /// <typeparam name="T">Image type to process and return</typeparam>
        /// <param name="image">Image to convert</param>
        /// <returns>Negative image</returns>
        public static T ToNegative <T>(T image) where T : Image
        {
            Bitmap bitmap = ImageFormatting.ToBitmap(image);

            ToNegativeDirect(ref bitmap);

            return((T)ImageFormatting.Convert(bitmap, image.RawFormat));
        }
        /// <summary>
        /// Applies color filter to image.
        /// </summary>
        /// <typeparam name="T">Image type to process and return</typeparam>
        /// <param name="image">Image to process</param>
        /// <param name="r">Red component to apply</param>
        /// <param name="g">Green component to apply</param>
        /// <param name="b">Blue component to apply</param>
        /// <returns>New image with filter applied</returns>
        public static T ApplyFilterRGB <T>(T image, byte r, byte g, byte b) where T : Image
        {
            Bitmap bitmap = ImageFormatting.ToBitmap(image);

            ApplyFilterDirectRGB(ref bitmap, r, g, b);

            return((T)ImageFormatting.Convert(bitmap, image.RawFormat));
        }
Beispiel #10
0
 /// <summary>
 /// Converts the image to a bitmap, and gets the bytes.
 /// </summary>
 /// <param name="image">Image to get bytes from</param>
 /// <param name="bitmapData">Data relating to bitmap</param>
 /// <returns>Image bytes (without header info)</returns>
 public static byte[] FromImage(Image image, out BitmapData bitmapData)
 {
     if (image is Bitmap bmp)
     {
         return(GetBitmapBytes(bmp, out bitmapData));
     }
     else
     {
         using (Bitmap bitmap = ImageFormatting.ToBitmap(image))
         {
             return(GetBitmapBytes(bitmap, out bitmapData));
         }
     }
 }
Beispiel #11
0
 /// <summary>
 /// Get the average pixel value between min and max.
 /// </summary>
 /// <param name="image">Image to process</param>
 /// <param name="min">Minimum byte value</param>
 /// <param name="max">Maximum byte value</param>
 /// <returns>Average pixel intensity</returns>
 public static byte GetAverageValue(Image image, byte min, byte max)
 {
     if (image is Bitmap bmp)
     {
         return(GetAverageBitmapValue(bmp, min, max));
     }
     else
     {
         using (Bitmap bitmap = ImageFormatting.ToBitmap(image))
         {
             return(GetAverageBitmapValue(bitmap, min, max));
         }
     }
 }
Beispiel #12
0
 /// <summary>
 /// Gets the minimum & maximum pixel value within an image.
 /// For color images, min/max pixel avg is returned.
 /// </summary>
 /// <param name="image">Image to search</param>
 /// <param name="findMin">Determines whether to return min value</param>
 /// <param name="findMax">Determines whether to return max value</param>
 /// <returns>min, max bytes</returns>
 private static Tuple <byte, byte> GetMinMaxValue(Image image, bool findMin, bool findMax)
 {
     if (image is Bitmap bmp)
     {
         return(GetMinMaxBitmapValue(bmp, findMin, findMax));
     }
     else
     {
         using (Bitmap bitmap = ImageFormatting.ToBitmap(image))
         {
             return(GetMinMaxBitmapValue(bitmap, findMin, findMax));
         }
     }
 }
Beispiel #13
0
 /// <summary>
 /// Applies multiple convolution kernels to source image, then combines the results.
 /// </summary>
 /// <typeparam name="T">Image type to process and return</typeparam>
 /// <param name="image">Image to apply kernel to</param>
 /// <param name="convolutionTypes">Convolutions to apply</param>
 /// <returns>Image with all kernels combined</returns>
 public static T ApplyKernelsThenCombine <T>(T image, params ConvolutionType[] convolutionTypes) where T : Image
 {
     if (image is Bitmap bmp)
     {
         return((T)(Image)ApplyKernelsThenCombine(bmp, convolutionTypes));
     }
     else
     {
         // Convert to bitmap for image processing
         using (Bitmap bitmap = ImageFormatting.ToBitmap(image))
         {
             using (Bitmap combinedBitmap = ApplyKernelsThenCombine(bitmap, convolutionTypes))
             {
                 // Return processed image to original format
                 return((T)ImageFormatting.ToFormat(combinedBitmap, image.RawFormat));
             }
         }
     }
 }
Beispiel #14
0
 /// <summary>
 /// Applies convolution matrix/kernel to image.
 /// </summary>
 /// <typeparam name="T">Image type to process and return</typeparam>
 /// <param name="image">Image to apply kernel to</param>
 /// <param name="kernelMatrix">Kernel matrix</param>
 /// <returns>Image with kernel applied</returns>
 public static T ApplyKernel <T>(T image, int[,] kernelMatrix) where T : Image
 {
     // Skip conversion
     if (image is Bitmap bmp)
     {
         return((T)(Image)ApplyKernel(bmp, kernelMatrix));
     }
     else
     {
         // Convert to bitmap for image processing
         using (Bitmap bitmap = ImageFormatting.ToBitmap(image))
         {
             // Apply filter to bitmap
             using (Bitmap bitmapWithFilter = ApplyKernel(bitmap, kernelMatrix))
             {
                 // Covert processed image to original format
                 return((T)ImageFormatting.ToFormat(bitmapWithFilter, image.RawFormat));
             }
         }
     }
 }
Beispiel #15
0
 /// <summary>
 /// Crops an image based on the crop region.
 /// </summary>
 /// <typeparam name="T">Image type to process and return</typeparam>
 /// <param name="image">Image to crop</param>
 /// <param name="cropRegion">Region within image to crop</param>
 /// <returns>Cropped image</returns>
 public static T ByRegion <T>(T image, Rectangle cropRegion) where T : Image
 {
     // Check if already a bitmap
     if (image is Bitmap bmp)
     {
         return((T)(Image)CropBitmap(bmp, cropRegion));
     }
     else
     {
         // Convert to bitmap
         using (Bitmap bitmap = ImageFormatting.ToBitmap(image))
         {
             // Crop as bitmap
             using (Image croppedBitmap = CropBitmap(bitmap, cropRegion))
             {
                 // Restore original image format
                 return((T)ImageFormatting.ToFormat(croppedBitmap, image.RawFormat));
             }
         }
     }
 }
        /// <summary>
        /// Combines multiple images together.
        /// (Pixel values combined via bitwise or, not averaged)
        /// </summary>
        /// <param name="images">Images to combine</param>
        /// <returns>New combined image as bitmap</returns>
        public static Bitmap All<T>(IEnumerable<T> images) where T : Image
        {
            // Check have at least 1 image
            if (!images.Any())
            {
                return null;
            }

            // Use first image as starting point
            Bitmap combinedImage = ImageFormatting.ToBitmap(images.ElementAt(0));

            // Get bytes for image
            byte[] rgbValues1 = ImageEdit.Begin(combinedImage, out BitmapData bmpData1);

            try
            {
                // Get image 1 data
                int pixelDepth1 = bmpData1.GetPixelDepth();
                int pixelDepthWithoutAlpha = Math.Min(pixelDepth1, Constants.PixelDepthRGB);
                int stride1 = bmpData1.Stride;
                int width1 = bmpData1.GetStrideWithoutPadding();
                int height1 = bmpData1.Height;

                // Add additional images to first
                foreach (Image image in images.Skip(1))
                {
                    // Only reading this image
                    byte[] rgbValues2 = ImageBytes.FromImage(image, out BitmapData bmpData2);

                    // Check both images are color or B&W
                    if (pixelDepth1 == bmpData2.GetPixelDepth())
                    {
                        // Protect against different sized images
                        int limit = Math.Min(bmpData1.GetSafeArrayLimitForImage(rgbValues1), bmpData2.GetSafeArrayLimitForImage(rgbValues2));
                        int minHeight = Math.Min(height1, bmpData2.Height);
                        int minStride = Math.Min(stride1, bmpData2.Stride);
                        int minWidth = Math.Min(width1, bmpData2.GetStrideWithoutPadding());

                        for (int y = 0; y < minHeight; y++)
                        {
                            // Images may have extra bytes per row to pad for CPU addressing.
                            // so need to ensure we traverse to the correct byte when moving between rows.
                            int offset = y * minStride;

                            for (int x = 0; x < minWidth; x += pixelDepth1)
                            {
                                int i = offset + x;

                                if (i < limit)
                                {
                                    for (int j = 0; j < pixelDepthWithoutAlpha; j++)
                                    {
                                        // Combine images
                                        rgbValues1[i + j] |= rgbValues2[i + j];
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        throw new ArgumentException("Not all images have the same color depth");
                    }    
                }
            }
            finally
            {
                // Release combined image
                ImageEdit.End(combinedImage, bmpData1, rgbValues1);
            }

            return combinedImage;
        }