如何进行图片去除背景,利用C#

日常我们经常碰到图片去除背景的问题,比如我希望人物的周边背景均替换为背景色,但人物衣服上跟背景色接近的部分不受影响。最典型的例子就是身份证照片更换背景色,这需要用到复杂一点的算法。从图片的上部、左部、右部和下部开始,使用边界检测方法处理,直到遇到与背景颜色不相似的像素为止。程序如下,成品演示详见https://calc.xycost.com/Chatgpt/Changebg.aspx

   public class ImageProcessor
    {
        public static Bitmap ReplaceSimilarColorsBoundary(string imagePath, Color originalColor, Color replacementColor, int tolerance)
        {
            Bitmap image = new Bitmap(imagePath);
            bool[,] visited = new bool[image.Width, image.Height];

            bool IsSimilar(Color color1, Color color2)
            {
                int diffR = Math.Abs(color1.R - color2.R);
                int diffG = Math.Abs(color1.G - color2.G);
                int diffB = Math.Abs(color1.B - color2.B);
                return (diffR + diffG + diffB) <= tolerance;
            }

            void FloodFill(int x, int y)
            {
                Stack<Point> stack = new Stack<Point>();
                stack.Push(new Point(x, y));

                while (stack.Count > 0)
                {
                    Point current = stack.Pop();
                    if (current.X < 0 || current.X >= image.Width || current.Y < 0 || current.Y >= image.Height)
                        continue;

                    if (visited[current.X, current.Y] || !IsSimilar(image.GetPixel(current.X, current.Y), originalColor))
                        continue;

                    visited[current.X, current.Y] = true;
                    image.SetPixel(current.X, current.Y, replacementColor);

                    stack.Push(new Point(current.X + 1, current.Y));
                    stack.Push(new Point(current.X - 1, current.Y));
                    stack.Push(new Point(current.X, current.Y + 1));
                    stack.Push(new Point(current.X, current.Y - 1));
                }
            }

            // Start flood fill from the four corners
            FloodFill(0, 0);
            FloodFill(0, image.Height - 1);
            FloodFill(image.Width - 1, 0);
            FloodFill(image.Width - 1, image.Height - 1);

            return image;
        }
    }