ExposedIntent.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. using OpenCvSharp;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace PaintDotNet.Adjust
  8. {
  9. /// <summary>
  10. /// 曝光处理
  11. /// </summary>
  12. public unsafe class ExposedIntent
  13. {
  14. private static int underExposedPixel = 0;//曝光不足像素阈值
  15. private static int overExposedPixel = 0;//过曝光像素阈值
  16. private static float ratio = 0;//占总像素点比例
  17. private static Mat exposedMat;//全局mat对象
  18. private static float underPixelCount = 0;//过暗像素点个数
  19. private static float overPixelCount = 0;//过亮像素点个数
  20. private static float allPixelCount = 0;//总像素点个数
  21. /// <summary>
  22. /// 判断曝光状态并返回对应像素点数量
  23. /// </summary>
  24. /// <param name="src"></param>
  25. /// <returns></returns>
  26. public static void ExposureState(Mat src)
  27. {
  28. //配置输出的结果存储的 空间 ,用MatND类型来存储结果
  29. Mat hist = new Mat();
  30. //设置计算的维度
  31. int dims = 1;
  32. //每一个维度的柱条的数目(就是将数值分组,共有多少组)
  33. int[] histSize = { 256 };
  34. Rangef[] pranges = new Rangef[1];//一个通道,范围
  35. pranges[0] = new Rangef(0.0F, 256.0F);
  36. Mat grayMat = src.CvtColor(ColorConversionCodes.BGRA2GRAY);//转换为灰度图
  37. //计算直方图
  38. Cv2.CalcHist(new Mat[1] { grayMat }, new int[] { 0 }, new Mat(), hist, dims, histSize, pranges);
  39. //循环记录像素点
  40. for (int i = 0; i < hist.Height; i++)
  41. {
  42. for (int j = 0; j < hist.Width; j++)
  43. {
  44. float pixelCount = hist.At<float>(i, j);
  45. allPixelCount += pixelCount;
  46. if (i < underExposedPixel && underExposedPixel != 0)
  47. underPixelCount += pixelCount;
  48. if (i > overExposedPixel && overExposedPixel != 0)
  49. overPixelCount += pixelCount;
  50. }
  51. }
  52. }
  53. /// <summary>
  54. /// 曝光不足,替换像素点为蓝色
  55. /// </summary>
  56. /// <param name="src"></param>
  57. /// <param name="underExposedPixel">曝光不足像素阈值</param>
  58. /// <param name="ratio">占总像素点比例</param>
  59. /// <returns></returns>
  60. public static Mat UnderExposed(Mat src, int thresholdvalue, float exposedRatio)
  61. {
  62. underExposedPixel = thresholdvalue;
  63. ratio = exposedRatio;
  64. exposedMat = src;
  65. ExposureState(src);
  66. //判断过暗,如果阈值内的像素点多余总像素点一定比例
  67. if (underPixelCount > 0)
  68. {
  69. if (underPixelCount / allPixelCount > ratio)
  70. {
  71. Mat grayMat = src.CvtColor(ColorConversionCodes.BGRA2GRAY);//转换为灰度图
  72. grayMat.ForEachAsByte(ForeachFunctionUnderExposedByte);
  73. }
  74. }
  75. return exposedMat;
  76. }
  77. /// <summary>
  78. /// 过曝光,替换像素点为红色
  79. /// </summary>
  80. /// <param name="src"></param>
  81. /// <param name="overExposedPixel">过曝光像素阈值</param>
  82. /// <param name="ratio">占总像素点比例</param>
  83. /// <returns></returns>
  84. public static Mat OverExposed(Mat src, int thresholdvalue, float exposedRatio)
  85. {
  86. overExposedPixel = thresholdvalue;
  87. ratio = exposedRatio;
  88. exposedMat = src;
  89. ExposureState(src);
  90. //判断过亮,如果阈值内的像素点多余总像素点一定比例
  91. if (overPixelCount > 0)
  92. {
  93. if (overPixelCount / allPixelCount > ratio)
  94. {
  95. Mat grayMat = src.CvtColor(ColorConversionCodes.BGRA2GRAY);//转换为灰度图
  96. grayMat.ForEachAsByte(ForeachFunctionOverExposedByte);
  97. }
  98. }
  99. return exposedMat;
  100. }
  101. /// <summary>
  102. /// 更高效的循环替换方法-曝光不足
  103. /// </summary>
  104. /// <param name="t"></param>
  105. /// <param name="position"></param>
  106. public unsafe static void ForeachFunctionUnderExposedByte(byte* t, int* position)
  107. {
  108. int y = position[0];
  109. int x = position[1];
  110. if (*t < underExposedPixel)
  111. {
  112. exposedMat.Set<Vec3b>(y, x, new Vec3b(255, 0, 0));//改为蓝色
  113. }
  114. }
  115. /// <summary>
  116. /// 更高效的循环替换方法-过曝光
  117. /// </summary>
  118. /// <param name="t"></param>
  119. /// <param name="position"></param>
  120. public unsafe static void ForeachFunctionOverExposedByte(byte* t, int* position)
  121. {
  122. int y = position[0];
  123. int x = position[1];
  124. if (*t > overExposedPixel)
  125. {
  126. exposedMat.Set<Vec3b>(y, x, new Vec3b(0, 0, 255));//改为红色
  127. }
  128. }
  129. }
  130. }