惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 叶小钗
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
SegmentFault 最新的问题
博客园 - 三生石上(FineUI控件)
雷峰网
雷峰网
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
V
Visual Studio Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 聂微东
P
Proofpoint News Feed
Last Week in AI
Last Week in AI
U
Unit 42
W
WeLiveSecurity
博客园 - Franky
Recent Announcements
Recent Announcements
Hacker News - Newest:
Hacker News - Newest: "LLM"
Attack and Defense Labs
Attack and Defense Labs
月光博客
月光博客
The Cloudflare Blog
Spread Privacy
Spread Privacy
腾讯CDC
P
Privacy International News Feed
N
News and Events Feed by Topic
AWS News Blog
AWS News Blog
NISL@THU
NISL@THU
T
Troy Hunt's Blog
小众软件
小众软件
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Microsoft Security Blog
Microsoft Security Blog
L
Lohrmann on Cybersecurity
Webroot Blog
Webroot Blog
Y
Y Combinator Blog
量子位
P
Palo Alto Networks Blog
N
News and Events Feed by Topic
V
Vulnerabilities – Threatpost
K
Kaspersky official blog
IT之家
IT之家
T
Threat Research - Cisco Blogs
Cloudbric
Cloudbric
云风的 BLOG
云风的 BLOG
C
Check Point Blog
Blog — PlanetScale
Blog — PlanetScale
爱范儿
爱范儿
G
Google Developers Blog
S
Secure Thoughts

博客园 - Sanny.Liu-CV&&ML

GRPO 是否“真的在学” clip的底层原理---深入源码:手把手剖析OpenAI CLIP的实现结构与细节 Decoder-Only、Encoder-Only 与 Encoder-Decoder linux 进程内存占用查看 算一个bbox和一个mask区域的重叠 用PyTorch从零搭建一个Transformer模型 基于树编辑距离的相似度(TEDS) 图片,二进制,base64互转 OCR相关的笔记 opencv的RGB 颜色表 transformers中的generate函数解读 5 levels of text splitting PyMuPDF工具说明 OCR表格识别 uvicorn,一个无敌的 Python 库! stable diffusion中controlnet详细使用方法总结 lora训练参数设置 Dreambooth, Textual Inversion, LoRA, Hypernetworks ,示意图解释 转载:深度学习:蒸馏Distill MoveNet:超快且准确的姿态检测模型
根据5个人脸特征点,快速计算人脸角度
Sanny.Liu-CV&&ML · 2023-11-02 · via 博客园 - Sanny.Liu-CV&&ML
参考python代码实现:https://github.com/fisakhan/Face_Pose  pose_detection_scrfd.py

def find_pose(points):
  """
  Parameters
  ----------
  points : float32, Size = (5,2)
  coordinates of landmarks for the selected faces.
  Returns
  -------
  float32, float32, float32
  """
  LMx = points[:,0]#points[0:5]# horizontal coordinates of landmarks
  LMy = points[:,1]#[5:10]# vertical coordinates of landmarks


  dPx_eyes = max((LMx[1] - LMx[0]), 1)
  dPy_eyes = (LMy[1] - LMy[0])
  angle = np.arctan(dPy_eyes / dPx_eyes) # angle for rotation based on slope


  alpha = np.cos(angle)
  beta = np.sin(angle)


  # rotated landmarks
  LMxr = (alpha * LMx + beta * LMy + (1 - alpha) * LMx[2] / 2 - beta * LMy[2] / 2)
  LMyr = (-beta * LMx + alpha * LMy + beta * LMx[2] / 2 + (1 - alpha) * LMy[2] / 2)


  # average distance between eyes and mouth
  dXtot = (LMxr[1] - LMxr[0] + LMxr[4] - LMxr[3]) / 2
  dYtot = (LMyr[3] - LMyr[0] + LMyr[4] - LMyr[1]) / 2


  # average distance between nose and eyes
  dXnose = (LMxr[1] - LMxr[2] + LMxr[4] - LMxr[2]) / 2
  dYnose = (LMyr[3] - LMyr[2] + LMyr[4] - LMyr[2]) / 2


  # relative rotation 0 degree is frontal 90 degree is profile
  Xfrontal = (-90+90 / 0.5 * dXnose / dXtot) if dXtot != 0 else 0
  Yfrontal = (-90+90 / 0.5 * dYnose / dYtot) if dYtot != 0 else 0


  return angle * 180 / np.pi, Xfrontal, Yfrontal

