Welcome, guest! Login / Register - Why register?
Psst.. new poll here.
Psst.. new forums here.
Microsoft is blocking us again (TY IP Reputation!) so just use oauth login instead. :)

Paste

Pasted as C# by AlbertEinstein ( 7 years ago )
using System;
using System.Collections.Generic;
using OpenCvSharp;

namespace 
{
	public class ISLAMRemover : OpenCvFilter
	{
		private const Double FloodFillRelativeSeedPoint = 0.01;
		private       Double _floodFillTolerance        = 0.01;

		public Double FloodFillTolerance
		{
			get => _floodFillTolerance;
			set
			{
				if (value > 1)
					throw new ArgumentException("Слишком много толерантности, кому ты пиздишь, насильник!");
				if (value < 0)
					throw new ArgumentException("Слишком мало толерантности, хуемразь!");

				_floodFillTolerance = value;
			}
		}
		public Int32 MaskBlurFactor { get; set; } = 5;

		public override IEnumerable<MatType> SupportedMatTypes => new[] {_8UC3, _8UC4};

		protected override void ProcessFilter(Mat src, Mat dst)
		{
			using (Mat alphaMask = GetGradient(src))
			{
				void PerformMorphologyEx(MorphTypes operation, Int32 iterations)
				{
					Double elementSize = Math.Sqrt(alphaMask.Width * alphaMask.Height) / 300;
					if (elementSize < 3)
						elementSize = 3;
					if (elementSize > 20)
						elementSize = 20;
					using (var se = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(elementSize, elementSize)))
					{
						Cv2.MorphologyEx(alphaMask, alphaMask, operation, se, null, iterations);
					}
				}
				PerformMorphologyEx(MorphTypes.Dilate, 1);
				Cv2.FloodFill(
					image: alphaMask,
					seedPoint: new Point(
						(Int32) (FloodFillRelativeSeedPoint * src.Width),
						(Int32) (FloodFillRelativeSeedPoint * src.Height)),
					newVal: new Scalar(0),
					rect: out Rect _,
					loDiff: new Scalar(FloodFillTolerance),
					upDiff: new Scalar(FloodFillTolerance),
					flags: FloodFillFlags.FixedRange | FloodFillFlags.Link4);
				PerformMorphologyEx(MorphTypes.Erode, 1);
				PerformMorphologyEx(MorphTypes.Open,  2); 
				PerformMorphologyEx(MorphTypes.Erode, 1);

				Cv2.Threshold(
					src: alphaMask,
					dst: alphaMask,
					thresh: 0,
					maxval: 255,
					type: ThresholdTypes.Binary);

				alphaMask.ConvertTo(alphaMask, _8UC1, 255);

				if (MaskBlurFactor > 0)
					Cv2.GaussianBlur(alphaMask, alphaMask, new Size(MaskBlurFactor, MaskBlurFactor), MaskBlurFactor);

				AddAlphaChannel(src, dst, alphaMask);
			}
		}
		private static void AddAlphaChannel(Mat src, Mat dst, Mat alpha)
		{
			var bgr  = Cv2.Split(src);
			var bgra = new[] {bgr[0], bgr[1], bgr[2], alpha};
			Cv2.Merge(bgra, dst);
		}
		private Mat GetGradient(Mat src)
		{
			using (var preparedSrc = new Mat())
			{
				Cv2.CvtColor(src, preparedSrc, ColorConversionCodes.BGR2GRAY);
				preparedSrc.ConvertTo(preparedSrc, _32FC1, 1.0 / 255);
				Mat Derivative(Int32 dx, Int32 dy)
				{
					Int32 resolution = preparedSrc.Width * preparedSrc.Height;
					Int32 kernelSize =
						resolution < 1280 * 1280 ? 3 : // Larger image --> larger kernel
						resolution < 2000 * 2000 ? 5 :
						resolution < 3000 * 3000 ? 9 :
						                           15;
					Single kernelFactor = kernelSize == 3 ? 1 : 2;

					using (var kernelRows = new Mat())
					using (var kernelColumns = new Mat())
					{
						Cv2.GetDerivKernels(kernelRows, kernelColumns, dx, dy, kernelSize, normalize: true);

						using (var multipliedKernelRows = kernelRows * kernelFactor)
						using (var multipliedKernelColumns = kernelColumns * kernelFactor)
						{
							return preparedSrc.SepFilter2D(_32FC1, multipliedKernelRows, multipliedKernelColumns);
						}
					}
				}

				using (var gradX = Derivative(1, 0))
				using (var gradY = Derivative(0, 1))
				{
					var result = new Mat();
					Cv2.Magnitude(gradX, gradY, result);

					result += 0.15f;
					return result;
				}
			}
		}
	}
}

 

Revise this Paste

Children: 101326
Your Name: Code Language: