Rimuovi lo sfondo dell'immagine C#

Nella creazione e manipolazione di contenuti digitali, rimuovere lo sfondo dalle immagini è un compito comune ed essenziale. Che tu stia lavorando alla progettazione grafica, all’e-commerce o a qualsiasi altro progetto visivo, avere la possibilità di isolare gli oggetti dai loro sfondi amplia la tua creatività. In questo post del blog esploreremo come rimuovere lo sfondo dalle immagini a livello di codice in C#.

Libreria C# per rimuovere lo sfondo dalle immagini

Per rimuovere lo sfondo dalle immagini, utilizzeremo Aspose.Imaging for .NET, una potente libreria che fornisce un’ampia gamma di funzionalità di elaborazione delle immagini per le applicazioni .NET. Supporta vari formati di immagine e consente agli sviluppatori di eseguire operazioni come ridimensionare, ritagliare, ruotare e, ovviamente, rimuovere facilmente gli sfondi.

È possibile scaricare l’API o installarla da NuGet.

PM> Install-Package Aspose.Imaging

Rimozione dello sfondo dell’immagine con mascheramento automatico in C#

Per ottenere risultati migliori nella rimozione dello sfondo, è preferibile il metodo di mascheramento automatico. L’obiettivo è creare una maschera che identifichi con precisione i pixel appartenenti al primo piano e quelli appartenenti allo sfondo. Aspose.Imaging fornisce tre tecniche di mascheramento automatico per rimuovere lo sfondo dall’immagine, come descritto nelle sezioni seguenti.

Mascheramento automatico del taglio del grafico con sfumatura

In questa tecnica, l’API esegue il mascheramento dell’immagine con sfumatura in base alla dimensione dell’immagine e utilizza tratti predefiniti calcolati automaticamente. Il seguente frammento di codice mostra come utilizzare il mascheramento automatico del taglio grafico con sfumatura. La proprietà Args di AutoMaskingGraphCutOptions può essere omessa poiché i tratti predefiniti vengono posizionati lì alla fine.

using Aspose.Imaging;
using Aspose.Imaging.FileFormats.Png;
using Aspose.Imaging.ImageOptions;
using Aspose.Imaging.Masking;
using Aspose.Imaging.Masking.Options;
using Aspose.Imaging.Masking.Result;
using Aspose.Imaging.Sources;
using System;
using System.IO;

string templatesFolder = @"c:\Users\USER\Downloads\templates\";
string dataDir = templatesFolder;

MaskingResult results;
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // Per utilizzare Taglio grafico con tratti calcolati automaticamente, viene utilizzato AutoMaskingGraphCutOptions.
    AutoMaskingGraphCutOptions options = new AutoMaskingGraphCutOptions
    {
        // Indica che durante la scomposizione dell'immagine deve essere eseguito un nuovo calcolo dei tratti predefiniti.
        CalculateDefaultStrokes = true,
        // Impostazione del raggio di sfumatura post-elaborazione in base alla dimensione dell'immagine.
        FeatheringRadius = (Math.Max(image.Width, image.Height) / 500) + 1,
        Method = SegmentationMethod.GraphCut,
        Decompose = false,
        ExportOptions =
                                                        new PngOptions()
                                                        {
                                                            ColorType = PngColorType.TruecolorWithAlpha,
                                                            Source = new FileCreateSource(dataDir + "result.png")
                                                        },
        BackgroundReplacementColor = Color.Transparent
    };

    results = new ImageMasking(image).Decompose(options);

    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result2.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}



File.Delete(dataDir + "result.png");
File.Delete(dataDir + "result2.png");

La schermata seguente mostra le immagini di input e output.

rimozione dello sfondo dell'immagine in C#

Riutilizzo dei tratti predefiniti nel mascheramento automatico ripetuto

