Esempio n. 1
0
        public static SoftwareBitmap GenenateResizedThumbnail(SoftwareBitmap Input, int Height, int Width)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                {
                    if (inputMat.Cols > inputMat.Rows)
                    {
                        int  CropSize       = inputMat.Rows;
                        int  StartXPosition = (inputMat.Cols - CropSize) / 2;
                        int  StartYPosition = 0;
                        Rect CropRect       = new Rect(StartXPosition, StartYPosition, CropSize, CropSize);
                        using (Mat CroppedMat = new Mat(inputMat, CropRect))
                        {
                            Cv2.Resize(CroppedMat, outputMat, new Size(Width, Height), 0, 0, InterpolationFlags.Linear);
                        }
                    }
                    else
                    {
                        int  CropSize       = inputMat.Cols;
                        int  StartYPosition = (inputMat.Rows - CropSize) / 2;
                        int  StartXPosition = 0;
                        Rect CropRect       = new Rect(StartXPosition, StartYPosition, CropSize, CropSize);
                        using (Mat CroppedMat = new Mat(inputMat, CropRect))
                        {
                            Cv2.Resize(CroppedMat, outputMat, new Size(Width, Height), 0, 0, InterpolationFlags.Linear);
                        }
                    }

                    return(outputMat.MatToSoftwareBitmap());
                }
        }
Esempio n. 2
0
        public static SoftwareBitmap ResizeToActual(SoftwareBitmap Input)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
            {
                Mat[] Channels = Array.Empty <Mat>();

                try
                {
                    Channels = Cv2.Split(inputMat);

                    if (Channels.Length == 4)
                    {
                        Mat  Contour    = Channels.Last().FindNonZero();
                        Rect ActualArea = Cv2.BoundingRect(Contour);
                        Rect ExtraArea  = new Rect(Math.Max(ActualArea.X - 5, 0), Math.Max(ActualArea.Y - 5, 0), Math.Min(ActualArea.Width + 10, inputMat.Width - ActualArea.X), Math.Min(ActualArea.Height + 10, inputMat.Height - ActualArea.Y));
                        return(inputMat[ExtraArea].Clone().MatToSoftwareBitmap());
                    }
                    else
                    {
                        throw new ArgumentException("Input must be BGRA image");
                    }
                }
                catch
                {
                    return(SoftwareBitmap.Copy(Input));
                }
                finally
                {
                    Array.ForEach(Channels, (Channel) => Channel.Dispose());
                }
            }
        }
Esempio n. 3
0
        public static SoftwareBitmap ResizeToActual(SoftwareBitmap Input)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
            {
                Mat[] Channels = Array.Empty <Mat>();

                try
                {
                    Channels = Cv2.Split(inputMat);

                    if (Channels.Length == 4)
                    {
                        Mat  Contour = Channels.Last().FindNonZero();
                        Rect Area    = Cv2.BoundingRect(Contour);
                        return(inputMat[Area].Clone().MatToSoftwareBitmap());
                    }
                    else
                    {
                        throw new ArgumentException("Input must have be BGRA image");
                    }
                }
                catch
                {
                    return(SoftwareBitmap.Copy(Input));
                }
                finally
                {
                    Array.ForEach(Channels, (Channel) => Channel.Dispose());
                }
            }
        }
Esempio n. 4
0
        public static SoftwareBitmap AdjustBrightnessContrast(SoftwareBitmap Input, double Alpha, double Beta)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                {
                    inputMat.ConvertTo(outputMat, MatType.CV_8UC4, Alpha, Beta);

                    return(outputMat.MatToSoftwareBitmap());
                }
        }
Esempio n. 5
0
        public static SoftwareBitmap GaussianBlurEffect(SoftwareBitmap Input)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                {
                    Cv2.GaussianBlur(inputMat, outputMat, new Size(0, 0), 8);

                    return(outputMat.MatToSoftwareBitmap());
                }
        }
Esempio n. 6
0
        public static SoftwareBitmap InvertEffect(SoftwareBitmap Input)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                {
                    Cv2.BitwiseNot(inputMat, outputMat);

                    return(outputMat.MatToSoftwareBitmap());
                }
        }
