如何进行图片去除背景,利用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; } }