In questa tecnica, il mascheramento dell’immagine viene eseguito utilizzando tratti predefiniti calcolati automaticamente, tuttavia, l’API riutilizza le opzioni di mascheramento per la nuova iterazione di mascheramento. Nel seguente frammento di codice, puoi notare che i dati dei due oggetti presunti sono specificati anche nella proprietà AssumedObjects di AutoMaskingGraphCutOptions. Dopo i risultati iniziali del mascheramento, vengono apportate modifiche ai tratti di sfondo/primo piano applicati e viene eseguita una successiva iterazione del mascheramento.

using Aspose.Imaging;
using Aspose.Imaging.FileFormats.Png;
using Aspose.Imaging.ImageOptions;
using Aspose.Imaging.Masking;
using Aspose.Imaging.Masking.Options;
using Aspose.Imaging.Masking.Result;
using Aspose.Imaging.Sources;
using System;
using System.Collections.Generic;
using System.IO;

string templatesFolder = @"c:\Users\USER\Downloads\templates\";
string dataDir = templatesFolder;

// Per migliorare i risultati del mascheramento, potrebbero essere forniti i dati degli oggetti specifici che dovrebbero essere inclusi nel risultato del mascheramento in primo piano.
List<AssumedObjectData> assumedObjects = new List<AssumedObjectData>();
// È necessario specificare il tipo di oggetto e l'area che lo contiene.
assumedObjects.Add(new AssumedObjectData(DetectedObjectType.Human, new Rectangle(0, 0, 300, 300)));

MaskingResult results;
AutoMaskingGraphCutOptions options;
Point[] appliedBackgroundStrokes;
Point[] appliedForegroundStrokes;
Rectangle[] appliedObjectRectangles;

