Python AI之BackgroundRemover

慈云数据 8个月前 (03-12) 技术支持 99 0

BackgroundRemover  简介

基于AI,使用简单指令完成图片/视频文件移除背景。

官方代码及其资料文档:https://github.com/nadermx/backgroundremover

Windows 11 安装BackgroundRemover 

个人认为BackgroundRemover官网提供的安装手册不适合新手安装,我这边将一步步讲述我是如何搭建Python Conda虚拟环境来运行BackgroundRemover 项目。在此文当中还会穿插一些Python基础知识讲解、Python 开源项目和Python 敏捷开发的知识点。

第一个拓展知识点 :Anaconda

我个人的理解就是两点:第一点:  Python 构建虚拟环境。

                                        第二点:  Python 包管理。

Windows 如何安装Anaconda

BackgroundRemover 源码下载

打开Git 命令窗口,右击选择->Open Git Base Here

执行如下指令,下载BackgroundRemover 源码。

git clone https://github.com/nadermx/backgroundremover.git

构建BackgroundRemover运行虚拟环境(pytorch),并安装项目依赖

创建pytorch 虚拟环境执行如下指令:

-- 创建pyotrch 虚拟环境,并指定Python版本
conda create -n pytorch python=3.10
-- 激活pytorch 环境
activate pytorch

安装项目依赖并创建虚拟环境 通常是执行如下指令:

conda env create -f environment.yml

指令含义:命令会读取环境文件(environment.yml),并根据其中的清单信息创建一个新的Conda环境。

第二知识点拓展:conda 指定虚拟环境创建文件,并下载项目依赖。

我这里提供一个通用标准虚拟环境创建文件。

name: animatediff  # 虚拟环境名称
channels:
  - pytorch
  - nvidia
dependencies:      # 虚拟环境基础包
  - python=3.10
  - pytorch=1.13.1
  - torchvision=0.14.1
  - torchaudio=0.13.1
  - pytorch-cuda=11.7
  - pip
  - pip:          # 项目依赖包
    - diffusers==0.11.1
    - transformers==4.25.1
    - xformers==0.0.16
    - imageio==2.27.0
    - decord==0.6.0
    - gdown
    - einops
    - omegaconf
    - safetensors
    - gradio
    - wandb

温馨提示:BackgroundRemover 暂时未提供该资源文件。

依据BackgroundRemover 官方文档和项目依赖要求安装虚拟环境基础包和项目依赖包。

第一步:安装BackgroundRemover 官方文档要求安装基础包

