deepfacelab中文网

 找回密码
 立即注册(仅限QQ邮箱)
查看: 82|回复: 3

哪位老兄帮忙哈,脸部特征点提取的问题

[复制链接]

20

主题

155

帖子

994

积分

高级丹师

Rank: 5Rank: 5

积分
994
 楼主| 发表于 昨天 11:01 | 显示全部楼层 |阅读模式
星级打分
  • 1
  • 2
  • 3
  • 4
  • 5
平均分:NAN  参与人数:0  我的评分:未评
00003.jpg


彻底换了deepfacelab框架,基于pytorch框架构建的,丫的光这个面部识别参数调整了一个小时了,愣是不能完美。 哪位老兄帮忙哈,给个逻辑,或者重构哈。

  1.     def get_pts_from_predict(self, a, center, scale):
  2.         """
  3.         Extract points from the model prediction heatmaps
  4.         """
  5.         a_ch, a_h, a_w = a.shape
  6.         
  7.         print(f"get_pts_from_predict: Input shape = ({a_ch}, {a_h}, {a_w}), dtype = {a.dtype}")

  8.         # Make sure we have the right number of channels (should be 68 for landmarks)
  9.         if a_ch != 68:
  10.             print(f"Warning: Expected 68 channels for landmarks, got {a_ch}. Using fallback landmarks.")
  11.             base_landmarks = LandmarksProcessor.landmarks_2D
  12.             # Create fallback landmarks based on center
  13.             fallback_pts = base_landmarks.astype(np.float32) * 100 + np.array([center[0], center[1]], dtype=np.float32)
  14.             return fallback_pts

  15.         b = a.reshape((a_ch, a_h*a_w))
  16.         c = b.argmax(1).reshape((a_ch, 1)).repeat(2, axis=1).astype(np.float32)  # Force to float32
  17.         c[:,0] %= a_w
  18.         c[:,1] = np.apply_along_axis(lambda x: np.floor(x / a_w), 0, c[:,1])

  19.         for i in range(a_ch):
  20.             pX, pY = int(c[i,0]), int(c[i,1])
  21.             # Use dynamic boundary check instead of hardcoding 63
  22.             if pX > 0 and pX < a_w-1 and pY > 0 and pY < a_h-1:
  23.                 diff = np.array([a[i,pY,pX+1]-a[i,pY,pX-1], a[i,pY+1,pX]-a[i,pY-1,pX]], dtype=np.float32)  # Force to float32
  24.                 c[i] += np.sign(diff)*0.25

  25.         c += 0.5
  26.         
  27.         # Apply a scaling factor to adjust landmark size if needed
  28.         pts = np.array([self.transform(c[i], center, scale, a_w) for i in range(a_ch)], dtype=np.float32)  # Ensure output is float32
  29.         
  30.         # Fine-tune adjustment based on face size
  31.         # Calculate the actual face width and height from the bounding box
  32.         face_width = scale * 195.0  # This is the actual face width in pixels
  33.         # Use a reference face size (e.g., 200 pixels) as baseline
  34.         reference_face_size = 200.0
  35.         # Calculate adjustment factor based on actual face size
  36.         adjustment_factor = face_width / reference_face_size
  37.         
  38.         # Apply a small adjustment to reduce the spread slightly
  39.         # Based on historical experience, use a factor between 0.95 and 0.98
  40.         fine_tune_factor = 0.97  # Reduce spread by 3%
  41.         
  42.         # Apply adjustment to landmarks
  43.         if adjustment_factor > 0:
  44.             # Calculate centroid of landmarks
  45.             centroid = np.mean(pts, axis=0)
  46.             # Scale distances from centroid by the adjustment factor
  47.             pts = centroid + (pts - centroid) * adjustment_factor * fine_tune_factor
  48.         
  49.         return pts
复制代码


回复

使用道具 举报

20

主题

155

帖子

994

积分

高级丹师

Rank: 5Rank: 5

积分
994
 楼主| 发表于 昨天 11:02 | 显示全部楼层
精细化了 我发现还是有问题
# Apply a small adjustment to reduce the spread slightly
        # Based on historical experience, use a factor between 0.95 and 0.98
        fine_tune_factor = 0.97  # Reduce spread by 3%
回复 支持 反对

使用道具 举报

20

主题

155

帖子

994

积分

高级丹师

Rank: 5Rank: 5