c++ 实现

facial5Pts 五个点分别是:左眼,有眼,鼻子,左嘴角,右嘴角
std::vector<float> find_pose(const std::vector<cv::Point2d>& facial5Pts)
{
    const float PI_VALUE = 3.1415926;
    cv::Point2d eye_l = facial5Pts[0];
    cv::Point2d eye_r = facial5Pts[1];
    cv::Point2d nose =  facial5Pts[2];
    cv::Point2d mouth_l = facial5Pts[3];
    cv::Point2d mouth_r = facial5Pts[4];

    float dx = std::max(facial5Pts[1].x - facial5Pts[0].x, 1.0);
    float dy = facial5Pts[1].y - facial5Pts[0].y;
    double angle = atan(dy / dx);
    double alpha = cos(angle);
    double beta = sin(angle);

    // rotated landmarks
    std::vector<float> lmx_rot;
    lmx_rot.resize(5);
    std::vector<float> lmy_rot;
    lmy_rot.resize(5);
    float LM_nose_x = facial5Pts[2].x;
    float LM_nose_y = facial5Pts[2].y;
    //LMxr = (alpha * LMx + beta * LMy + (1 - alpha) * LMx[2] / 2 - beta * LMy[2] / 2)
    //LMyr = (-beta * LMx + alpha * LMy + beta * LMx[2] / 2 + (1 - alpha) * LMy[2] / 2)
    for(int i=0; i<5; i++){
        float LMx = facial5Pts[i].x;
        float LMy = facial5Pts[i].y;
        lmx_rot[i] = alpha * LMx + beta * LMy + (1 - alpha) * LM_nose_x / 2 - beta * LM_nose_y / 2;
        lmy_rot[i] = -beta * LMx + alpha * LMy + beta * LM_nose_x / 2 + (1 - alpha) * LM_nose_y / 2;
    }
    //# average distance between eyes and mouth
    //dXtot = (LMxr[1] - LMxr[0] + LMxr[4] - LMxr[3]) / 2
    //dYtot = (LMyr[3] - LMyr[0] + LMyr[4] - LMyr[1]) / 2
    float dXtot = (lmx_rot[1] - lmx_rot[0] + lmx_rot[4] - lmx_rot[3])/2;
    float dYtot = (lmy_rot[3] - lmy_rot[0] + lmy_rot[4] - lmy_rot[1])/2;
    //# average distance between nose and eyes
    //dXnose = (LMxr[1] - LMxr[2] + LMxr[4] - LMxr[2]) / 2
    //dYnose = (LMyr[3] - LMyr[2] + LMyr[4] - LMyr[2]) / 2
    float dXnose = (lmx_rot[1] - lmx_rot[2] + lmx_rot[4] - lmx_rot[2])/2;
    float dYnose = (lmy_rot[3] - lmy_rot[2] + lmy_rot[4] - lmy_rot[2])/2;

    //# relative rotation 0 degree is frontal 90 degree is profile
    //Xfrontal = (-90+90 / 0.5 * dXnose / dXtot) if dXtot != 0 else 0
    //Yfrontal = (-90+90 / 0.5 * dYnose / dYtot) if dYtot != 0 else 0
    float Xfrontal = 0;
    float Yfrontal = 0;
    if(dXtot != 0){
        Xfrontal = -90+90 / 0.5 * dXnose / dXtot;
    }
    if(dYtot != 0){
        Yfrontal = -90+90 / 0.5 * dYnose / dYtot;
    }
    float roll = angle * 180/PI_VALUE;
    float yaw = Xfrontal;
    float pitch = Yfrontal;
    std::vector<float> result = {roll, yaw, pitch};
    std::cout << "roll:" << result[0] << " yaw:" << result[1] << " pitch:" << result[2] << std::endl;
    return result;


}