Esempio n. 7
0
        public static SoftwareBitmap ExtendImageBorder(SoftwareBitmap Input, Color Colors, int Top, int Left, int Right, int Bottom)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                {
                    Cv2.CopyMakeBorder(inputMat, outputMat, Top, Bottom, Left, Right, BorderTypes.Constant, new Scalar(Colors.B, Colors.G, Colors.R));

                    return(outputMat.MatToSoftwareBitmap());
                }
        }
Esempio n. 8
0
        public static SoftwareBitmap GrayEffect(SoftwareBitmap Input)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                {
                    Cv2.CvtColor(inputMat, outputMat, ColorConversionCodes.BGRA2GRAY);
                    Cv2.CvtColor(outputMat, outputMat, ColorConversionCodes.GRAY2BGRA);

                    return(outputMat.MatToSoftwareBitmap());
                }
        }
Esempio n. 9
0
        public static SoftwareBitmap OilPaintingEffect(SoftwareBitmap Input)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                {
                    Cv2.CvtColor(inputMat, outputMat, ColorConversionCodes.BGRA2BGR);
                    Cv2.PyrMeanShiftFiltering(outputMat, outputMat, 12, 60);
                    Cv2.CvtColor(outputMat, outputMat, ColorConversionCodes.BGR2BGRA);

                    return(outputMat.MatToSoftwareBitmap());
                }
        }
Esempio n. 10
0
        public static SoftwareBitmap SketchEffect(SoftwareBitmap Input)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                {
                    Cv2.CvtColor(inputMat, outputMat, ColorConversionCodes.BGRA2GRAY);
                    Cv2.AdaptiveThreshold(outputMat, outputMat, 255, AdaptiveThresholdTypes.GaussianC, ThresholdTypes.Binary, 11, 2);
                    Cv2.CvtColor(outputMat, outputMat, ColorConversionCodes.GRAY2BGRA);

                    return(outputMat.MatToSoftwareBitmap());
                }
        }
Esempio n. 11
0
        public static SoftwareBitmap MosaicEffect(SoftwareBitmap Input)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                {
                    Cv2.CvtColor(inputMat, outputMat, ColorConversionCodes.BGRA2BGR);

                    int level = 15;

                    for (int i = 0; i < outputMat.Rows; i += level)
                    {
                        for (int j = 0; j < outputMat.Cols; j += level)
                        {
                            Rect mosaicRect;

                            if (j + level > outputMat.Cols && i + level > outputMat.Rows)
                            {
                                mosaicRect = new Rect(j, i, outputMat.Cols - j, outputMat.Rows - i);
                            }
                            else if (j + level > outputMat.Cols)
                            {
                                mosaicRect = new Rect(j, i, outputMat.Cols - j, level);
                            }
                            else if (i + level > outputMat.Rows)
                            {
                                mosaicRect = new Rect(j, i, level, outputMat.Rows - i);
                            }
                            else
                            {
                                mosaicRect = new Rect(j, i, level, level);
                            }

                            Vec3b Vec = outputMat.At <Vec3b>(i, j);

                            Scalar scalar = new Scalar(
                                Vec.Item0,
                                Vec.Item1,
                                Vec.Item2);

                            outputMat[mosaicRect] = new Mat(mosaicRect.Size, MatType.CV_8UC3, scalar);
                        }
                    }

                    Cv2.CvtColor(outputMat, outputMat, ColorConversionCodes.BGR2BGRA);

                    return(outputMat.MatToSoftwareBitmap());
                }
        }
Esempio n. 12
0
        public static SoftwareBitmap FlipEffect(SoftwareBitmap Input, bool FlipByX)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                {
                    if (FlipByX)
                    {
                        Cv2.Flip(inputMat, outputMat, FlipMode.X);
                    }
                    else
                    {
                        Cv2.Flip(inputMat, outputMat, FlipMode.Y);
                    }

                    return(outputMat.MatToSoftwareBitmap());
                }
        }
Esempio n. 13
0
        public static float DetectAvgBrightness(SoftwareBitmap Input)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat BGRMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC3))
                {
                    Cv2.CvtColor(inputMat, BGRMat, ColorConversionCodes.BGRA2BGR);

                    using (Mat HSVMat = new Mat(BGRMat.Rows, BGRMat.Cols, MatType.CV_8UC3))
                    {
                        Cv2.CvtColor(BGRMat, HSVMat, ColorConversionCodes.BGR2HSV);

                        using (Mat VChannel = HSVMat.ExtractChannel(2))
                        {
                            Scalar Mean = Cv2.Mean(VChannel);
                            return(Convert.ToSingle(Mean.Val0));
                        }
                    }
                }
        }