using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // Per utilizzare Taglio grafico con tratti calcolati automaticamente, viene utilizzato AutoMaskingGraphCutOptions.
    options = new AutoMaskingGraphCutOptions
    {
        AssumedObjects = assumedObjects,
        // Indica che durante la scomposizione dell'immagine deve essere eseguito un nuovo calcolo dei tratti predefiniti.
        CalculateDefaultStrokes = true,
        // Impostazione del raggio di sfumatura post-elaborazione in base alla dimensione dell'immagine.
        FeatheringRadius = (Math.Max(image.Width, image.Height) / 500) + 1,
        Method = SegmentationMethod.GraphCut,
        Decompose = false,
        ExportOptions = new PngOptions()
        {
            ColorType = PngColorType.TruecolorWithAlpha,
            Source = new FileCreateSource(dataDir + "result.png")
        },
        BackgroundReplacementColor = Color.Transparent
    };

    using (IMaskingSession maskingSession = new ImageMasking(image).CreateSession(options))
    {
        results = maskingSession.Decompose();

        // Salvataggio del risultato del mascheramento intermedio.
        using (RasterImage resultImage = results[1].GetImage())
        {
            resultImage.Save(dataDir + "result2.png",
                new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
        }

        // A questo punto i tratti di primo piano/sfondo applicati possono essere analizzati e basati su di essi aggiuntivi 
        // i tratti di primo piano/sfondo possono essere forniti manualmente.
        appliedBackgroundStrokes = options.DefaultBackgroundStrokes;
        appliedForegroundStrokes = options.DefaultForegroundStrokes;
        appliedObjectRectangles = options.DefaultObjectsRectangles;

        // Riutilizzando AutoMaskingGraphCutOptions non è necessario eseguire i calcoli del tratto predefinito una seconda volta.
        // Quando vengono forniti sia i tratti predefiniti che gli ObjectsPoints nella proprietà Args di AutoMaskingArgs, le matrici di punti vengono combinate.
        // Il primo array ObjectsPoints è considerato un array di punti di sfondo e 
        // il secondo array ObjectsPoints è considerato un array di punti in primo piano.
        // Quando vengono forniti sia DefaultObjectsRectangles che ObjectsRectangles nella proprietà Args di AutoMaskingArgs, 
        // viene utilizzato solo l'array di Args.
        AutoMaskingArgs newAutoMaskingArgs = new AutoMaskingArgs()
        {
            ObjectsPoints = new Point[][]
            {
                // Specificando inoltre le aree che vogliamo vengano rimosse.
                GetRectanglePoints(
                    new Rectangle(100, 100, 35, 90),
                    new Rectangle(300, 140, 95, 50)
                )
            },
        };

        results = maskingSession.ImproveDecomposition(newAutoMaskingArgs);

        using (RasterImage resultImage = results[1].GetImage())
        {
            resultImage.Save(dataDir +
                "result3.png",
                new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
        }
    }
}
//Esempi - grafico - tagliato - ripetuto - mascheramento - con - nuovi-punti.cs
// Per migliorare i risultati del mascheramento, potrebbero essere forniti i dati degli oggetti specifici che dovrebbero essere inclusi nel risultato del mascheramento in primo piano.
assumedObjects = new List<AssumedObjectData>();
// È necessario specificare il tipo di oggetto e l'area che lo contiene.
assumedObjects.Add(new AssumedObjectData(DetectedObjectType.Human, new Rectangle(100, 100, 150, 300)));

// La prima iterazione del mascheramento viene eseguita per ottenere pennellate di primo piano/sfondo calcolate automaticamente.
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // Per utilizzare Taglio grafico con tratti calcolati automaticamente, viene utilizzato AutoMaskingGraphCutOptions.
    options = new AutoMaskingGraphCutOptions
    {
        AssumedObjects = assumedObjects,
        // Indica che durante la scomposizione dell'immagine deve essere eseguito un nuovo calcolo dei tratti predefiniti.
        CalculateDefaultStrokes = true,
        // Impostazione del raggio di sfumatura post-elaborazione.
        FeatheringRadius = 3,
        Method = SegmentationMethod.GraphCut,
        Decompose = false,
        ExportOptions =
                            new PngOptions()
                            {
                                ColorType = PngColorType.TruecolorWithAlpha,
                                Source = new FileCreateSource(dataDir + "result4.png")
                            },
        BackgroundReplacementColor = Color.Transparent
    };

    results = new ImageMasking(image).Decompose(options);

    // A questo punto i tratti di primo piano/sfondo applicati possono essere analizzati e basati su di essi aggiuntivi 
    // i tratti di primo piano/sfondo possono essere forniti manualmente.
    appliedBackgroundStrokes = options.DefaultBackgroundStrokes;
    appliedForegroundStrokes = options.DefaultForegroundStrokes;
    appliedObjectRectangles = options.DefaultObjectsRectangles;
    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result5.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}



// Viene eseguita la seconda iterazione del mascheramento per migliorare ulteriormente la qualità del mascheramento aggiungendo nuovi punti di primo piano/sfondo scelti manualmente.
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // Riutilizzando AutoMaskingGraphCutOptions non è necessario eseguire i calcoli del tratto predefinito una seconda volta.
    options.CalculateDefaultStrokes = false;
    // Quando vengono forniti sia i tratti predefiniti che gli ObjectsPoints nella proprietà Args di AutoMaskingArgs, le matrici di punti vengono combinate.
    // Il primo array ObjectsPoints è considerato un array di punti di sfondo e 
    // il secondo array ObjectsPoints è considerato un array di punti in primo piano.
    // Quando vengono forniti sia DefaultObjectsRectangles che ObjectsRectangles nella proprietà Args di AutoMaskingArgs, 
    // viene utilizzato solo l'array di Args.
    options.Args = new AutoMaskingArgs()
    {
        ObjectsPoints = new Point[][]
                                                {
                                                    new Point[] { new Point(100, 100), new Point(150, 100) },
                                                    new Point[] { new Point(300, 200) },
                                                },
        ObjectsRectangles = new Rectangle[]
                                                    {
                                                        new Rectangle(100, 100, 300, 300),
                                                    }
    };

    results = new ImageMasking(image).Decompose(options);

    // Salvataggio del risultato finale del mascheramento.
    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result6.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}



