123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Drawing;
- using System.Drawing.Imaging;
- namespace ImageCls
- {
- static class ImageProcessing
- {
- /// <summary>
- /// Extracts image pixels in CHW using parallelization(提取像素值)
- /// </summary>
- /// <param name="image">The bitmap image to extract features from</param>
- /// <returns>A list of pixels in CHW order</returns>
- public static List<float> ParallelExtractCHW(this Bitmap image)
- {
- // We use local variables to avoid contention on the image object through the multiple threads.
- int channelStride = image.Width * image.Height;
- int imageWidth = image.Width;
- int imageHeight = image.Height;
- var features = new byte[imageWidth * imageHeight * 3];
- var bitmapData = image.LockBits(new System.Drawing.Rectangle(0, 0, imageWidth, imageHeight), ImageLockMode.ReadOnly, image.PixelFormat);
- IntPtr ptr = bitmapData.Scan0;
- int bytes = Math.Abs(bitmapData.Stride) * bitmapData.Height;
- byte[] rgbValues = new byte[bytes];
- int stride = bitmapData.Stride;
- // Copy the RGB values into the array.
- System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
- // The mapping depends on the pixel format
- // The mapPixel lambda will return the right color channel for the desired pixel
- Func<int, int, int, int> mapPixel = GetPixelMapper(image.PixelFormat, stride);
- Parallel.For(0, imageHeight, (int h) =>
- {
- Parallel.For(0, imageWidth, (int w) =>
- {
- Parallel.For(0, 3, (int c) =>
- {
- features[channelStride * c + imageWidth * h + w] = rgbValues[mapPixel(h, w, c)];
- });
- });
- });
- image.UnlockBits(bitmapData);
- return features.Select(b => (float)b).ToList();
- }
- /// <summary>
- /// Returns a function for extracting the R-G-B values properly from an image based on its pixel format(针对图像的对应格式提取像素值)
- /// </summary>
- /// <param name="pixelFormat">The image's pixel format</param>
- /// <param name="heightStride">The stride (row byte count)</param>
- /// <returns>A function with signature (height, width, channel) returning the corresponding color value</returns>
- private static Func<int, int, int, int> GetPixelMapper(PixelFormat pixelFormat, int heightStride)
- {
- switch (pixelFormat)
- {
- case PixelFormat.Format32bppArgb:
- return (h, w, c) => h * heightStride + w * 4 + c; // bytes are B-G-R-A
- case PixelFormat.Format24bppRgb:
- default:
- return (h, w, c) => h * heightStride + w * 3 + c; // bytes are B-G-R
- }
- }
- /// <summary>
- /// Resizes an image(实现图片的尺寸变换)
- /// </summary>
- /// <param name="image">The image to resize</param>
- /// <param name="width">New width in pixels</param>
- /// <param name="height">New height in pixels</param>
- /// <param name="useHighQuality">Resize quality</param>
- /// <returns>The resized image</returns>
- public static Bitmap Resize(this Bitmap image, int width, int height, bool useHighQuality)
- {
- var newImg = new Bitmap(width, height);
- newImg.SetResolution(image.HorizontalResolution, image.VerticalResolution);
- using (var g = Graphics.FromImage(newImg))
- {
- g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
- if (useHighQuality)
- {
- g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
- g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
- g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
- g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
- }
- else
- {
- g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default;
- g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.Default;
- g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
- g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Default;
- }
- var attributes = new ImageAttributes();
- attributes.SetWrapMode(System.Drawing.Drawing2D.WrapMode.TileFlipXY);
- g.DrawImage(image, new System.Drawing.Rectangle(0, 0, width, height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
- }
- return newImg;
- }
- }
- }
|