Esempio n. 14
0
        public static SoftwareBitmap SepiaEffect(SoftwareBitmap Input)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                {
                    Cv2.CvtColor(inputMat, outputMat, ColorConversionCodes.BGRA2BGR);

                    float[] Data = new float[9] {
                        0.273f, 0.534f, 0.131f, 0.349f, 0.686f, 0.168f, 0.393f, 0.769f, 0.189f
                    };

                    using (Mat Kernel = new Mat <float>(3, 3, Data))
                    {
                        Cv2.Transform(outputMat, outputMat, Kernel);
                    }

                    Cv2.CvtColor(outputMat, outputMat, ColorConversionCodes.BGR2BGRA);

                    return(outputMat.MatToSoftwareBitmap());
                }
        }
Esempio n. 15
0
        public static SoftwareBitmap ResizeToActual(SoftwareBitmap Input)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat tempMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                {
                    Cv2.CvtColor(inputMat, tempMat, ColorConversionCodes.BGRA2GRAY);
                    Cv2.Threshold(tempMat, tempMat, 100, 255, ThresholdTypes.Binary);

                    using (Mat Hie = new Mat(tempMat.Size(), tempMat.Type()))
                    {
                        Cv2.FindContours(tempMat, out Mat[] Result, Hie, RetrievalModes.External, ContourApproximationModes.ApproxNone);

                        try
                        {
                            if (Result.FirstOrDefault() is Mat Contour)
                            {
                                Rect Area = Cv2.BoundingRect(Contour);
                                return(inputMat[Area].Clone().MatToSoftwareBitmap());
                            }
                            else
                            {
                                return(SoftwareBitmap.Copy(Input));
                            }
                        }
                        catch
                        {
                            return(SoftwareBitmap.Copy(Input));
                        }
                        finally
                        {
                            foreach (Mat Item in Result)
                            {
                                Item.Dispose();
                            }
                        }
                    }
                }
        }
Esempio n. 16
0
        public static SoftwareBitmap RotateEffect(SoftwareBitmap Input, int Angle)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                {
                    switch (Angle)
                    {
                    case 90:
                    {
                        Cv2.Transpose(inputMat, outputMat);
                        Cv2.Flip(outputMat, outputMat, FlipMode.Y);
                        break;
                    }

                    case 180:
                    {
                        Cv2.Flip(inputMat, outputMat, FlipMode.XY);
                        break;
                    }

                    case -90:
                    {
                        Cv2.Transpose(inputMat, outputMat);
                        Cv2.Flip(outputMat, outputMat, FlipMode.X);
                        break;
                    }

                    default:
                    {
                        throw new Exception("Angle 仅支持90、180、-90度");
                    }
                    }

                    return(outputMat.MatToSoftwareBitmap());
                }
        }
