حذف پس زمینه تصویر C#

در تولید و دستکاری محتوای دیجیتال، حذف پس زمینه از تصاویر یک کار معمول و ضروری است. چه در حال کار بر روی طراحی گرافیکی، تجارت الکترونیک یا هر پروژه بصری دیگری باشید، داشتن توانایی جداسازی اشیا از پس زمینه آنها خلاقیت شما را افزایش می دهد. در این پست وبلاگ، نحوه حذف پس‌زمینه تصاویر را به صورت برنامه‌نویسی در سی شارپ بررسی خواهیم کرد.

کتابخانه سی شارپ برای حذف پس زمینه از تصاویر

برای حذف پس‌زمینه از تصاویر، از Aspose.Imaging for .NET استفاده می‌کنیم - یک کتابخانه قدرتمند که طیف وسیعی از ویژگی‌های پردازش تصویر را برای برنامه‌های NET فراهم می‌کند. این برنامه از فرمت های مختلف تصویر پشتیبانی می کند و به توسعه دهندگان اجازه می دهد تا عملیاتی مانند تغییر اندازه، برش، چرخش و البته حذف پس زمینه را به راحتی انجام دهند.

می توانید API را دانلود یا از NuGet نصب کنید.

PM> Install-Package Aspose.Imaging

حذف پس‌زمینه تصویر با پوشش خودکار در سی شارپ

برای دریافت بهتر نتایج حذف پس‌زمینه، روش پوشش خودکار ترجیح داده می‌شود. هدف ایجاد ماسکی است که پیکسل های متعلق به پیش زمینه و پیکسل های مربوط به پس زمینه را به دقت شناسایی کند. Aspose.Imaging سه تکنیک پوشش خودکار را برای حذف پس‌زمینه از تصویر ارائه می‌کند، همانطور که در بخش‌های زیر توضیح داده شده است.

Graph Cut Auto Masking with Feathering