///<summary>
/// Restituisce tutti i punti che appartengono ai rettangoli specificati.
///</summary>
///<param name="rectangles"> La matrice di rettangoli.</param>
///<returns> Tutti i punti del rettangolo.</returns>
static Point[] GetRectanglePoints(params Rectangle[] rectangles)
{
    int arraySize = 0;
    foreach (Rectangle rectangle in rectangles)
    {
        arraySize += rectangle.Width * rectangle.Height;
    }

    Point[] pointArray = new Point[arraySize];
    int arrayIndex = 0;
    foreach (Rectangle rectangle in rectangles)
    {
       for (int x = rectangle.Left; x < rectangle.Right; x++)
        {
           for (int y = rectangle.Top; y < rectangle.Bottom; y++)
            {
                pointArray[arrayIndex++] = new Point(x, y);
            }
        }
    }

    return pointArray;
}


File.Delete(dataDir + "result.png");
File.Delete(dataDir + "result2.png");
File.Delete(dataDir + "result3.png");
File.Delete(dataDir + "result4.png");
File.Delete(dataDir + "result5.png");
File.Delete(dataDir + "result6.png");

La schermata seguente mostra le immagini di input e output.

Mascheramento automatico ripetuto per la rimozione dello sfondo

Mascheramento automatico del taglio del grafico con i dati oggetto presupposti specificati

In questa tecnica, i dati di uno specifico oggetto presunto vengono utilizzati nella proprietà AssumedObjects di AutoMaskingGraphCutOptions, che viene utilizzata nelle successive iterazioni di mascheramento. Il seguente frammento di codice mostra come utilizzare il mascheramento automatico del taglio del grafico con un oggetto presunto per rimuovere lo sfondo di un’immagine.

using Aspose.Imaging;
using Aspose.Imaging.FileFormats.Png;
using Aspose.Imaging.ImageOptions;
using Aspose.Imaging.Masking;
using Aspose.Imaging.Masking.Options;
using Aspose.Imaging.Masking.Result;
using Aspose.Imaging.Sources;
using System;
using System.Collections.Generic;
using System.IO;

string templatesFolder = @"c:\Users\USER\Downloads\templates\";
string dataDir = templatesFolder;

// Per migliorare i risultati del mascheramento, potrebbero essere forniti i dati degli oggetti specifici che dovrebbero essere inclusi nel risultato del mascheramento in primo piano.
List<AssumedObjectData> assumedObjects = new List<AssumedObjectData>();
// È necessario specificare il tipo di oggetto e l'area che lo contiene.
assumedObjects.Add(new AssumedObjectData(DetectedObjectType.Human, new Rectangle(0, 0, 256, 365)));

MaskingResult results;
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // Per utilizzare Taglio grafico con tratti calcolati automaticamente, viene utilizzato AutoMaskingGraphCutOptions.
    AutoMaskingGraphCutOptions options = new AutoMaskingGraphCutOptions
    {
        AssumedObjects = assumedObjects,
        // Indica che durante la scomposizione dell'immagine deve essere eseguito un nuovo calcolo dei tratti predefiniti.
        CalculateDefaultStrokes = true,
        // Impostazione del raggio di sfumatura post-elaborazione in base alla dimensione dell'immagine.
        FeatheringRadius = (Math.Max(image.Width, image.Height) / 500) + 1,
        Method = SegmentationMethod.GraphCut,
        Decompose = false,
        ExportOptions =
                                                        new PngOptions()
                                                        {
                                                            ColorType = PngColorType.TruecolorWithAlpha,
                                                            Source = new FileCreateSource(dataDir + "result.png")
                                                        },
        BackgroundReplacementColor = Color.Transparent
    };

    results = new ImageMasking(image).Decompose(options);

    // Salvataggio del risultato finale del mascheramento.
    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result2.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}