Esempio n. 17
0
        public static SoftwareBitmap CalculateHistogram(SoftwareBitmap Input)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                    using (Mat temp = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC3))
                    {
                        Mat[] OutputRGB = new Mat[3]
                        {
                            new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC3),
                            new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC3),
                            new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC3)
                        };

                        try
                        {
                            int[] hissize = new int[1] {
                                512
                            };
                            int     histHeight = 512, histWidth = 512;
                            float[] ranges = new float[2] {
                                0.0f, 256.0f
                            };

                            Cv2.CvtColor(inputMat, temp, ColorConversionCodes.BGRA2BGR);

                            Mat[] RGBChannels = Cv2.Split(temp);

                            try
                            {
                                Cv2.CalcHist(new Mat[1] {
                                    RGBChannels[0]
                                }, new int[1] {
                                    0
                                }, null, OutputRGB[0], 1, hissize, new float[][] { ranges });
                                Cv2.CalcHist(new Mat[1] {
                                    RGBChannels[1]
                                }, new int[1] {
                                    0
                                }, null, OutputRGB[1], 1, hissize, new float[][] { ranges });
                                Cv2.CalcHist(new Mat[1] {
                                    RGBChannels[2]
                                }, new int[1] {
                                    0
                                }, null, OutputRGB[2], 1, hissize, new float[][] { ranges });

                                Cv2.Normalize(OutputRGB[0], OutputRGB[0], 0, histHeight, NormTypes.MinMax);
                                Cv2.Normalize(OutputRGB[1], OutputRGB[1], 0, histHeight, NormTypes.MinMax);
                                Cv2.Normalize(OutputRGB[2], OutputRGB[2], 0, histHeight, NormTypes.MinMax);

                                using (Mat histImage = new Mat(histHeight, histWidth, MatType.CV_8UC3, new Scalar(20, 20, 20)))
                                {
                                    int binStep = Convert.ToInt32(Math.Round(histWidth / (float)hissize[0], MidpointRounding.AwayFromZero));

                                    for (int i = 1; i < hissize[0]; i++)
                                    {
                                        Cv2.Line(histImage, new Point(binStep * (i - 1), histHeight - Convert.ToInt32(Math.Round(OutputRGB[0].At <float>(i - 1), MidpointRounding.AwayFromZero))), new Point(binStep * (i), histHeight - Convert.ToInt32(Math.Round(OutputRGB[0].At <float>(i), MidpointRounding.AwayFromZero))), new Scalar(255, 0, 0));
                                        Cv2.Line(histImage, new Point(binStep * (i - 1), histHeight - Convert.ToInt32(Math.Round(OutputRGB[1].At <float>(i - 1), MidpointRounding.AwayFromZero))), new Point(binStep * (i), histHeight - Convert.ToInt32(Math.Round(OutputRGB[1].At <float>(i), MidpointRounding.AwayFromZero))), new Scalar(0, 255, 0));
                                        Cv2.Line(histImage, new Point(binStep * (i - 1), histHeight - Convert.ToInt32(Math.Round(OutputRGB[2].At <float>(i - 1), MidpointRounding.AwayFromZero))), new Point(binStep * (i), histHeight - Convert.ToInt32(Math.Round(OutputRGB[2].At <float>(i), MidpointRounding.AwayFromZero))), new Scalar(0, 0, 255));
                                    }

                                    Cv2.CvtColor(histImage, outputMat, ColorConversionCodes.BGR2BGRA);

                                    return(outputMat.MatToSoftwareBitmap());
                                }
                            }
                            finally
                            {
                                Array.ForEach(RGBChannels, (Channel) => Channel.Dispose());
                            }
                        }
                        finally
                        {
                            Array.ForEach(OutputRGB, (Channel) => Channel.Dispose());
                        }
                    }
        }
Esempio n. 18
0
        public static SoftwareBitmap AutoWhiteBalance(SoftwareBitmap Input)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                    using (Mat temp = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC3))
                    {
                        Cv2.CvtColor(inputMat, temp, ColorConversionCodes.BGRA2BGR);

                        int[] HistRGB = new int[767];
                        Array.Fill(HistRGB, 0);

                        int MaxVal = 0;
                        for (int i = 0; i < inputMat.Rows; i++)
                        {
                            for (int j = 0; j < inputMat.Cols; j++)
                            {
                                MaxVal = Math.Max(MaxVal, (int)temp.At <Vec3b>(i, j)[0]);
                                MaxVal = Math.Max(MaxVal, (int)temp.At <Vec3b>(i, j)[1]);
                                MaxVal = Math.Max(MaxVal, (int)temp.At <Vec3b>(i, j)[2]);

                                HistRGB[temp.At <Vec3b>(i, j)[0] + temp.At <Vec3b>(i, j)[1] + temp.At <Vec3b>(i, j)[2]]++;
                            }
                        }

                        int Threshold = 0;
                        int sum       = 0;
                        for (int i = 766; i >= 0; i--)
                        {
                            sum += HistRGB[i];
                            if (sum > inputMat.Rows * inputMat.Cols * 0.1)
                            {
                                Threshold = i;
                                break;
                            }
                        }

                        int AvgB = 0;
                        int AvgG = 0;
                        int AvgR = 0;
                        int cnt  = 0;
                        for (int i = 0; i < inputMat.Rows; i++)
                        {
                            for (int j = 0; j < inputMat.Cols; j++)
                            {
                                int sumP = temp.At <Vec3b>(i, j)[0] + temp.At <Vec3b>(i, j)[1] + temp.At <Vec3b>(i, j)[2];
                                if (sumP > Threshold)
                                {
                                    AvgB += temp.At <Vec3b>(i, j)[0];
                                    AvgG += temp.At <Vec3b>(i, j)[1];
                                    AvgR += temp.At <Vec3b>(i, j)[2];
                                    cnt++;
                                }
                            }
                        }

                        AvgB /= cnt;
                        AvgG /= cnt;
                        AvgR /= cnt;
                        for (int i = 0; i < inputMat.Rows; i++)
                        {
                            for (int j = 0; j < inputMat.Cols; j++)
                            {
                                int Blue  = temp.At <Vec3b>(i, j)[0] * MaxVal / AvgB;
                                int Green = temp.At <Vec3b>(i, j)[1] * MaxVal / AvgG;
                                int Red   = temp.At <Vec3b>(i, j)[2] * MaxVal / AvgR;

                                if (Red > 255)
                                {
                                    Red = 255;
                                }
                                else if (Red < 0)
                                {
                                    Red = 0;
                                }

                                if (Green > 255)
                                {
                                    Green = 255;
                                }
                                else if (Green < 0)
                                {
                                    Green = 0;
                                }

                                if (Blue > 255)
                                {
                                    Blue = 255;
                                }
                                else if (Blue < 0)
                                {
                                    Blue = 0;
                                }

                                temp.At <Vec3b>(i, j)[0] = (byte)Blue;
                                temp.At <Vec3b>(i, j)[1] = (byte)Green;
                                temp.At <Vec3b>(i, j)[2] = (byte)Red;
                            }
                        }

                        Cv2.CvtColor(temp, outputMat, ColorConversionCodes.BGR2BGRA);
                        return(outputMat.MatToSoftwareBitmap());
                    }
        }