در این تکنیک، API پوشش تصویر را با پر کردن بر اساس اندازه تصویر انجام می‌دهد و از ضربات پیش‌فرض محاسبه‌شده خودکار استفاده می‌کند. قطعه کد زیر نحوه استفاده از پوشش خودکار برش نمودار با پر کردن را نشان می دهد. خاصیت Args AutoMaskingGraphCutOptions را می توان حذف کرد زیرا در انتها ضربه های پیش فرض در آنجا قرار می گیرند.

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"))
{
    // برای استفاده از Graph Cut با ضربه های محاسبه شده خودکار، AutoMaskingGraphCutOptions استفاده می شود.
    AutoMaskingGraphCutOptions options = new AutoMaskingGraphCutOptions
    {
        // نشان می دهد که یک محاسبه جدید از ضربات پیش فرض باید در طول تجزیه تصویر انجام شود.
        CalculateDefaultStrokes = true,
        // تنظیم شعاع پر کردن پس از فرآیند بر اساس اندازه تصویر.
        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");

اسکرین شات زیر تصاویر ورودی و خروجی را نشان می دهد.

حذف پس زمینه تصویر در سی شارپ

استفاده مجدد از ضربات پیش فرض در پوشش خودکار مکرر

در این تکنیک، پوشش تصویر با استفاده از ضربات پیش‌فرض محاسبه‌شده خودکار انجام می‌شود، با این حال، API دوباره از گزینه‌های ماسک برای تکرار پوشش جدید استفاده می‌کند. در قطعه کد زیر، می توانید متوجه شوید که داده های دو شیء فرضی نیز در ویژگی AssumedObjects AutoMaskingGraphCutOptions مشخص شده است. پس از نتایج اولیه ماسک، تنظیماتی در سکته‌های پس‌زمینه/پیش‌زمینه اعمال‌شده انجام می‌شود و یک تکرار بعدی از پوشش انجام می‌شود.

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;

// برای بهبود نتایج پوشش، داده‌های اشیاء خاصی که باید در نتیجه پوشش پیش‌زمینه گنجانده شوند، می‌توانند ارائه شوند.
List<AssumedObjectData> assumedObjects = new List<AssumedObjectData>();
// نوع شی و ناحیه حاوی آن شی باید مشخص شود.
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"))
{
    // برای استفاده از Graph Cut با ضربه های محاسبه شده خودکار، AutoMaskingGraphCutOptions استفاده می شود.
    options = new AutoMaskingGraphCutOptions
    {
        AssumedObjects = assumedObjects,
        // نشان می دهد که یک محاسبه جدید از ضربات پیش فرض باید در طول تجزیه تصویر انجام شود.
        CalculateDefaultStrokes = true,
        // تنظیم شعاع پر کردن پس از فرآیند بر اساس اندازه تصویر.
        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();

        // ذخیره نتیجه ماسک میانی.
        using (RasterImage resultImage = results[1].GetImage())
        {
            resultImage.Save(dataDir + "result2.png",
                new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
        }

        // در این مرحله، سکته‌های پیش‌زمینه/پس‌زمینه اعمال‌شده را می‌توان آنالیز کرد و بر اساس آن اضافه کرد 
        // سکته مغزی پیش زمینه / پس زمینه را می توان به صورت دستی ارائه کرد.
        appliedBackgroundStrokes = options.DefaultBackgroundStrokes;
        appliedForegroundStrokes = options.DefaultForegroundStrokes;
        appliedObjectRectangles = options.DefaultObjectsRectangles;

        // با استفاده مجدد از AutoMaskingGraphCutOptions، نیازی به انجام محاسبات پیش فرض استروک برای بار دوم نیست.
        // هنگامی که هر دو strokes پیش‌فرض و ObjectsPoints در ویژگی Args AutoMaskingArgs ارائه می‌شوند، آرایه‌های نقطه‌ای در نهایت ترکیب می‌شوند.
        // اولین آرایه ObjectsPoints یک آرایه نقاط پس زمینه در نظر گرفته می شود و 
        // آرایه دوم ObjectsPoints به عنوان یک آرایه نقاط پیش زمینه در نظر گرفته می شود.
        // هنگامی که هر دو DefaultObjectsRectangles و ObjectsRectangles در ویژگی Args AutoMaskingArgs ارائه می شوند، 
        // فقط آرایه از Args استفاده می شود.
        AutoMaskingArgs newAutoMaskingArgs = new AutoMaskingArgs()
        {
            ObjectsPoints = new Point[][]
            {
                // علاوه بر این، مناطقی که می‌خواهیم حذف شوند را مشخص می‌کنیم.
                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 });
        }
    }
}
//مثال - نمودار - برش - تکرار - پوشاندن - با - new- points.cs
// برای بهبود نتایج پوشش، داده‌های اشیاء خاصی که باید در نتیجه پوشش پیش‌زمینه گنجانده شوند، می‌توانند ارائه شوند.
assumedObjects = new List<AssumedObjectData>();
// نوع شی و ناحیه حاوی آن شی باید مشخص شود.
assumedObjects.Add(new AssumedObjectData(DetectedObjectType.Human, new Rectangle(100, 100, 150, 300)));

// اولین تکرار ماسک برای محاسبه خودکار ضربات قلم مو پیش زمینه/پس زمینه انجام می شود.
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // برای استفاده از Graph Cut با ضربه های محاسبه شده خودکار، AutoMaskingGraphCutOptions استفاده می شود.
    options = new AutoMaskingGraphCutOptions
    {
        AssumedObjects = assumedObjects,
        // نشان می دهد که یک محاسبه جدید از ضربات پیش فرض باید در طول تجزیه تصویر انجام شود.
        CalculateDefaultStrokes = true,
        // تنظیم شعاع پر کردن پس از فرآیند.
        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);

    // در این مرحله، سکته‌های پیش‌زمینه/پس‌زمینه اعمال‌شده را می‌توان آنالیز کرد و بر اساس آن اضافه کرد 
    // سکته مغزی پیش زمینه / پس زمینه را می توان به صورت دستی ارائه کرد.
    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 });
    }
}



// تکرار پوشش دوم برای بهبود بیشتر کیفیت پوشش با افزودن نقاط پیش زمینه/پس زمینه جدید انتخاب شده به صورت دستی انجام می شود.
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // با استفاده مجدد از AutoMaskingGraphCutOptions، نیازی به انجام محاسبات پیش فرض استروک برای بار دوم نیست.
    options.CalculateDefaultStrokes = false;
    // هنگامی که هر دو strokes پیش‌فرض و ObjectsPoints در ویژگی Args AutoMaskingArgs ارائه می‌شوند، آرایه‌های نقطه‌ای در نهایت ترکیب می‌شوند.
    // اولین آرایه ObjectsPoints یک آرایه نقاط پس زمینه در نظر گرفته می شود و 
    // آرایه دوم ObjectsPoints به عنوان یک آرایه نقاط پیش زمینه در نظر گرفته می شود.
    // هنگامی که هر دو DefaultObjectsRectangles و ObjectsRectangles در ویژگی Args AutoMaskingArgs ارائه می شوند، 
    // فقط آرایه از 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);

    // ذخیره نتیجه پوشش نهایی
    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result6.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}