积分
994
 楼主| 发表于 昨天 11:26 | 显示全部楼层
  1.     def transform(self, point, center, scale, resolution):
  2.         """
  3.         Transform a point from model space to image space
  4.         """
  5.         pt = np.array([point[0], point[1], 1.0], dtype=np.float32)  # Ensure float32
  6.         h = 200.0 * scale
  7.         m = np.eye(3, dtype=np.float32)  # Ensure float32
  8.         m[0,0] = resolution / h
  9.         m[1,1] = resolution / h
  10.         m[0,2] = resolution * ( -center[0] / h + 0.5 )
  11.         m[1,2] = resolution * ( -center[1] / h + 0.5 )
  12.         m = np.linalg.inv(m)
  13.         
  14.         # Apply a small adjustment to the transformed points based on actual face size
  15.         # This is based on empirical observation that PyTorch version tends to produce slightly smaller landmarks
  16.         adjusted_pt = np.matmul(m, pt)[0:2].astype(np.float32)
  17.         
  18.         # Calculate the actual face width and height from the bounding box
  19.         face_width = scale * 195.0  # This is the actual face width in pixels
  20.         # Use a reference face size (e.g., 200 pixels) as baseline
  21.         reference_face_size = 200.0
  22.         # Calculate adjustment factor based on actual face size
  23.         adjustment_factor = face_width / reference_face_size
  24.         
  25.         # Apply a small adjustment to reduce the spread slightly
  26.         fine_tune_factor = 0.98  # Reduce by 2%
  27.         
  28.         # Apply adjustment to the transformed point
  29.         if adjustment_factor > 0:
  30.             # Calculate centroid of landmarks (approximate)
  31.             centroid = np.array([center[0], center[1]], dtype=np.float32)
  32.             # Scale distances from centroid by the adjustment factor
  33.             adjusted_pt = centroid + (adjusted_pt - centroid) * adjustment_factor * fine_tune_factor
  34.         
  35.         return adjusted_pt
复制代码


在transform方法中添加一个基于实际人脸尺寸的动态调整机制 也不行,草了。
回复 支持 反对

使用道具 举报

20

主题

155

帖子

994

积分

高级丹师

Rank: 5Rank: 5

积分
994
 楼主| 发表于 昨天 11:29 | 显示全部楼层
基于热图峰值位置的精确调整,也不行

    def get_pts_from_predict(self, a, center, scale):
        """
        Extract points from the model prediction heatmaps
        """
        a_ch, a_h, a_w = a.shape
        
        print(f"get_pts_from_predict: Input shape = ({a_ch}, {a_h}, {a_w}), dtype = {a.dtype}")

        # Make sure we have the right number of channels (should be 68 for landmarks)
        if a_ch != 68:
            print(f"Warning: Expected 68 channels for landmarks, got {a_ch}. Using fallback landmarks.")
            base_landmarks = LandmarksProcessor.landmarks_2D
            # Create fallback landmarks based on center
            fallback_pts = base_landmarks.astype(np.float32) * 100 + np.array([center[0], center[1]], dtype=np.float32)
            return fallback_pts

        b = a.reshape((a_ch, a_h*a_w))
        c = b.argmax(1).reshape((a_ch, 1)).repeat(2, axis=1).astype(np.float32)  # Force to float32
        c[:,0] %= a_w
        c[:,1] = np.apply_along_axis(lambda x: np.floor(x / a_w), 0, c[:,1])

        for i in range(a_ch):
            pX, pY = int(c[i,0]), int(c[i,1])
            # Use dynamic boundary check instead of hardcoding 63
            if pX > 0 and pX < a_w-1 and pY > 0 and pY < a_h-1:
                diff = np.array([a[i,pY,pX+1]-a[i,pY,pX-1], a[i,pY+1,pX]-a[i,pY-1,pX]], dtype=np.float32)  # Force to float32
                c[i] += np.sign(diff)*0.25

        c += 0.5
        
        # Apply a scaling factor to adjust landmark size if needed
        pts = np.array([self.transform(c[i], center, scale, a_w) for i in range(a_ch)], dtype=np.float32)  # Ensure output is float32
        
        # Add a small offset to adjust for potential bias in the model's output
        # This is based on empirical observation that FAN model tends to produce slightly oversized landmarks
        offset_factor = 0.95  # Reduce by 5%
        
        # Calculate centroid of landmarks
        centroid = np.mean(pts, axis=0)
        # Scale distances from centroid by the offset factor
        pts = centroid + (pts - centroid) * offset_factor
        
        return pts
回复 支持 反对

使用道具 举报

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

GMT+8, 2026-1-14 00:26 , Processed in 0.127262 second(s), 32 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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