复制 import cv2
import numpy as np
# 加载图像
img = cv2.imread('input.jpg')
# 转换到 HSV 色彩空间,便于基于颜色的抠图
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 定义绿色背景的范围(证件照常见背景色)
lower_green = np.array([40, 40, 40])
upper_green = np.array([80, 255, 255])
mask = cv2.inRange(hsv, lower_green, upper_green)
# 形态学操作去除噪点
kernel = np.ones((5,5), np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
# 生成透明背景(alpha 通道)
bgra = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
bgra[:,:,3] = cv2.bitwise_not(mask)
# 替换为红色背景
red_bg = np.full_like(img, (0, 0, 255), dtype=np.uint8)
result = cv2.bitwise_and(img, img, mask=cv2.bitwise_not(mask))
result = cv2.add(result, cv2.bitwise_and(red_bg, red_bg, mask=mask))
cv2.imwrite('output.jpg', result)复制 package main
import (
"image"
"image/color"
"image/jpeg"
"log"
"os"
)
func main() {
// 打开输入图片
file, err := os.Open("input.jpg")
if err != nil {
log.Fatal(err)
}
defer file.Close()
img, _, err := image.Decode(file)
if err != nil {
log.Fatal(err)
}
bounds := img.Bounds()
result := image.NewRGBA(bounds)
// 遍历像素,将接近绿色的像素替换为红色
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
r, g, b, a := img.At(x, y).RGBA()
// 简单阈值判断:绿色分量明显高于红蓝
if g > r+5000 && g > b+5000 {
result.Set(x, y, color.RGBA{255, 0, 0, 255}) // 红色背景
} else {
result.Set(x, y, color.RGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)})
}
}
}
outFile, err := os.Create("output.jpg")
if err != nil {
log.Fatal(err)
}
defer outFile.Close()
jpeg.Encode(outFile, result, &jpeg.Options{Quality: 95})
}复制 const sharp = require('sharp');
async function changeBackground() {
// 读取图像并获取像素数据
const image = sharp('input.jpg');
const { data, info } = await image.raw().toBuffer({ resolveWithObject: true });
const pixels = new Uint8Array(data);
const threshold = 100; // 绿色检测阈值
// 遍历每个像素(RGBA 格式)
for (let i = 0; i < pixels.length; i += 4) {
const r = pixels[i];
const g = pixels[i + 1];
const b = pixels[i + 2];
// 检测绿色背景并替换为红色
if (g > r + threshold && g > b + threshold) {
pixels[i] = 255; // R
pixels[i + 1] = 0; // G
pixels[i + 2] = 0; // B
}
}
// 保存结果
await sharp(pixels, { raw: { width: info.width, height: info.height, channels: 4 } })
.jpeg()
.toFile('output.jpg');
}
changeBackground().catch(console.error);