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