File.Delete(dataDir + "result.png");
File.Delete(dataDir + "result2.png");

La schermata seguente mostra le immagini di input e output.

Mascheramento automatico del taglio del grafico con l'oggetto presunto

Rimozione dello sfondo dell’immagine utilizzando il mascheramento manuale

Se non sei interessato al mascheramento automatico, puoi utilizzare il metodo di mascheramento manuale per rimuovere lo sfondo dalle immagini. Il seguente frammento di codice mostra come applicare il mascheramento manuale a un’immagine raster per rimuoverne lo sfondo.

using Aspose.Imaging;
using Aspose.Imaging.FileFormats.Png;
using Aspose.Imaging.ImageOptions;
using Aspose.Imaging.Masking;
using Aspose.Imaging.Masking.Options;
using Aspose.Imaging.Masking.Result;
using Aspose.Imaging.Shapes;
using Aspose.Imaging.Sources;
using System.IO;

string templatesFolder = @"c:\Users\USER\Downloads\templates\";
string dataDir = templatesFolder;

string sourceFileName = dataDir + "couple.png";
GraphicsPath manualMask = new GraphicsPath();
Figure firstFigure = new Figure();
firstFigure.AddShape(new EllipseShape(new RectangleF(100, 30, 40, 40)));
firstFigure.AddShape(new RectangleShape(new RectangleF(10, 200, 50, 30)));
manualMask.AddFigure(firstFigure);
GraphicsPath subPath = new GraphicsPath();
Figure secondFigure = new Figure();
secondFigure.AddShape(
    new PolygonShape(
     new PointF[]
     {
         new PointF(310, 100), new PointF(350, 200), new PointF(250, 200)

     }, true));

secondFigure.AddShape(new PieShape(new RectangleF(10, 10, 80, 80), 30, 120));
subPath.AddFigure(secondFigure);
manualMask.AddPath(subPath);
using (RasterImage image = (RasterImage)Image.Load(sourceFileName))
{
    MaskingOptions maskingOptions = new MaskingOptions()
    {
        Method = SegmentationMethod.Manual,
        Args = new ManualMaskingArgs
        {
            Mask = manualMask
        },
        Decompose = false,
        ExportOptions =
      new PngOptions()
      {
          ColorType = PngColorType.TruecolorWithAlpha,
          Source = new StreamSource(new MemoryStream())
      },
    };
    MaskingResult results = new ImageMasking(image).Decompose(maskingOptions);
    // Salvataggio del risultato finale del mascheramento.
    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}       

File.Delete(dataDir + "result.png");

La schermata seguente mostra le immagini di input e output.

Mascheramento manuale per la rimozione dello sfondo

Ottieni l’API C# per la rimozione dello sfondo dell’immagine

Puoi ottenere una licenza temporanea gratuita e utilizzare la nostra libreria di modifica delle immagini e rimozione dello sfondo senza alcuna limitazione.

Conclusione

Rimuovere gli sfondi dalle immagini è un’abilità cruciale nell’editing e nella progettazione delle immagini. Aspose.Imaging for .NET consente agli sviluppatori di rimuovere con precisione gli sfondi dalle immagini nelle applicazioni C#. Questo post del blog ha trattato le nozioni di base sul caricamento delle immagini, sull’implementazione della rimozione dello sfondo utilizzando diversi metodi di mascheramento automatico e manuale e sul salvataggio dell’immagine di output.

Integrando Aspose.Imaging nei tuoi progetti C#, puoi semplificare il flusso di lavoro di elaborazione delle immagini e sbloccare un nuovo livello di creatività nelle tue applicazioni. Sperimenta diverse funzionalità e tecniche per scoprire tutto il potenziale di Aspose.Imaging for .NET. Inoltre, condividi le tue domande con noi tramite il nostro forum.

Guarda anche