human_pose_estimation_demo的進一步研究

  • 2019 年 10 月 30 日
  • 筆記

一、demo能力

OpenVINO提供了範例(human_pose_estimation_demo),能夠在CPU上以較快速度識別出多人

 

iE:/OpenVINO_modelZoo/head-pose-face-detection-female-and-male.mp4 -mE:/OpenVINO_modelZoo/human-pose-estimation-0001.xml -d CPU

基於這篇論文:

參考文檔:
https://docs.openvinotoolkit.org/latest/_demos_human_pose_estimation_demo_README.html
二、抽取18個點,做簡單的越界分析
既然以及能夠從影片中抽取人體骨骼,並且對應18個數據點
那麼就能夠做定量分析。
對於這個影片,使用MarkMan能夠測量出關鍵領域的位置,那麼最簡單的想法就是首先獲得“人的中心”這個點,當這個點位於敏感區域的時候進行報警。
但是這種方法很粗糙,我們希望得到的是這個敏感區域裡面,沒有人體的任何一個位置,因此首先對所有的點進行排序,而後判斷
bool SortbyXaxis(const cv::Point2f & a, const cv::Point2f &b)
{
    return a.x > b.x;
}

//而後對所有的點進行這樣處理
HumanPose firstHumanPose = poses[0];
std::vector<cv::Point2f> firstKeypoints = firstHumanPose.keypoints;
sort( firstKeypoints .begin(), firstKeypoints .end(), SortbyYaxis );

if (! (firstKeypoints[0].x < 369 || firstKeypoints[firstKeypoints.size() 1].x > 544))
{
    std::stringstream inRanges;
    inRanges << “inRanges! “;
    cv::putText(image, inRanges.str(), cv::Point(16, 64),
    cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(0, 0, 255));
}

這樣就能夠好許多。

三、更接近實際的情況
前面的情況還是過於簡單,這個影片更接近實際情況

比如地上有這條安全線,傾斜的,就是不能越過,應該如何來處理?
首先還是量出這條線(固定物鏡關係),並且我們能夠繪製出這條線;
下面,首先要做一個簡單的數學複習
K = (y1-y2)/(x1-x2),當K1>K2的時候點在左邊,而在左邊灰色區域的時候,絕對在左邊,在右邊藍色區域的時候,絕對在右邊。
據此編寫函數
bool PointIsLeftLine(cv::Point2f point, cv::Point2f PointLineLeft, cv::Point2f PointLineRight)
{
    //邊界外直接返回
    if (point.x < 0)
        return false;
    if (point.x <= PointLineLeft.x)
        return true;
    if (point.x > PointLineRight.x)
        return false;
    //在邊界內的情況,通過計算斜率
    if (PointLineRight.x == PointLineLeft.x)
        assert(“error PointLineRight.x == PointLineLeft.x”);
    
    float kLine = (PointLineRight.y  PointLineLeft.y) / (PointLineRight.x  PointLineLeft.x);
    float k = (point.y  PointLineLeft.y) / (point.x  PointLineLeft.x);
    return (k >= kLine);
}

並且分別對兩個腳進行處理
     bRight = PointIsLeftLine(pointRightFoot, cv::Point2f(1017513), cv::Point2f(433, image.rows  1));
     bLeft  = PointIsLeftLine(pointLeftFoot, cv::Point2f(1017513), cv::Point2f(433, image.rows  1));

 
加上一些影像繪製
 
    if (bRight|| bLeft)
            {
                line(image, cv::Point(1017513), cv::Point(433, image.rows  1), cv::Scalar(00255), 8);
            }
            else
            {
                line(image, cv::Point(1017513), cv::Point(433, image.rows  1), cv::Scalar(02550), 8);
            }

能夠得到這樣的結果:
四、存在的問題
做到這一步,看起來問題得到了很好的解決,但是實際上還是出現了新的問題:
1、速度。目前只能做到8-9FPS,如何提高速度是不卡影片輸入是新問題;
2、多人的識別;
3、區域的劃定;
4、介面操作。
這些問題都解決好,應該能夠商用,最主要的是速度問題。
感謝閱讀至此,希望有所幫助。