123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- using OpenCvSharp;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace PaintDotNet.Adjust
- {
- /// <summary>
- /// 曝光处理
- /// </summary>
- public unsafe class ExposedIntent
- {
- private static int underExposedPixel = 0;//曝光不足像素阈值
- private static int overExposedPixel = 0;//过曝光像素阈值
- private static float ratio = 0;//占总像素点比例
- private static Mat exposedMat;//全局mat对象
- private static float underPixelCount = 0;//过暗像素点个数
- private static float overPixelCount = 0;//过亮像素点个数
- private static float allPixelCount = 0;//总像素点个数
- /// <summary>
- /// 判断曝光状态并返回对应像素点数量
- /// </summary>
- /// <param name="src"></param>
- /// <returns></returns>
- public static void ExposureState(Mat src)
- {
- //配置输出的结果存储的 空间 ,用MatND类型来存储结果
- Mat hist = new Mat();
- //设置计算的维度
- int dims = 1;
- //每一个维度的柱条的数目(就是将数值分组,共有多少组)
- int[] histSize = { 256 };
- Rangef[] pranges = new Rangef[1];//一个通道,范围
- pranges[0] = new Rangef(0.0F, 256.0F);
- Mat grayMat = src.CvtColor(ColorConversionCodes.BGRA2GRAY);//转换为灰度图
- //计算直方图
- Cv2.CalcHist(new Mat[1] { grayMat }, new int[] { 0 }, new Mat(), hist, dims, histSize, pranges);
- //循环记录像素点
- for (int i = 0; i < hist.Height; i++)
- {
- for (int j = 0; j < hist.Width; j++)
- {
- float pixelCount = hist.At<float>(i, j);
- allPixelCount += pixelCount;
- if (i < underExposedPixel && underExposedPixel != 0)
- underPixelCount += pixelCount;
- if (i > overExposedPixel && overExposedPixel != 0)
- overPixelCount += pixelCount;
- }
- }
- }
- /// <summary>
- /// 曝光不足,替换像素点为蓝色
- /// </summary>
- /// <param name="src"></param>
- /// <param name="underExposedPixel">曝光不足像素阈值</param>
- /// <param name="ratio">占总像素点比例</param>
- /// <returns></returns>
- public static Mat UnderExposed(Mat src, int thresholdvalue, float exposedRatio)
- {
- underExposedPixel = thresholdvalue;
- ratio = exposedRatio;
- exposedMat = src;
- ExposureState(src);
- //判断过暗,如果阈值内的像素点多余总像素点一定比例
- if (underPixelCount > 0)
- {
- if (underPixelCount / allPixelCount > ratio)
- {
- Mat grayMat = src.CvtColor(ColorConversionCodes.BGRA2GRAY);//转换为灰度图
- grayMat.ForEachAsByte(ForeachFunctionUnderExposedByte);
- }
- }
-
- return exposedMat;
- }
- /// <summary>
- /// 过曝光,替换像素点为红色
- /// </summary>
- /// <param name="src"></param>
- /// <param name="overExposedPixel">过曝光像素阈值</param>
- /// <param name="ratio">占总像素点比例</param>
- /// <returns></returns>
- public static Mat OverExposed(Mat src, int thresholdvalue, float exposedRatio)
- {
- overExposedPixel = thresholdvalue;
- ratio = exposedRatio;
- exposedMat = src;
- ExposureState(src);
- //判断过亮,如果阈值内的像素点多余总像素点一定比例
- if (overPixelCount > 0)
- {
- if (overPixelCount / allPixelCount > ratio)
- {
- Mat grayMat = src.CvtColor(ColorConversionCodes.BGRA2GRAY);//转换为灰度图
- grayMat.ForEachAsByte(ForeachFunctionOverExposedByte);
- }
- }
-
- return exposedMat;
- }
- /// <summary>
- /// 更高效的循环替换方法-曝光不足
- /// </summary>
- /// <param name="t"></param>
- /// <param name="position"></param>
- public unsafe static void ForeachFunctionUnderExposedByte(byte* t, int* position)
- {
- int y = position[0];
- int x = position[1];
- if (*t < underExposedPixel)
- {
- exposedMat.Set<Vec3b>(y, x, new Vec3b(255, 0, 0));//改为蓝色
- }
- }
- /// <summary>
- /// 更高效的循环替换方法-过曝光
- /// </summary>
- /// <param name="t"></param>
- /// <param name="position"></param>
- public unsafe static void ForeachFunctionOverExposedByte(byte* t, int* position)
- {
- int y = position[0];
- int x = position[1];
- if (*t > overExposedPixel)
- {
- exposedMat.Set<Vec3b>(y, x, new Vec3b(0, 0, 255));//改为红色
- }
- }
- }
- }
|