deepfacelab中文网

 找回密码
 立即注册(仅限QQ邮箱)
12
返回列表 发新帖
楼主: day270010678

自动画遮罩功能

[复制链接]

44

主题

1063

帖子

6682

积分

高级丹圣

Rank: 13Rank: 13Rank: 13Rank: 13

积分
6682

万事如意节日勋章开心娱乐节日勋章

发表于 昨天 22:48 | 显示全部楼层
day270010678 发表于 2026-7-15 22:42
通过网盘分享的文件:
链接: https://pan.baidu.com/s/12lH1u11mEnDDYnV75_ZK5g?pwd=t8i8 提取码: t8i8  ...

下载你baidu盘的覆盖一样   我是直接cmd ,然后在dos窗口 pip装的   没有在df目录装  我试试进dfl里
回复 支持 反对

使用道具 举报

33

主题

223

帖子

1694

积分

初级丹圣

Rank: 8Rank: 8

积分
1694
 楼主| 发表于 昨天 22:56 | 显示全部楼层
pasanonic 发表于 2026-7-15 22:48
下载你baidu盘的覆盖一样   我是直接cmd ,然后在dos窗口 pip装的   没有在df目录装  我试试进dfl里 ...

是按照到你dfl的python环境里面,setenv.bat里面的python环境。不是你自己电脑的python
回复 支持 反对

使用道具 举报

44

主题

1063

帖子

6682

积分

高级丹圣

Rank: 13Rank: 13Rank: 13Rank: 13

积分
6682

万事如意节日勋章开心娱乐节日勋章

发表于 昨天 22:58 | 显示全部楼层
本帖最后由 pasanonic 于 2026-7-15 23:01 编辑
day270010678 发表于 2026-7-15 22:56
是按照到你dfl的python环境里面,setenv.bat里面的python环境。不是你自己电脑的python ...



大佬牛B  好了,自动画了  就是线条不太圆润,头部意外的有些多余,不过我要求不高,没那么追求精细
QQ20260715-225658.png


回复 支持 0 反对 1

使用道具 举报

33

主题

223

帖子

1694

积分

初级丹圣

Rank: 8Rank: 8

积分
1694
 楼主| 发表于 昨天 23:35 | 显示全部楼层
Usage in Python
Exhaustive list of labels can be extracted from config.json.

id        label        note
0        background       
1        skin       
2        nose       
3        eye_g        eyeglasses
4        l_eye        left eye
5        r_eye        right eye
6        l_brow        left eyebrow
7        r_brow        right eyebrow
8        l_ear        left ear
9        r_ear        right ear
10        mouth        area between lips
11        u_lip        upper lip
12        l_lip        lower lip
13        hair       
14        hat       
15        ear_r        earring
16        neck_l        necklace
17        neck       
18        cloth        clothing

这是模型的对应的位置,假如不要嘴巴区域标签,就修改下,把
    INCLUDE_LABELS = {1, 2, 4, 5, 6, 7, 10, 11, 12}
    EXCLUDE_LABELS = {3, 8, 9, 13, 14, 15, 16, 17, 18}  这EXCLUDE_LABELS 里面的10放到上面的标签里面就行了
回复 支持 反对

使用道具 举报

33

主题

223

帖子

1694

积分

初级丹圣

Rank: 8Rank: 8

积分
1694
 楼主| 发表于 5 小时前 | 显示全部楼层
pasanonic 发表于 2026-7-15 22:58
大佬牛B  好了,自动画了  就是线条不太圆润,头部意外的有些多余,不过我要求不高,没那么追求精细

线条不够圆润是因为我为了照顾内存小的电脑,如果要高圆滑的话,就修改下我源码
第一个量化模型 — 你用的是 model_quantized.onnx,量化会损失精度。model.onnx 更准确
第二,修改下采样,先放大 logits 再 argmax,而不是先 argmax 再放大
第三加入点高斯模糊
修改OcclusionDetector.py文件
第一个位置
  1.         self.model_path = model_path or str(
  2.             Path(__file__).parent / 'models' / 'model.onnx')
复制代码
这里模型修改下

第二个位置修改静态方法_logits_to_segmap
  1.     @staticmethod
  2.     def _logits_to_segmap(logits, h, w):
  3.         seg = logits[0].astype(np.float32)
  4.         seg_upscaled = np.zeros((seg.shape[0], h, w), dtype=np.float32)
  5.         for c in range(seg.shape[0]):
  6.             seg_upscaled[c] = cv2.resize(seg[c], (w, h), interpolation=cv2.INTER_LINEAR)
  7.         seg_map = np.argmax(seg_upscaled, axis=0).astype(np.uint8)
  8.         return seg_map