Esempio n. 19
0
        public static SoftwareBitmap AutoColorEnhancement(SoftwareBitmap Input)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                    using (Mat Temp = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_32FC3))
                        using (Mat Gray = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_32FC3))
                        {
                            inputMat.ConvertTo(Temp, MatType.CV_32FC3);

                            Cv2.CvtColor(Temp, Gray, ColorConversionCodes.BGR2GRAY);

                            Cv2.MinMaxLoc(Gray, out _, out double LwMax);

                            float LwAver;
                            int   Num;

                            using (Mat Lw_ = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_32FC3))
                            {
                                Num = inputMat.Rows * inputMat.Cols;

                                //计算每个数组元素绝对值的自然对数
                                Cv2.Log(Gray + 1e-3f, Lw_);

                                //矩阵自然指数
                                LwAver = Convert.ToSingle(Math.Exp(Cv2.Sum(Lw_)[0] / Num));
                            }

                            using (Mat Lg = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_32FC3))
                            {
                                Cv2.Log(Gray / LwAver + 1f, Lg);
                                Cv2.Divide(Lg, Math.Log(LwMax / LwAver + 1f), Lg);

                                //局部自适应
                                using (Mat Lout = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_32FC3))
                                {
                                    int kernelSize = Convert.ToInt32(Math.Floor(Convert.ToDouble(Math.Max(3, Math.Max(inputMat.Rows / 100, inputMat.Cols / 100)))));

                                    using (Mat Lp = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_32FC3))
                                    {
                                        using (Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(kernelSize, kernelSize)))
                                        {
                                            Cv2.Dilate(Lg, Lp, kernel);
                                        }

                                        using (Mat Hg = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_32FC3))
                                        {
                                            CvXImgProc.GuidedFilter(Lg, Lp, Hg, 10, 0.01);

                                            Cv2.MinMaxLoc(Lg, out _, out double LgMax);

                                            using (Mat alpha = 1.0f + Lg * (36 / LgMax))
                                                using (Mat Lg_ = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_32FC3))
                                                {
                                                    Cv2.Log(Lg + 1e-3f, Lg_);

                                                    float beta = 10 * Convert.ToSingle(Math.Exp(Cv2.Sum(Lg_)[0] / Num));

                                                    Cv2.Log(Lg / Hg + beta, Lout);
                                                    Cv2.Multiply(alpha, Lout, Lout);
                                                    Cv2.Normalize(Lout, Lout, 0, 255, NormTypes.MinMax);
                                                }
                                        }
                                    }

                                    using (Mat gain = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_32F))
                                    {
                                        for (int i = 0; i < inputMat.Rows; i++)
                                        {
                                            for (int j = 0; j < inputMat.Cols; j++)
                                            {
                                                float x = Gray.At <float>(i, j);
                                                float y = Lout.At <float>(i, j);
                                                gain.At <float>(i, j) = 0 == x ? y : y / x;
                                            }
                                        }

                                        Mat[] BGRChannel = Cv2.Split(Temp);

                                        try
                                        {
                                            BGRChannel[0] = (gain.Mul(BGRChannel[0] + Gray) + BGRChannel[0] - Gray) * 0.5f;
                                            BGRChannel[1] = (gain.Mul(BGRChannel[1] + Gray) + BGRChannel[1] - Gray) * 0.5f;
                                            BGRChannel[2] = (gain.Mul(BGRChannel[2] + Gray) + BGRChannel[2] - Gray) * 0.5f;

                                            Cv2.Merge(BGRChannel, Temp);
                                            Temp.ConvertTo(outputMat, MatType.CV_8UC4);
                                        }
                                        finally
                                        {
                                            Array.ForEach(BGRChannel, (Channel) => Channel.Dispose());
                                        }
                                    }
                                }
                            }

                            return(outputMat.MatToSoftwareBitmap());
                        }
        }