///<summary>
/// تمام نقاطی که متعلق به مستطیل های مشخص شده است را برگردانید.
///</summary>
///<param name="rectangles"> آرایه مستطیل ها</param>
///<returns> تمام نقاط مستطیل</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");

اسکرین شات زیر تصاویر ورودی و خروجی را نشان می دهد.

پوشش خودکار مکرر برای حذف پس زمینه

پوشش خودکار برش نمودار با داده های شیء فرضی مشخص شده

در این تکنیک، داده‌های یک شی مفروض خاص در ویژگی AssumedObjects AutoMaskingGraphCutOptions استفاده می‌شود که در تکرارهای پوشاندن بعدی استفاده می‌شود. قطعه کد زیر نحوه استفاده از پوشش خودکار برش نمودار را با یک شیء فرضی برای حذف پس‌زمینه تصویر نشان می‌دهد.

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;

// برای بهبود نتایج پوشش، داده‌های اشیاء خاصی که باید در نتیجه پوشش پیش‌زمینه گنجانده شوند، می‌توانند ارائه شوند.
List<AssumedObjectData> assumedObjects = new List<AssumedObjectData>();
// نوع شی و ناحیه حاوی آن شی باید مشخص شود.
assumedObjects.Add(new AssumedObjectData(DetectedObjectType.Human, new Rectangle(0, 0, 256, 365)));

MaskingResult results;
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // برای استفاده از Graph Cut با ضربه های محاسبه شده خودکار، AutoMaskingGraphCutOptions استفاده می شود.
    AutoMaskingGraphCutOptions options = new AutoMaskingGraphCutOptions
    {
        AssumedObjects = assumedObjects,
        // نشان می دهد که یک محاسبه جدید از ضربات پیش فرض باید در طول تجزیه تصویر انجام شود.
        CalculateDefaultStrokes = true,
        // تنظیم شعاع پر کردن پس از فرآیند بر اساس اندازه تصویر.
        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");

اسکرین شات زیر تصاویر ورودی و خروجی را نشان می دهد.

پوشش خودکار برش نمودار با شیء فرضی

حذف پس زمینه تصویر با استفاده از پوشش دستی

اگر علاقه ای به ماسک کردن خودکار ندارید، می توانید از روش پوشاندن دستی برای حذف پس زمینه از تصاویر استفاده کنید. قطعه کد زیر نحوه اعمال پوشش دستی روی یک تصویر شطرنجی برای حذف پس‌زمینه آن را نشان می‌دهد.

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);
    // ذخیره نتیجه پوشش نهایی
    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}       

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

اسکرین شات زیر تصاویر ورودی و خروجی را نشان می دهد.

پوشش دستی برای حذف پس زمینه

C# Image Background Remover API را دریافت کنید

شما می توانید یک مجوز موقت رایگان دریافت کنید و از کتابخانه ویرایش تصویر و حذف پس زمینه ما بدون هیچ محدودیتی استفاده کنید.

نتیجه

حذف پس زمینه از تصاویر یک مهارت بسیار مهم در ویرایش و طراحی تصویر است. Aspose.Imaging for .NET به توسعه دهندگان این امکان را می دهد که به طور دقیق پس زمینه تصاویر را در برنامه های C# حذف کنند. این پست وبلاگ اصول بارگذاری تصاویر، پیاده سازی حذف پس زمینه با استفاده از روش های مختلف پوشش خودکار و دستی و ذخیره تصویر خروجی را پوشش می دهد.

با ادغام Aspose.Imaging در پروژه های C# خود، می توانید گردش کار پردازش تصویر را ساده کنید و سطح جدیدی از خلاقیت را در برنامه های خود باز کنید. برای کشف پتانسیل کامل Aspose.Imaging برای دات نت، [ویژگی ها و تکنیک های مختلف] را آزمایش کنید. همچنین، سؤالات خود را از طریق [فروم 3 ما با ما در میان بگذارید.

همچنین ببینید