部署RemBG真是太要命了

简介

RemoveBG超级好用,能够很方便地移除照片的背景,方便制作证件照、临时抠图啥的
(是个python库,git:GitHub - danielgatis/rembg: Rembg is a tool to remove images background

效果

注意,我没有使用针对动漫的专用模型而是偷懒直接用了人像的模型,人像照片效果很好,只是不好放出来图


但是

但是,一个极其重要的问题,部署太要命了……直接在命令行 pip install rembg[cli] 大概率会出事,不是模块版本与py版本不对应,就是ffmpy部署时出错,提示“找不到ffmpy”……

部署完了以后一看,好家伙,1个G了已经

此时,如果你直接用,它还会自动试图下载“u2net.onnx”模型,这玩意走github下载,156M,要人小命。

要是想避开这个坑,要么手动改rembg库的原始文件调用方法,要么自己下载一个"u2netp.onnx"(轻量版,仅4M),然后手动放到“C:\users\ username \.u2net\”的目录下让程序自己识别

更关键的是,程序的readme里面默认调用完全体“u2net.onnx”并且没提供用于修改默认调用模型的参数!!!

不仅如此,善于折腾的我还想到了一个巧妙的方法:我用python embedded直接做个绿色程序,u盘一拷,想去哪里用就去哪里用不香嘛,然后不出意外的出意外了……

cmd调用显示一团乱码,最后说python调用失败,这大概是模块的原因而不是python的原因,然后我重新安装了一次模块,错误消失了……就离谱,完全不明白消失的原理是啥……

现在又发挥自己的传统艺能,用aardio写了个GUI出来,把上面的步骤都塞进去了,理论上大抵可以做到拷到哪里都能用?

随手放个坚果云分享链接吧,想要的自取就是,过期不补
分享:https://www.jianguoyun.com/p/Deb3e7sQia2lCxjt968FIAA

aardio源码如下,懒得传github了,在哪里开源不是开源啊
(还是用之前那个rimage_gui的框架修修补补出来的玩意)

总结
import fsys.dlg
import process
import win.ui
import win.ui.tooltip
/*DSG{{*/
mainForm = win.form(cls="RIMG_GUI_FORM";text="rimage_gui";right=587;bottom=396;border="thin";max=false)
mainForm.add(
auto_delete={cls="checkbox";text="删除原件 DelOriginal";left=254;top=310;right=438;bottom=335;bgcolor=65535;color=255;font=LOGFONT(h=-16;name='微软雅黑');z=11};
edit_o_d={cls="edit";left=154;top=356;right=567;bottom=381;autovscroll=false;edge=1;font=LOGFONT(h=-14;name='微软雅黑');multiline=1;readonly=1;z=6};
edit_s={cls="edit";text="_updated";left=467;top=218;right=557;bottom=243;align="center";edge=1;font=LOGFONT(h=-16;name='微软雅黑');z=8};
file_list={cls="listbox";left=7;top=31;right=442;bottom=295;acceptfiles=1;edge=1;font=LOGFONT(h=-14;name='微软雅黑');hscroll=1;items={};vscroll=1;z=9};
out_format={cls="combobox";left=467;top=97;right=554;bottom=123;edge=1;font=LOGFONT(h=-16;name='微软雅黑');items={"jpg";"png";"jxl";"webp";"avif"};mode="dropdown";z=5};
show_hide={cls="checkbox";text="隐藏执行 HiddenExecute";left=12;top=309;right=225;bottom=334;bgcolor=65535;checked=1;color=255;font=LOGFONT(h=-16;name='微软雅黑');z=10};
start_cov={cls="button";text="开始 Start";left=453;top=288;right=566;bottom=341;border=1;default=1;font=LOGFONT(h=-17;name='微软雅黑');z=3};
static_file_list={cls="static";text="文件列表 File list";left=7;top=4;right=141;bottom=29;align="center";center=1;font=LOGFONT(h=-16;name='微软雅黑');notify=1;transparent=1;z=2};
static_out_dir={cls="static";text="输出目录 Out-Dir:";left=6;top=356;right=154;bottom=381;align="center";center=1;font=LOGFONT(h=-16;name='微软雅黑');notify=1;transparent=1;z=1};
static_out_format={cls="static";text="输出格式
Out-Format";left=453;top=43;right=566;bottom=84;align="center";font=LOGFONT(h=-16;name='微软雅黑');notify=1;transparent=1;z=4};
static_suffix={cls="static";text="输出后缀
Suffix";left=473;top=167;right=551;bottom=209;align="center";font=LOGFONT(h=-16;name='微软雅黑');notify=1;transparent=1;z=7}
)
/*}}*/

model_path = io.getSpecial(0x28/*_CSIDL_PROFILE*/) + "\.u2net"
model_path = string.replace(model_path,"@\","\\")
if(!io.exist(model_path)){
	fsys.copy(io._exedir + ".u2net",model_path)
	process.executeWait(io._exedir + "\Scripts\pip.exe","uninstall rembg -q",,0/*_SW_HIDE*/)
	process.executeWait(io._exedir + "\Scripts\pip.exe","install" + string.replace(io._exedir,"@\","\\") + "rembg-2.0.53-py3-none-any.whl -q",,0/*_SW_HIDE*/)
}

mainForm.file_list.add("双击左键添加,选中后使用右键删除")
mainForm.file_list.add("双击下方的(清空Clear)以快速清空文件列表")
mainForm.file_list.add(" ")
mainForm.file_list.add("Double click left button of mouse to add pic(s).")
mainForm.file_list.add("Click right Button after select to del it.")
mainForm.file_list.add("Double click ""(清空Clear)"" on the following to clear file list.")

mainForm.edit_o_d.wndproc = function(hwnd,message,wParam,lParam){
	select(message){
		case 0x203/*_WM_LBUTTONDBLCLK*/{
			temp = fsys.dlg.openDir(,mainForm.hwnd,"请选择目录 Please select the Dir for output")
			if(temp != null){
				mainForm.edit_o_d.text = temp + "\"
			}else{
				win.msgbox('请选择正确的目录\nPlease select right dir to save.',"Warning",,mainForm.hwnd,2000)
			}
		}
	}
}
mainForm.edit_o_d.text = io._exedir

var count = null
mainForm.onDropFiles = function(files){
	if(count == null){
		mainForm.file_list.clear()
		count = 0
	}
	var temp_list = {
		".png";
		".jpg";
		".jpeg";
	}
	if(!fsys.isDir(files[1])){
		for(k,v in files){
			temp_ext = io.splitpath(v).ext
			for m,n in temp_list{
				if(n == temp_ext){
					mainForm.file_list.add(v)
					mainForm.edit_o_d.text = io.splitpath(mainForm.file_list.getItemText(1)).dir + "\"
				}
			}
		}
	}else{win.msgbox('请勿使用文件夹\nDir is not supported.',"Warning",,mainForm.hwnd,2000)}
}
mainForm.file_list.wndproc = function(hwnd,message,wParam,lParam){
	select(message){
		case 0x203/*_WM_LBUTTONDBLCLK*/{
			if(count == null){
				mainForm.file_list.clear()
				count = 0
			}
			var temp1,temp2 = fsys.dlg.openEx("图片 Picture|*.png;*.jpg;*.jpeg","选择图片 Select IMGs",,mainForm.hwnd)
			if(temp1 != null){
				for(i,j in temp1){mainForm.file_list.add(j,1)}
				mainForm.edit_o_d.text = string.left(io.splitpath(mainForm.file_list.getItemText(1)).dir,-2,true) + "\"
			}else{
				win.msgbox('请选择正确的图片\nPlease select Pics we support.',"Warning",,mainForm.hwnd,2000)
			}
			fsys.setCurDir(io._exedir)
		}
		case 0x204/*_WM_RBUTTONDOWN*/{
			mainForm.file_list.delete()
		}
	}
}

mainForm.start_cov.oncommand = function(id,event){
	if(count != 0){
		win.msgbox('请选择正确的图片\nPlease select Pics we support before execute.',"Warning",,mainForm.hwnd,2000)
	}else{
		mainForm.file_list.disabled = true
		if(mainForm.out_format.selText == "png"){
			format = ".png"
		}else{
			format = ".jpg"
		}
		if(mainForm.auto_delete.checked == true){auto_del = true}else{auto_del = false}
		if((mainForm.edit_s.text != "") and (mainForm.edit_s.text != null)){
			suf_text = mainForm.edit_s.text
		}else {
			suf_text = ""
		}
		
		out_dir = mainForm.edit_o_d.text
		
		for(count=1;mainForm.file_list.count;1){
			temp_file = mainForm.file_list.getItemText(1)
			argvs = "i """ + temp_file + """"
			out_path = out_dir + io.splitpath(temp_file).name + suf_text
			if(io.exist(out_path + format)){
				out_path = out_path + "_update"
			}
			out_path = out_path + format
			out_path = " """ + out_path + """"
			argvs = argvs + out_path + " -m u2netp"
			argvs = string.replace(argvs,"@\","\\")
			
			rembg_path = io._exedir + "Scripts\rembg.exe"
			if(mainForm.show_hide.checked){
				process.executeWait(rembg_path,argvs,,0/*_SW_HIDE*/)
			}else{
				process.executeWait(rembg_path,argvs)
			}
			if(auto_del){
				io.remove(temp_file)
			}
			mainForm.file_list.delete(1)
		}
		mainForm.file_list.disabled = false
		win.setForeground(mainForm.hwnd)
		win.msgbox("转换完毕!Complete!","成功Success",,mainForm.hwnd,10000)
	}
}

mainForm.show()
return win.loopMessage()

去看了下库,已经被删了

没删,我的问题,后面的括号被含在了超链接里面……

试了一下,效果还不错,扣人像还是 u2net_human_seg 效果更好一点。

官方提供了docker镜像,可以起个网络服务器了,不过镜像大小也是有点难绷:joy:

python应用经常遇到这种部署异常问题,
所以一直怀念单exe、绿色便携软件的模式。

docker好像是能解决这类问题,但win没有(10之后的内置linux才有),而且镜像可能很大

问题不是太大,通用模型干啥都能将就将就,人像模型就只能人像了

难道只有我下了以后添加图片后不输出图片?

自行到根目录里面

  1. 复制根目录的 .u2net 文件夹到users目录
  2. 在根目录 Scripts 文件夹里开cmd,pip.exe uninstall rembg -q
  3. pip.exe install 根目录路径下的 “rembg-2.0.53-py3-none-any.whl” -q

应该就可以解决了