Esempio n. 20
0
        public static SoftwareBitmap AutoWhiteBalance(SoftwareBitmap Input)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                    using (Mat temp = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC3))
                    {
                        Cv2.CvtColor(inputMat, temp, ColorConversionCodes.BGRA2BGR);

                        int[] HistRGB = new int[767];

                        int MaxVal = 0;

                        for (int i = 0; i < inputMat.Rows; i++)
                        {
                            for (int j = 0; j < inputMat.Cols; j++)
                            {
                                Vec3b Vec = temp.At <Vec3b>(i, j);

                                MaxVal = Math.Max(Math.Max(Math.Max(MaxVal, Vec.Item0), Vec.Item1), Vec.Item2);

                                HistRGB[Vec.Item0 + Vec.Item1 + Vec.Item2]++;
                            }
                        }

                        int Threshold = 0;
                        int Sum       = 0;
                        for (int i = 766; i >= 0; i--)
                        {
                            Sum += HistRGB[i];
                            if (Sum > inputMat.Rows * inputMat.Cols * 0.1)
                            {
                                Threshold = i;
                                break;
                            }
                        }

                        int AvgB = 0;
                        int AvgG = 0;
                        int AvgR = 0;
                        int Cnt  = 0;
                        for (int i = 0; i < inputMat.Rows; i++)
                        {
                            for (int j = 0; j < inputMat.Cols; j++)
                            {
                                Vec3b Vec = temp.At <Vec3b>(i, j);

                                int SumP = Vec.Item0 + Vec.Item1 + Vec.Item2;

                                if (SumP > Threshold)
                                {
                                    AvgB += Vec.Item0;
                                    AvgG += Vec.Item1;
                                    AvgR += Vec.Item2;
                                    Cnt++;
                                }
                            }
                        }

                        AvgB /= Cnt;
                        AvgG /= Cnt;
                        AvgR /= Cnt;
                        for (int i = 0; i < inputMat.Rows; i++)
                        {
                            for (int j = 0; j < inputMat.Cols; j++)
                            {
                                Vec3b Vec = temp.At <Vec3b>(i, j);

                                int Blue  = Vec.Item0 * MaxVal / AvgB;
                                int Green = Vec.Item1 * MaxVal / AvgG;
                                int Red   = Vec.Item2 * MaxVal / AvgR;

                                if (Red > 255)
                                {
                                    Red = 255;
                                }
                                else if (Red < 0)
                                {
                                    Red = 0;
                                }

                                if (Green > 255)
                                {
                                    Green = 255;
                                }
                                else if (Green < 0)
                                {
                                    Green = 0;
                                }

                                if (Blue > 255)
                                {
                                    Blue = 255;
                                }
                                else if (Blue < 0)
                                {
                                    Blue = 0;
                                }

                                temp.At <Vec3b>(i, j) = new Vec3b((byte)Blue, (byte)Green, (byte)Red);
                            }
                        }

                        Cv2.CvtColor(temp, outputMat, ColorConversionCodes.BGR2BGRA);
                        return(outputMat.MatToSoftwareBitmap());
                    }
        }