复制代码


第三个地方静态方法mask_to_polys


  1.     def mask_to_polys(mask, min_area=100, epsilon_factor=0.005):
  2.         blurred = cv2.GaussianBlur(mask, (7, 7), 0)
  3.         _, smoothed = cv2.threshold(blurred, 128, 255, cv2.THRESH_BINARY)
  4.         contours, _ = cv2.findContours(smoothed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_L1)
  5.         polys = []
  6.         for contour in contours:
  7.             if cv2.contourArea(contour) < min_area:
  8.                 continue
  9.             epsilon = epsilon_factor * cv2.arcLength(contour, True)
  10.             approx = cv2.approxPolyDP(contour, epsilon, True)
  11.             pts = approx.reshape(-1, 2).astype(np.float32)
  12.             if len(pts) >= 3:
  13.                 polys.append(pts)
  14.         return polys
复制代码
经过上面三处修改就会变成圆润的了,完整的文件代码是下面的
  1. import multiprocessing
  2. import numpy as np
  3. import cv2
  4. from pathlib import Path


  5. class OcclusionDetector:

  6.     CMD_LOAD = 1
  7.     CMD_DETECT = 2
  8.     CMD_SHUTDOWN = 3
  9.     RSP_LOADED = 10
  10.     RSP_RESULT = 11
  11.     RSP_ERROR = 12

  12.     INCLUDE_LABELS = {1, 2, 4, 5, 6, 7, 10, 11, 12}
  13.     EXCLUDE_LABELS = {3, 8, 9, 13, 14, 15, 16, 17, 18}
  14.     HEAD_LABELS = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}

  15.     MODEL_INPUT_SIZE = 512

  16.     def __init__(self, model_path=None):
  17.         self.model_path = model_path or str(
  18.             Path(__file__).parent / 'models' / 'model.onnx')
  19.         self._req_q = multiprocessing.Queue()
  20.         self._rsp_q = multiprocessing.Queue()
  21.         self._proc = None

  22.     def start(self):
  23.         if self._proc is not None and self._proc.is_alive():
  24.             return
  25.         self._proc = multiprocessing.Process(
  26.             target=self._subprocess_run,
  27.             args=(self._req_q, self._rsp_q, self.model_path),
  28.             daemon=True,
  29.         )
  30.         self._proc.start()
  31.         rsp = self._rsp_q.get(timeout=30)
  32.         if rsp[0] == self.RSP_ERROR:
  33.             raise RuntimeError(f"OcclusionDetector load failed: {rsp[1]}")

  34.     def detect(self, img, landmarks=None):
  35.         if self._proc is None or not self._proc.is_alive():
  36.             self.start()
  37.         self._req_q.put((self.CMD_DETECT, img))
  38.         rsp = self._rsp_q.get(timeout=60)
  39.         if rsp[0] == self.RSP_ERROR:
  40.             raise RuntimeError(f"OcclusionDetector detect failed: {rsp[1]}")
  41.         return rsp[1]

  42.     def shutdown(self):
  43.         if self._proc is not None and self._proc.is_alive():
  44.             self._req_q.put((self.CMD_SHUTDOWN,))
  45.             self._proc.join(timeout=5)
  46.             if self._proc.is_alive():
  47.                 self._proc.terminate()
  48.             self._proc = None

  49.     @staticmethod
  50.     def _subprocess_run(req_q, rsp_q, model_path):
  51.         try:
  52.             import onnxruntime as ort
  53.             sess = ort.InferenceSession(model_path, providers=['CPUExecutionProvider'])
  54.             rsp_q.put((OcclusionDetector.RSP_LOADED,))

  55.             while True:
  56.                 cmd = req_q.get()
  57.                 if cmd[0] == OcclusionDetector.CMD_SHUTDOWN:
  58.                     break
  59.                 elif cmd[0] == OcclusionDetector.CMD_DETECT:
  60.                     try:
  61.                         img = cmd[1]
  62.                         result = OcclusionDetector._run_detection(sess, img)
  63.                         rsp_q.put((OcclusionDetector.RSP_RESULT, result))
  64.                     except Exception as e:
  65.                         rsp_q.put((OcclusionDetector.RSP_ERROR, str(e)))
  66.         except Exception as e:
  67.             rsp_q.put((OcclusionDetector.RSP_ERROR, str(e)))

  68.     @staticmethod
  69.     def _run_detection(sess, img):
  70.         h, w = img.shape[:2]
  71.         input_img = OcclusionDetector._preprocess(img)
  72.         logits = sess.run(None, {'pixel_values': input_img})[0]
  73.         seg_map = OcclusionDetector._logits_to_segmap(logits, h, w)
  74.         return OcclusionDetector._seg_map_to_polys(seg_map, h, w)

  75.     @staticmethod
  76.     def _preprocess(img):
  77.         blob = cv2.dnn.blobFromImage(img, 1.0 / 255.0,
  78.                                       (OcclusionDetector.MODEL_INPUT_SIZE,
  79.                                        OcclusionDetector.MODEL_INPUT_SIZE),
  80.                                       swapRB=True, crop=False)
  81.         return blob.astype(np.float32)

  82.     @staticmethod
  83.     def _logits_to_segmap(logits, h, w):
  84.         seg = logits[0].astype(np.float32)
  85.         seg_upscaled = np.zeros((seg.shape[0], h, w), dtype=np.float32)
  86.         for c in range(seg.shape[0]):
  87.             seg_upscaled[c] = cv2.resize(seg[c], (w, h), interpolation=cv2.INTER_LINEAR)
  88.         seg_map = np.argmax(seg_upscaled, axis=0).astype(np.uint8)
  89.         return seg_map

  90.     @staticmethod
  91.     def _seg_map_to_polys(seg_map, h, w):
  92.         head_mask = np.zeros((h, w), dtype=np.uint8)
  93.         for label in OcclusionDetector.HEAD_LABELS:
  94.             head_mask[seg_map == label] = 255

  95.         include_mask = np.zeros((h, w), dtype=np.uint8)
  96.         for label in OcclusionDetector.INCLUDE_LABELS:
  97.             include_mask[seg_map == label] = 255

  98.         kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
  99.         include_mask = cv2.morphologyEx(include_mask, cv2.MORPH_CLOSE, kernel, iterations=1)
  100.         include_mask = cv2.morphologyEx(include_mask, cv2.MORPH_OPEN, kernel, iterations=1)

  101.         exclude_polys = []
  102.         for label in OcclusionDetector.EXCLUDE_LABELS:
  103.             label_mask = (seg_map == label).astype(np.uint8) * 255
  104.             overlap = cv2.bitwise_and(label_mask, head_mask)
  105.             if np.sum(overlap > 0) == 0:
  106.                 continue
  107.             overlap = cv2.morphologyEx(overlap, cv2.MORPH_CLOSE, kernel, iterations=1)
  108.             overlap = cv2.morphologyEx(overlap, cv2.MORPH_OPEN, kernel, iterations=1)
  109.             exclude_polys.extend(
  110.                 OcclusionDetector.mask_to_polys(overlap, min_area=80, epsilon_factor=0.003))

  111.         return {
  112.             'include': OcclusionDetector.mask_to_polys(include_mask, min_area=300, epsilon_factor=0.002),
  113.             'exclude': exclude_polys,
  114.         }

  115.     @staticmethod
  116.     def mask_to_polys(mask, min_area=100, epsilon_factor=0.005):
  117.         blurred = cv2.GaussianBlur(mask, (7, 7), 0)
  118.         _, smoothed = cv2.threshold(blurred, 128, 255, cv2.THRESH_BINARY)
  119.         contours, _ = cv2.findContours(smoothed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_L1)
  120.         polys = []
  121.         for contour in contours:
  122.             if cv2.contourArea(contour) < min_area:
  123.                 continue
  124.             epsilon = epsilon_factor * cv2.arcLength(contour, True)
  125.             approx = cv2.approxPolyDP(contour, epsilon, True)
  126.             pts = approx.reshape(-1, 2).astype(np.float32)
  127.             if len(pts) >= 3:
  128.                 polys.append(pts)
  129.         return polys
复制代码


回复 支持 反对

使用道具 举报

51

主题

926

帖子

7759

积分

高级丹圣

Rank: 13Rank: 13Rank: 13Rank: 13

积分
7759

万事如意节日勋章开心娱乐节日勋章

发表于 3 小时前 | 显示全部楼层
牛逼!
先收藏了
暂时用不上,
等以后需要用到的时候,再回来看
回复 支持 反对

使用道具 举报

QQ|Archiver|手机版|deepfacelab中文网 |网站地图

GMT+8, 2026-7-16 05:49 , Processed in 0.091044 second(s), 30 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表