运用AI技术,实现智能识别,一键抠图,满足您在日常生活中的抠图需求,无需下载PS,也可快速实现图片背景切换。基于深度学习模型,通过对大量图像数据的学习与优化,深度学习模型能够识别图片中的主体与背景,实现精准抠图。这种方法相较传统手工抠图,不仅效率高,而且能处理复杂场景下的抠图需求,显著提高抠图质量与用户体验。通过持续学习与优化,提升AI模型的精确度与泛化能力,持续优化抠图的效果。
遇到bug或者使用上的问题,记得评论区留言!
此工具需要电脑有一定的配置,可在局域网下运行,电脑运行python文件,此局域网下所有设备均可打开网页。显存至少6个G!
可前往:https://huggingface.co/spaces/SJY-HIM/my-rembg-tool 进行在线体验。(huggingface为国外网站,需要挂梯子才能访问,建议本地部署!)
首先安装所需库
pip install rembg flask flask-cors pillow
pip install onnxruntime🤔请确保python文件和index.html在同一文件夹。首次运行需要下载一个约200MB的模型文件,耐心等待!
from rembg import remove, new_session
from flask import Flask, request, send_file
from flask_cors import CORS
from PIL import Image
import io
app = Flask(__name__)
CORS(app)
# 预加载高精度模型
print("正在加载 AI 模型...")
model_name = "isnet-general-use"
session = new_session(model_name)
print("模型加载完成!")
@app.route('/')
def index():
return send_file('index.html')
@app.route('/remove-bg', methods=['POST'])
def remove_background():
if 'image' not in request.files:
return '没有上传图片', 400
file = request.files['image']
if file.filename == '':
return '文件名为空', 400
# 获取前端传来的模式参数,默认为 'general'
mode = request.form.get('mode', 'general')
print(f"收到请求 -> 模式: {mode} | 文件: {file.filename}")
try:
input_image = Image.open(file.stream)
input_image = input_image.convert('RGB') # 强制转RGB防止报错
#根据模式动态调整参数
if mode == 'hair':
# 模式2:精细发丝 (开启 Alpha Matting)
output_image = remove(
input_image,
session=session,
alpha_matting=True,
alpha_matting_foreground_threshold=240,
alpha_matting_background_threshold=10,
alpha_matting_erode_size=10
)
elif mode == 'aggressive':
# 模式3:强力去底 (更大的腐蚀力度,适合难搞的背景)
output_image = remove(
input_image,
session=session,
alpha_matting=True,
alpha_matting_foreground_threshold=250,
alpha_matting_background_threshold=10,
alpha_matting_erode_size=15 # 腐蚀更多边缘
)
else:
output_image = remove(input_image, session=session)
img_io = io.BytesIO()
output_image.save(img_io, 'PNG')
img_io.seek(0)
return send_file(img_io, mimetype='image/png')
except Exception as e:
print(f"Error occurred: {e}")
return str(e), 500
if __name__ == '__main__':
app.run(debug=True, port=5000, host='0.0.0.0')以下为html文件。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI 多模式智能抠图</title>
<link href="https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.css" rel="stylesheet">
<style>
:root {
--glass-bg: rgba(255, 255, 255, 0.15);
--glass-border: 1px solid rgba(255, 255, 255, 0.3);
--glass-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
--text-color: #ffffff;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(45deg, #2575fc 0%, #6a11cb 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
color: var(--text-color);
position: relative;
overflow-x: hidden;
}
/* 动态背景 */
.blob {
position: absolute;
border-radius: 50%;
filter: blur(80px);
z-index: -1;
opacity: 0.8;
animation: move 10s infinite alternate;
}
.blob:nth-child(1) { top: -10%; left: -10%; width: 500px; height: 500px; background: #ff416c; }
.blob:nth-child(2) { bottom: -10%; right: -10%; width: 400px; height: 400px; background: #2575fc; }
@keyframes move { from { transform: translate(0, 0); } to { transform: translate(30px, -30px); } }
.main-card {
background: var(--glass-bg);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: var(--glass-border);
box-shadow: var(--glass-shadow);
border-radius: 24px;
padding: 40px;
width: 90%;
max-width: 900px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
h1 { font-size: 2.2rem; margin-bottom: 10px; font-weight: 700; }
p.subtitle { margin-bottom: 25px; opacity: 0.9; font-size: 1rem; }
.upload-area {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
max-width: 600px;
height: 160px;
background: rgba(255, 255, 255, 0.1);
border: 2px dashed rgba(255, 255, 255, 0.5);
border-radius: 16px;
cursor: pointer;
transition: all 0.3s ease;
margin-bottom: 20px;
}
.upload-area:hover { background: rgba(255, 255, 255, 0.2); border-color: #fff; }
.upload-area i { font-size: 2.5rem; margin-bottom: 10px; color: rgba(255,255,255,0.9); }
#uploadInput { display: none; }
.mode-select-container {
margin-bottom: 20px;
position: relative;
width: 100%;
max-width: 300px;
}
select {
width: 100%;
padding: 12px 20px;
font-size: 1rem;
border-radius: 50px;
border: 1px solid rgba(255, 255, 255, 0.4);
background: rgba(0, 0, 0, 0.2); /* 半透明黑底,保证白色文字可见 */
color: white;
outline: none;
appearance: none; /* 去掉默认箭头 */
cursor: pointer;
text-align: center;
font-family: inherit;
}
select:hover { background: rgba(0, 0, 0, 0.3); }
/* 自定义下拉箭头图标 */
.mode-select-container::after {
content: '▼';
font-size: 0.8rem;
position: absolute;
right: 20px;
top: 50%;
transform: translateY(-50%);
pointer-events: none;
color: rgba(255,255,255,0.7);
}
option { background-color: #333; color: white; }
.action-btn {
padding: 12px 50px;
background: linear-gradient(90deg, #ff416c, #ff4b2b);
color: white;
border: none;
border-radius: 50px;
font-size: 1.1rem;
font-weight: bold;
cursor: pointer;
box-shadow: 0 4px 15px rgba(255, 75, 43, 0.4);
transition: transform 0.2s;
}
.action-btn:hover { transform: translateY(-2px); }
.action-btn:disabled { background: #ccc; cursor: not-allowed; box-shadow: none; }
.preview-container {
display: none;
width: 100%;
margin-top: 40px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
display: none;
}
.image-card {
background: rgba(255, 255, 255, 0.1);
border-radius: 16px;
padding: 15px;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.image-card h3 { margin-bottom: 15px; font-size: 1rem; opacity: 0.9; }
.checkerboard {
background-image: linear-gradient(45deg, #ccc 25%, transparent 25%),
linear-gradient(-45deg, #ccc 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, #ccc 75%),
linear-gradient(-45deg, transparent 75%, #ccc 75%);
background-size: 20px 20px;
background-color: #fff;
border-radius: 12px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
min-height: 200px;
}
img { max-width: 100%; max-height: 400px; display: block; image-rendering: -webkit-optimize-contrast; object-fit: contain;}
.loader-wrapper { display: none; margin: 20px 0; text-align: center; }
.spinner {
width: 40px; height: 40px;
border: 4px solid rgba(255,255,255,0.3); border-top: 4px solid #fff;
border-radius: 50%; animation: spin 1s linear infinite; margin: 0 auto 10px auto;
}
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
.download-link {
display: inline-flex; align-items: center; gap: 5px; margin-top: 15px;
color: #fff; text-decoration: none; font-size: 0.9rem;
background: rgba(0,0,0,0.2); padding: 8px 20px; border-radius: 20px;
}
@media (max-width: 768px) {
.preview-container { grid-template-columns: 1fr; }
.main-card { padding: 20px; width: 95%; }
}
</style>
</head>
<body>
<div class="blob"></div>
<div class="blob"></div>
<div class="main-card">
<h1><i class="ri-magic-line"></i> AI 智能抠图</h1>
<p class="subtitle">选择模式,精准去除背景</p>
<label for="uploadInput" class="upload-area" id="dropZone">
<i class="ri-upload-cloud-2-line"></i>
<span id="fileName">点击或拖拽图片到这里上传</span>
</label>
<input type="file" id="uploadInput" accept="image/*">
<div class="mode-select-container">
<select id="modeSelect">
<option value="general">🚀 通用模式 (Logo/商品/硬边)</option>
<option value="hair">🦁 精细模式 (头发/毛绒/婚纱)</option>
<option value="aggressive">🛡️ 强力去底 (复杂杂乱背景)</option>
</select>
</div>
<button onclick="processImage()" id="btnProcess" class="action-btn">开始抠图</button>
<div class="loader-wrapper" id="loader">
<div class="spinner"></div>
<p>正在进行 AI 推理...</p>
</div>
<div class="preview-container" id="previewContainer">
<div class="image-card">
<h3>原始图片</h3>
<div class="checkerboard">
<img id="originalImg" alt="原始图片">
</div>
</div>
<div class="image-card">
<h3>处理结果</h3>
<div class="checkerboard">
<img id="resultImg" alt="抠图结果">
</div>
<div id="downloadArea"></div>
</div>
</div>
</div>
<script>
const input = document.getElementById('uploadInput');
const fileNameDisplay = document.getElementById('fileName');
const originalImg = document.getElementById('originalImg');
const resultImg = document.getElementById('resultImg');
const previewContainer = document.getElementById('previewContainer');
const loader = document.getElementById('loader');
const btn = document.getElementById('btnProcess');
const downloadArea = document.getElementById('downloadArea');
const modeSelect = document.getElementById('modeSelect');
input.addEventListener('change', function(e) {
const file = e.target.files[0];
if (file) {
fileNameDisplay.innerText = "已选择: " + file.name;
const reader = new FileReader();
reader.onload = function(e) {
originalImg.src = e.target.result;
previewContainer.style.display = 'grid';
resultImg.style.display = 'none';
downloadArea.innerHTML = '';
}
reader.readAsDataURL(file);
}
});
async function processImage() {
if (!input.files[0]) {
alert("请先选择一张图片!");
return;
}
loader.style.display = 'block';
btn.disabled = true;
btn.innerText = "处理中...";
resultImg.style.display = 'none';
const formData = new FormData();
formData.append('image', input.files[0]);
//把用户选择的模式传给后端
formData.append('mode', modeSelect.value);
// ===================================
try {
// 使用相对路径,自动适配手机/电脑
const response = await fetch('/remove-bg', {
method: 'POST',
body: formData
});
if (!response.ok) {
throw new Error("HTTP 状态码异常: " + response.status);
}
const blob = await response.blob();
const imgUrl = URL.createObjectURL(blob);
resultImg.src = imgUrl;
resultImg.style.display = 'block';
downloadArea.innerHTML = `
<a href="${imgUrl}" download="rembg_result.png" class="download-link">
<i class="ri-download-line"></i> 下载透明背景图
</a>
`;
} catch (error) {
console.error(error);
alert("错误详情: " + error.message);
} finally {
loader.style.display = 'none';
btn.disabled = false;
btn.innerText = "开始抠图";
}
}
</script>
</body>
</html>操作步骤:运行python文件,打开返回的网址信息,需要先开电脑防火墙端口。抠图速度与电脑配置有关。