python >= 3.6
python3.6-dev #or what ever version of python you use
torch and torchvision stable version (https://pytorch.org)
ffmpeg 4.4+
To clarify, you must install both python and whatever dev version of python you installed. IE; python3.10-dev with python3.10 or python3.8-dev with python3.8

大致含义:

1、Python 版本大于等于3.6

2、python3.6-dev 主要用于Linux系统环境声明Python 3.6开发所需的相关依赖库和头文件,而我的安装环境为Windows 可以暂时不考虑。

3、安装torch

4、安装Ffmpeg 4.4+

5、请确认下载python.*  对应的python*-dev 版本。

安装torch

打开pytorch 官网:https://pytorch.org/

拷贝运行指令在虚拟环境pytorch 中执行: 

pip3 install torch torchvision torchaudio

第三知识点拓展:conda 默认的镜像源为国外,需要添加国内镜像源,我这里添加的为清华镜像源。

问题产生:在pytorch 虚拟环境安装torch 安装进行缓慢。

解决办法:conda 默认镜像源的IP地址在国外,需要添加国内镜像源解决。

请执行如下步骤:

一、查看conda 默认镜像源:

conda config --show

 重点查看:channels属性值,默认值为:default

二、为conda 添加国内镜像源:

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch
conda config --add channels  https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
conda config --add channels  https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free
conda config --add channels  https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
conda config --add channels  https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/pro
conda config --add channels  https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2

执行conda clean -i清理一下缓存,国内镜像源添加完毕。

设置搜索时显示通道地址 

conda config --set show_channel_urls yes

第四知识点拓展:conda 常用命令总结

1、查看已安装的包:conda list
2、显示所有的虚拟环境:conda info -e (或conda env list)
3、创建新的虚拟环境:conda create -n env_name python=python_version
4、删除虚拟环境:conda remove -n env_name --all
5、激活虚拟环境:conda activate env_name
6、退出虚拟环境:conda deactivate
7、复制虚拟环境:conda create -n env_name –clone clone_env_name
9、删除虚拟环境:conda remove -n env_name –all
10、安装模块包:
在某个虚拟环境下直接安装包:conda install package_name
安装包到指定虚拟环境中去:conda install -n env_name package_name
11、移除(卸载uninstall)模块包:
在某个虚拟环境下移除该环境的包:conda remove package_name
移除指定虚拟环境中的包:conda remove -n env_name package_name
注意: 如果是通过pip安装的包,移除时也请使用 pip uninstall package_name 命令移除,如果使用 conda remove 可能会发生异常,导致conda不可用
12、更新:
conda更新:conda update conda
anaconda更新:conda update anaconda
更新某个包:conda update package_name
更新所有包:conda update --all
更新python至最新版本:conda update python
13、搜索某个包信息:conda search package_name
14、conda瘦身:
conda clean -p //删除没有用的包
conda clean -t //tar打包,将conda保存下来的tar包

第二步:运行BackgroundRemover 程序入口,安装项目依赖包

问题一:BackgroundRemover 提示ModuleNotFoundError: No module named 'pymatting'

解决过程:在conda 检索pymatting 模块 提示没有找到。

                  执行命令为:conda search pymatting

在 阿里镜像源 Simple Index中找到了pymatting 模块。

安装pymatting 模块的两种方式:

第一种:在线安装并指定镜像源通道

pip install -i  http://mirrors.aliyun.com/pypi/simple/ pymatting

建议操作:将阿里云镜像添加至pytorch 虚拟环境上面的指令可以省略指定镜像源通道。

第二种:离线安装

前提条件是需要下载pymattinng*.whl 安装包

再执行如下指令:

pip install E:\\whl\\PyMatting-1.1.8-py3-none-any.whl

问题二:BackgroundRemover 提示ModuleNotFoundError: No module named 'moviepy'

解决过程:在conda 检索moviepy模块,提示没有找到。同时国内各个镜像源中也没有检索到moviepy 模块

                  执行命令为:conda search pymatting

解决办法:下载moviepy 源码本地进行编译安装和打包为whl 文件。 

第一种方式:本地编译安装

1.moviepy 源码地址:https://github.com/Zulko/moviepy

2.切换至moviepy 源码的setup.py 所在目录,执行如下命令,moviepy 模块会安装在指定解释器

python setup.py install 

第二种:打包whl 再编译安装

切换至moviepy 源码的setup.py 所在目录,执行如下命令,moviepy 模块会打包成whl文件

python setup.py bdist_wheel

pip 安装whl 文件

pip install moviepy-*-*-*-any.whl

第五知识点拓展:Python 项目实现源码安装或打包成*.whl 文件。

前置条件:安装setuptools,wheel模块

功能演示:

helloworld

        --init.py

        --代码1

        --代码2

setup.py

编辑__init__.py

from helloworld import 代码1,代码2

在helloworld同级下新建setup.py

from setuptools import setup,find_packages
setup(name='helloworld',
      version='0.0.1',
      description='helloworld!',
      author='hello',
      author_email='helloworld@outlook.com',
      requires=['flask'], # 定义依赖哪些模块
      packages=find_packages(), # 系统自动从当前目录开始找包
      # 如果有的包不用打包,则只能指定需要打包的文件
      #packages=['代码1','代码2','__init__']  #指定目录中需要打包的py文件,注意不要.py后缀
      license='apache 3.0')
'''
name : 打包后包的文件名
version : 版本号
author : 作者
author_email : 作者的邮箱
py_modules : 要打包的.py文件
packages: 打包的python文件夹
include_package_data : 项目里会有一些非py文件,比如html和js等,这时候就要靠include_package_data 和 package_data 来指定了。package_data:一般写成{‘your_package_name’: [“files”]}, include_package_data还没完,还需要修改MANIFEST.in文件.MANIFEST.in文件的语法为: include xxx/xxx/xxx/.ini/(所有以.ini结尾的文件,也可以直接指定文件名)
license : 支持的开源协议
description : 对项目简短的一个形容
ext_modules : 是一个包含Extension实例的列表,Extension的定义也有一些参数。
ext_package : 定义extension的相对路径
requires : 定义依赖哪些模块
provides : 定义可以为哪些模块提供依赖
data_files :指定其他的一些文件(如配置文件),规定了哪些文件被安装到哪些目录中。如果目录名是相对路径,则是相对于sys.prefix或sys.exec_prefix的路径。如果没有提供模板,会被添加到MANIFEST文件中。
'''

方式一 

在程序根目录运行打包成whl文件,打包文件:helloworld-0.0.1-py3-none-any.whl 

python setup.py bdist_wheel

pip安装whl文件:将whl复制到程序目录,进入存放whl目录运行。

pip install helloworld-0.0.1-py3-none-any.whl

方式二

pip打包成压缩文件 

python setup.py sdist

安装压缩文件

解压压缩的文件进入setup.py所在目录,运行

python setup.py install

 问题三: 启动BackgroundRemover 提示:AttributeError: module 'cmd' has no attribute 'Cmd'

造成原因:BackgroundRemover 存在Cmd 模块与pytorch 模块中cmd 模块冲突。

解决办法:将BackgroundRemover 项目中cmd 模块重名为wincmd

问题四: 启动BackgroundRemover 提示:ModuleNotFoundError: No module named 'skimage'

快速解决,执行如下命令:pip  install skimage

命令控制台输出如下错误信息:

(pytorch) E:\whl\moviepy-0.2.2.09\moviepy-0.2.2.09>pip install skimage
Collecting skimage
  Downloading skimage-0.0.tar.gz (757 bytes)
  Preparing metadata (setup.py) ... error
  error: subprocess-exited-with-error
  × python setup.py egg_info did not run successfully.
  │ exit code: 1
  ╰─> [3 lines of output]
      *** Please install the `scikit-image` package (instead of `skimage`) ***
      [end of output]
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed
× Encountered error while generating package metadata.
╰─> See above for output.
note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

大致意思是:下载skimage 模块异常,正常的模块名称为:scikit-image

结论:Python 模块与项目名称存在不一致的情况。

问题六: 启动BackgroundRemover 提示:No module named 'pymatting ”

大家可能存在疑惑,问题一和问题六不是提示的相关错误信息,为什么还需要再重复一遍。

两者的问题差异在于:问题一,虚拟环境pytorch 中没有存在pymatting 中的模块。

                                    问题六,虚拟环境pytorch 中已经存在pymatting 中的模块。

造成问题原因:虚拟环境pytorch 的Library\bin 和Scripts 目录地址没有同步更新到计算机Path 全局变量,导致pymatting 模块没有找到。

将虚拟环境pytorch 的Library\bin 和Scripts 目录添加至全局环境变量中。

D:\anaconda3\envs\pytorch\Scripts
D:\anaconda3\envs\pytorch\Library\bin

第三步: 代码修改

问题一:Python 模块循环调用

在运行BackgroundRemover 项目时,提示"most likely due to a circular import" 这样的报错

原因:循环引用问题,即A引用了B,B又引用了A,造成循环引用的问题。

在BackgroundRemover 项目中的具体表现为:utilities.py 模块引用bg.py 模块,同时bg.py 模块引用utilities.py 模块等等。

解决办法:

1)延迟导入:即将 from xxx import yyy 放到函数或类的内部,从而使其作用域变成局部的。但是这样可能会对性能有些影响。 (我选择了此种方案)

