CNTKImageProcessing.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Drawing;
  7. using System.Drawing.Imaging;
  8. namespace ImageCls
  9. {
  10. static class ImageProcessing
  11. {
  12. /// <summary>
  13. /// Extracts image pixels in CHW using parallelization(提取像素值)
  14. /// </summary>
  15. /// <param name="image">The bitmap image to extract features from</param>
  16. /// <returns>A list of pixels in CHW order</returns>
  17. public static List<float> ParallelExtractCHW(this Bitmap image)
  18. {
  19. // We use local variables to avoid contention on the image object through the multiple threads.
  20. int channelStride = image.Width * image.Height;
  21. int imageWidth = image.Width;
  22. int imageHeight = image.Height;
  23. var features = new byte[imageWidth * imageHeight * 3];
  24. var bitmapData = image.LockBits(new System.Drawing.Rectangle(0, 0, imageWidth, imageHeight), ImageLockMode.ReadOnly, image.PixelFormat);
  25. IntPtr ptr = bitmapData.Scan0;
  26. int bytes = Math.Abs(bitmapData.Stride) * bitmapData.Height;
  27. byte[] rgbValues = new byte[bytes];
  28. int stride = bitmapData.Stride;
  29. // Copy the RGB values into the array.
  30. System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
  31. // The mapping depends on the pixel format
  32. // The mapPixel lambda will return the right color channel for the desired pixel
  33. Func<int, int, int, int> mapPixel = GetPixelMapper(image.PixelFormat, stride);
  34. Parallel.For(0, imageHeight, (int h) =>
  35. {
  36. Parallel.For(0, imageWidth, (int w) =>
  37. {
  38. Parallel.For(0, 3, (int c) =>
  39. {
  40. features[channelStride * c + imageWidth * h + w] = rgbValues[mapPixel(h, w, c)];
  41. });
  42. });
  43. });
  44. image.UnlockBits(bitmapData);
  45. return features.Select(b => (float)b).ToList();
  46. }
  47. /// <summary>
  48. /// Returns a function for extracting the R-G-B values properly from an image based on its pixel format(针对图像的对应格式提取像素值)
  49. /// </summary>
  50. /// <param name="pixelFormat">The image's pixel format</param>
  51. /// <param name="heightStride">The stride (row byte count)</param>
  52. /// <returns>A function with signature (height, width, channel) returning the corresponding color value</returns>
  53. private static Func<int, int, int, int> GetPixelMapper(PixelFormat pixelFormat, int heightStride)
  54. {
  55. switch (pixelFormat)
  56. {
  57. case PixelFormat.Format32bppArgb:
  58. return (h, w, c) => h * heightStride + w * 4 + c; // bytes are B-G-R-A
  59. case PixelFormat.Format24bppRgb:
  60. default:
  61. return (h, w, c) => h * heightStride + w * 3 + c; // bytes are B-G-R
  62. }
  63. }
  64. /// <summary>
  65. /// Resizes an image(实现图片的尺寸变换)
  66. /// </summary>
  67. /// <param name="image">The image to resize</param>
  68. /// <param name="width">New width in pixels</param>
  69. /// <param name="height">New height in pixels</param>
  70. /// <param name="useHighQuality">Resize quality</param>
  71. /// <returns>The resized image</returns>
  72. public static Bitmap Resize(this Bitmap image, int width, int height, bool useHighQuality)
  73. {
  74. var newImg = new Bitmap(width, height);
  75. newImg.SetResolution(image.HorizontalResolution, image.VerticalResolution);
  76. using (var g = Graphics.FromImage(newImg))
  77. {
  78. g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
  79. if (useHighQuality)
  80. {
  81. g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
  82. g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
  83. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
  84. g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
  85. }
  86. else
  87. {
  88. g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default;
  89. g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.Default;
  90. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
  91. g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Default;
  92. }
  93. var attributes = new ImageAttributes();
  94. attributes.SetWrapMode(System.Drawing.Drawing2D.WrapMode.TileFlipXY);
  95. g.DrawImage(image, new System.Drawing.Rectangle(0, 0, width, height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
  96. }
  97. return newImg;
  98. }
  99. }
  100. }