修改utilities.py 文件

第一步:移除声明导入

from .bg import DEVICE, Net, iter_frames, remove_many

第二步:在需要使用bg模块函数进行声明引用

2)直接导入模块名,通过模块调用其中的函数 

将 from xxx import yyy 转换成 import xxx;  在调用函数时修改 xxx.yyy 的形式 。

 3)重新设计代码结构,将代码和并或者分离 

方法1)和2)以上两种方式都是治标不治本的,只能说能够用,但是并不符合规范。

最好的办法应该是从代码布局入手,比如合并或分离循环引用的部分,合并就是将代码放到一个文件里面,自然就不用循环引用了,分离的话就是将循环引用的部分放到第三个py文件中,这样也可以。

问题二:Python 模块绝对路径和相对路径导致导致相关模块或模块函数无法正常加载

BackgroundRemover 代码片段:

BackgroundRemover.bg.py

 

自己添加功能代码片段如下: 

温馨提示: 指定项目资源加载路径地址添加了本文件所在目录

BackgroundRemover.u2net.detect.py

 

  

 自己添加功能代码片段如下: 

 温馨提示: 指定项目资源加载路径地址添加了本文件所在目录

第四步:模型文件下载

BackgroundRemover 执行前三步,还是提示如下错误信息:

(pytorch) E:\python_ai\stable-diffusion>backgroundremover -i "E:\python_ai\backgroundremover\examplefiles\1.png" -o "E:\python_ai\backgroundremover\examplefiles\output.png"
E:\python_ai\backgroundremover\examplefiles\output.png
Traceback (most recent call last):
  File "D:\anaconda3\envs\pytorch\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "D:\anaconda3\envs\pytorch\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "D:\anaconda3\envs\pytorch\Scripts\backgroundremover.exe\__main__.py", line 7, in 
  File "D:\anaconda3\envs\pytorch\lib\site-packages\backgroundremover\cmd\cli.py", line 239, in main
    remove(
  File "D:\anaconda3\envs\pytorch\lib\site-packages\backgroundremover\bg.py", line 183, in remove
    model = get_model(model_name)
  File "D:\anaconda3\envs\pytorch\lib\site-packages\backgroundremover\bg.py", line 171, in get_model
    return detect.load_model(model_name="u2net")
  File "D:\anaconda3\envs\pytorch\lib\site-packages\backgroundremover\u2net\detect.py", line 82, in load_model
    torch.load(
  File "D:\anaconda3\envs\pytorch\lib\site-packages\torch\serialization.py", line 1040, in load
    return _legacy_load(opened_file, map_location, pickle_module, **pickle_load_args)
  File "D:\anaconda3\envs\pytorch\lib\site-packages\torch\serialization.py", line 1258, in _legacy_load
    magic_number = pickle_module.load(f, **pickle_load_args)
EOFError: Ran out of input

造成此类 问题的原因是:BackgroundRemover 加载本地C:\Users\zzg\.u2net\u2net.pth 模型文件为空导致的报错。

解决办法:下载u2net.pth 模型文件并拷贝至C:\Users\zzg\.u2net 文件目录下。

下载u2net模型 

git 官网地址:https://github.com/xuebinqin/U-2-Net/blob/master/README.md

​百度网盘的地址:
https://pan.baidu.com/share/init?surl=WjwyEwDiaUjBbx_QxcXBwQ
提取码:pf9k

 温馨提示:具体的存放目录地址,用户需要在BackgroundRemover.u2net.detect.py 文件添加打印输出path 路径地址

吐槽一下:BackgroundRemover 的作者仅仅提供了虚拟环境的基础包,但是没有把BackgroundRemover 项目依赖的模块没有提供,我们只能从requirements.txt 文本获取。这里展示BackgroundRemover 项目的requirements.txt

certifi>=2021.5.30
charset-normalizer>=2.0.4
filelock>=3.0.12
idna>=3.2
PySocks>=1.7.1
six>=1.16.0
urllib3>=1.26.6
numpy>=1.19.4
scikit-image>=0.17.2
torch>=1.7.0
torchvision>=0.8.1
waitress>=1.4.4
tqdm>=4.51.0
requests>=2.24.0
scipy>=1.5.4
pymatting>=1.1.1
filetype>=1.0.7
hsh>=1.1.0
more_itertools>=8.7.0
moviepy~=0.2.2.9
Pillow~=10.2.0
ffmpeg-python
pip~=23.3.1
zlib~=1.2.13
wheel~=0.41.2
openssl~=3.0.13
typing_extensions~=4.9.0
setuptools~=68.2.2
ffmpeg~=1.4

BackgroundRemover  功能验证

前提条件:如果BackgroundRemover  python指令能够正常执行。

python.exe -m backgroundremover.wincmd.cli -i "video.mp4" -mk -o "output.mov"

我们就可以将BackgroundRemover  安装到虚拟环境pytorch 环境中,执行相关指令为

pip install backgroundremover

查看pip 已经安装模块

由于我仅仅下载u2net 模型,我这里也仅仅只展示图片移除背景相关功能。其他功能请参考官方文档。

(pytorch) E:\python_ai\stable-diffusion>backgroundremover -i "E:\python_ai\backgroundremover\examplefiles\1.png" -o "E:\python_ai\backgroundremover\examplefiles\output.png"
E:\python_ai\backgroundremover\examplefiles\output.png
(pytorch) E:\python_ai\stable-diffusion>backgroundremover -i "E:\python_ai\backgroundremover\examplefiles\rourou.jpg" -o "E:\python_ai\backgroundremover\examplefiles\rourou.png"
E:\python_ai\backgroundremover\examplefiles\rourou.png

 

 

微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon