CoolFace
Modelpublic

opencv/pose_estimation_mediapipe

sourceHugging Faceupdated 1y agoView on Hugging Face
6likes
demo.cpp2851 linesDownload Raw Back to root
1#include <vector>2#include <string>3#include <utility>4#include <cmath>5 6#include <opencv2/opencv.hpp>7 8const long double _M_PI = 3.141592653589793238L;9using namespace std;10using namespace cv;11using namespace dnn;12 13vector< pair<dnn::Backend, dnn::Target> > backendTargetPairs = {14        std::make_pair<dnn::Backend, dnn::Target>(dnn::DNN_BACKEND_OPENCV, dnn::DNN_TARGET_CPU),15        std::make_pair<dnn::Backend, dnn::Target>(dnn::DNN_BACKEND_CUDA, dnn::DNN_TARGET_CUDA),16        std::make_pair<dnn::Backend, dnn::Target>(dnn::DNN_BACKEND_CUDA, dnn::DNN_TARGET_CUDA_FP16),17        std::make_pair<dnn::Backend, dnn::Target>(dnn::DNN_BACKEND_TIMVX, dnn::DNN_TARGET_NPU),18        std::make_pair<dnn::Backend, dnn::Target>(dnn::DNN_BACKEND_CANN, dnn::DNN_TARGET_NPU) };19 20 21Mat getMediapipeAnchor();22 23class MPPersonDet {24private:25    Net net;26    string modelPath;27    Size inputSize;28    float scoreThreshold;29    float nmsThreshold;30    dnn::Backend backendId;31    dnn::Target targetId;32    int topK;33    Mat anchors;34 35public:36    MPPersonDet(string modPath, float nmsThresh = 0.3, float scoreThresh = 0.5, int tok=5000 , dnn::Backend bId = DNN_BACKEND_DEFAULT, dnn::Target tId = DNN_TARGET_CPU) :37        modelPath(modPath), nmsThreshold(nmsThresh),38        scoreThreshold(scoreThresh), topK(tok),39        backendId(bId), targetId(tId)40    {41        this->inputSize = Size(224, 224);42        this->net = readNet(this->modelPath);43        this->net.setPreferableBackend(this->backendId);44        this->net.setPreferableTarget(this->targetId);45        this->anchors = getMediapipeAnchor();46    }47 48    pair<Mat, Size> preprocess(Mat img)49    {50        Mat blob;51        Image2BlobParams paramMediapipe;52        paramMediapipe.datalayout = DNN_LAYOUT_NCHW;53        paramMediapipe.ddepth = CV_32F;54        paramMediapipe.mean = Scalar::all(127.5);55        paramMediapipe.scalefactor = Scalar::all(1/127.5);56        paramMediapipe.size = this->inputSize;57        paramMediapipe.swapRB = true;58        paramMediapipe.paddingmode = DNN_PMODE_LETTERBOX;59 60        double ratio = min(this->inputSize.height / double(img.rows), this->inputSize.width / double(img.cols));61        Size padBias(0, 0);62        if (img.rows != this->inputSize.height || img.cols != this->inputSize.width)63        {64            // keep aspect ratio when resize65            Size ratioSize(int(img.cols * ratio), int(img.rows* ratio));66            int padH = this->inputSize.height - ratioSize.height;67            int padW = this->inputSize.width - ratioSize.width;68            padBias.width = padW / 2;69            padBias.height = padH / 2;70        }71        blob = blobFromImageWithParams(img, paramMediapipe);72        padBias = Size(int(padBias.width / ratio), int(padBias.height / ratio));73        return pair<Mat, Size>(blob, padBias);74    }75 76   Mat infer(Mat srcimg)77    {78        pair<Mat, Size> w = this->preprocess(srcimg);79        Mat inputBlob = get<0>(w);80        Size padBias = get<1>(w);81        this->net.setInput(inputBlob);82        vector<Mat> outs;83        this->net.forward(outs, this->net.getUnconnectedOutLayersNames());84        Mat predictions = this->postprocess(outs, Size(srcimg.cols, srcimg.rows), padBias);85        return predictions;86    }87 88    Mat postprocess(vector<Mat> outputs, Size orgSize, Size padBias)89    {90        Mat score = outputs[1].reshape(0, outputs[1].size[0]);91        Mat boxLandDelta = outputs[0].reshape(outputs[0].size[0], outputs[0].size[1]);92        Mat boxDelta = boxLandDelta.colRange(0, 4);93        Mat landmarkDelta = boxLandDelta.colRange(4, boxLandDelta.cols);94        float scale = float(max(orgSize.height, orgSize.width));95        Mat mask = score < -100;96        score.setTo(-100, mask);97        mask = score > 100;98        score.setTo(100, mask);99        Mat deno;100        exp(-score, deno);101        divide(1.0, 1+deno, score);102        boxDelta.colRange(0, 1) = boxDelta.colRange(0, 1) / this->inputSize.width;103        boxDelta.colRange(1, 2) = boxDelta.colRange(1, 2) / this->inputSize.height;104        boxDelta.colRange(2, 3) = boxDelta.colRange(2, 3) / this->inputSize.width;105        boxDelta.colRange(3, 4) = boxDelta.colRange(3, 4) / this->inputSize.height;106        Mat xy1 = (boxDelta.colRange(0, 2) - boxDelta.colRange(2, 4) / 2 + this->anchors) * scale;107        Mat xy2 = (boxDelta.colRange(0, 2) + boxDelta.colRange(2, 4) / 2 + this->anchors) * scale;108        Mat boxes;109        hconcat(xy1, xy2, boxes);110        vector< Rect2d > rotBoxes(boxes.rows);111        boxes.colRange(0, 1) = boxes.colRange(0, 1) - padBias.width;112        boxes.colRange(1, 2) = boxes.colRange(1, 2) - padBias.height;113        boxes.colRange(2, 3) = boxes.colRange(2, 3) - padBias.width;114        boxes.colRange(3, 4) = boxes.colRange(3, 4) - padBias.height;115        for (int i = 0; i < boxes.rows; i++)116        {117            rotBoxes[i] = Rect2d(Point2d(boxes.at<float>(i, 0), boxes.at<float>(i, 1)), Point2d(boxes.at<float>(i, 2), boxes.at<float>(i, 3)));118        }119        vector<int> keep;120        NMSBoxes(rotBoxes, score, this->scoreThreshold, this->nmsThreshold, keep, 1.0f, this->topK);121        if (keep.size() == 0)122            return Mat();123        int nbCols = landmarkDelta.cols + boxes.cols + 1;124        Mat candidates(int(keep.size()), nbCols, CV_32FC1);125        int row = 0;126        for (auto idx : keep)127        {128            candidates.at<float>(row, nbCols - 1) = score.at<float>(idx);129            boxes.row(idx).copyTo(candidates.row(row).colRange(0, 4));130            candidates.at<float>(row, 4) = (landmarkDelta.at<float>(idx, 0) / this->inputSize.width + this->anchors.at<float>(idx,0)) * scale - padBias.width;131            candidates.at<float>(row, 5) = (landmarkDelta.at<float>(idx, 1) / this->inputSize.height + this->anchors.at<float>(idx, 1))* scale - padBias.height;132            candidates.at<float>(row, 6) = (landmarkDelta.at<float>(idx, 2) / this->inputSize.width + this->anchors.at<float>(idx, 0))* scale - padBias.width;133            candidates.at<float>(row, 7) = (landmarkDelta.at<float>(idx, 3) / this->inputSize.height + this->anchors.at<float>(idx, 1))* scale - padBias.height;134            candidates.at<float>(row, 8) = (landmarkDelta.at<float>(idx, 4) / this->inputSize.width + this->anchors.at<float>(idx, 0))* scale - padBias.width;135            candidates.at<float>(row, 9) = (landmarkDelta.at<float>(idx, 5) / this->inputSize.height + this->anchors.at<float>(idx, 1))* scale - padBias.height;136            candidates.at<float>(row, 10) = (landmarkDelta.at<float>(idx, 6) / this->inputSize.width + this->anchors.at<float>(idx, 0))* scale - padBias.width;137            candidates.at<float>(row, 11) = (landmarkDelta.at<float>(idx, 7) / this->inputSize.height + this->anchors.at<float>(idx, 1))* scale - padBias.height;138            row++;139        }140        return candidates;141       142    }143 144 145};146 147class MPPose {148private:149    Net net;150    string modelPath;151    Size inputSize;152    float confThreshold;153    dnn::Backend backendId;154    dnn::Target targetId;155    float personBoxPreEnlargeFactor;156    float personBoxEnlargeFactor;157    Mat anchors;158 159public:160    MPPose(string modPath, float confThresh = 0.5, dnn::Backend bId = DNN_BACKEND_DEFAULT, dnn::Target tId = DNN_TARGET_CPU) :161        modelPath(modPath), confThreshold(confThresh),162        backendId(bId), targetId(tId)163    {164        this->inputSize = Size(256, 256);165        this->net = readNet(this->modelPath);166        this->net.setPreferableBackend(this->backendId);167        this->net.setPreferableTarget(this->targetId);168        this->anchors = getMediapipeAnchor();169        // RoI will be larger so the performance will be better, but preprocess will be slower.Default to 1.170        this->personBoxPreEnlargeFactor = 1;171        this->personBoxEnlargeFactor = 1.25;172    }173 174    tuple<Mat, Mat, float, Mat, Size> preprocess(Mat image, Mat person)175    {176        /***177                Rotate input for inference.178                Parameters:179                  image - input image of BGR channel order180                  face_bbox - human face bounding box found in image of format [[x1, y1], [x2, y2]] (top-left and bottom-right points)181                  person_landmarks - 4 landmarks (2 full body points, 2 upper body points) of shape [4, 2]182                Returns:183                  rotated_person - rotated person image for inference184                  rotate_person_bbox - person box of interest range185                  angle - rotate angle for person186                  rotation_matrix - matrix for rotation and de-rotation187                  pad_bias - pad pixels of interest range188        */189        //  crop and pad image to interest range190        Size padBias(0, 0); // left, top191        Mat personKeypoints = person.colRange(4, 12).reshape(0, 4);192        Point2f midHipPoint = Point2f(personKeypoints.row(0));193        Point2f fullBodyPoint = Point2f(personKeypoints.row(1));194        // # get RoI195        double fullDist = norm(midHipPoint - fullBodyPoint);196        Mat fullBoxf,fullBox;197        Mat v1 = Mat(midHipPoint) - fullDist, v2 = Mat(midHipPoint);198        vector<Mat> vmat = { Mat(midHipPoint) - fullDist, Mat(midHipPoint) + fullDist };199        hconcat(vmat, fullBoxf);200        // enlarge to make sure full body can be cover201        Mat cBox, centerBox, whBox;202        reduce(fullBoxf, centerBox, 1, REDUCE_AVG, CV_32F);203        whBox = fullBoxf.col(1) - fullBoxf.col(0);204        Mat newHalfSize = whBox * this->personBoxPreEnlargeFactor / 2;205        vmat[0] = centerBox - newHalfSize;206        vmat[1] = centerBox + newHalfSize;207        hconcat(vmat, fullBox);208        Mat personBox;209        fullBox.convertTo(personBox, CV_32S);210        // refine person bbox211        Mat idx = personBox.row(0) < 0;212        personBox.row(0).setTo(0, idx);213        idx = personBox.row(0) >= image.cols;214        personBox.row(0).setTo(image.cols , idx);215        idx = personBox.row(1) < 0;216        personBox.row(1).setTo(0, idx);217        idx = personBox.row(1) >= image.rows;218        personBox.row(1).setTo(image.rows, idx);        // crop to the size of interest219 220        image = image(Rect(personBox.at<int>(0, 0), personBox.at<int>(1, 0), personBox.at<int>(0, 1) - personBox.at<int>(0, 0), personBox.at<int>(1, 1) - personBox.at<int>(1, 0)));221        // pad to square222        int top = int(personBox.at<int>(1, 0) - fullBox.at<float>(1, 0));223        int left = int(personBox.at<int>(0, 0) - fullBox.at<float>(0, 0));224        int bottom = int(fullBox.at<float>(1, 1) - personBox.at<int>(1, 1));225        int right = int(fullBox.at<float>(0, 1) - personBox.at<int>(0, 1));226        copyMakeBorder(image, image, top, bottom, left, right, BORDER_CONSTANT, Scalar(0, 0, 0));227        padBias = Point(padBias) + Point(personBox.col(0)) - Point(left, top);228        // compute rotation229        midHipPoint -= Point2f(padBias);230        fullBodyPoint -= Point2f(padBias);231        float radians = float(_M_PI / 2 - atan2(-(fullBodyPoint.y - midHipPoint.y), fullBodyPoint.x - midHipPoint.x));232        radians = radians - 2 * float(_M_PI) * int((radians + _M_PI) / (2 * _M_PI));233        float angle = (radians * 180 / float(_M_PI));234        //  get rotation matrix*235        Mat rotationMatrix = getRotationMatrix2D(midHipPoint, angle, 1.0);236        //  get rotated image237        Mat rotatedImage;238        warpAffine(image, rotatedImage, rotationMatrix, Size(image.cols, image.rows));239        //  get landmark bounding box240        Mat blob;241        Image2BlobParams paramPoseMediapipe;242        paramPoseMediapipe.datalayout = DNN_LAYOUT_NHWC;243        paramPoseMediapipe.ddepth = CV_32F;244        paramPoseMediapipe.mean = Scalar::all(0);245        paramPoseMediapipe.scalefactor = Scalar::all(1 / 255.);246        paramPoseMediapipe.size = this->inputSize;247        paramPoseMediapipe.swapRB = true;248        paramPoseMediapipe.paddingmode = DNN_PMODE_NULL;249        blob = blobFromImageWithParams(rotatedImage, paramPoseMediapipe); // resize INTER_AREA becomes INTER_LINEAR in blobFromImage250        Mat rotatedPersonBox = (Mat_<float>(2, 2) << 0, 0, image.cols, image.rows);251 252        return tuple<Mat, Mat, float, Mat, Size>(blob, rotatedPersonBox, angle, rotationMatrix, padBias);253    }254 255    tuple<Mat, Mat, Mat, Mat, Mat, float> infer(Mat image, Mat person)256    {257        int h = image.rows;258        int w = image.cols;259        // Preprocess260        tuple<Mat, Mat, float, Mat, Size> tw;261        tw = this->preprocess(image, person);262        Mat inputBlob = get<0>(tw);263        Mat rotatedPersonBbox = get<1>(tw);264        float  angle = get<2>(tw);265        Mat rotationMatrix = get<3>(tw);266        Size padBias = get<4>(tw);267 268        // Forward269        this->net.setInput(inputBlob);270        vector<Mat> outputBlob;271        this->net.forward(outputBlob, this->net.getUnconnectedOutLayersNames());272 273        // Postprocess274        tuple<Mat, Mat, Mat, Mat, Mat, float> results;275        results = this->postprocess(outputBlob, rotatedPersonBbox, angle, rotationMatrix, padBias, Size(w, h));276        return results;// # [bbox_coords, landmarks_coords, conf]277    }278 279    tuple<Mat, Mat, Mat, Mat, Mat, float> postprocess(vector<Mat> blob, Mat rotatedPersonBox, float angle, Mat rotationMatrix, Size padBias, Size imgSize)280    {281        float valConf = blob[1].at<float>(0);282        if (valConf < this->confThreshold)283            return tuple<Mat, Mat, Mat, Mat, Mat, float>(Mat(), Mat(), Mat(), Mat(), Mat(), valConf);284        Mat landmarks = blob[0].reshape(0, 39);285        Mat mask = blob[2];286        Mat heatmap = blob[3];287        Mat landmarksWorld = blob[4].reshape(0, 39);288 289        Mat deno;290        // recover sigmoid score291        exp(-landmarks.colRange(3, landmarks.cols), deno);292        divide(1.0, 1 + deno, landmarks.colRange(3, landmarks.cols));293        // TODO: refine landmarks with heatmap. reference: https://github.com/tensorflow/tfjs-models/blob/master/pose-detection/src/blazepose_tfjs/detector.ts#L577-L582294        heatmap = heatmap.reshape(0, heatmap.size[0]);295        // transform coords back to the input coords296        Mat whRotatedPersonPbox = rotatedPersonBox.row(1) - rotatedPersonBox.row(0);297        Mat scaleFactor = whRotatedPersonPbox.clone();298        scaleFactor.col(0) /= this->inputSize.width;299        scaleFactor.col(1) /= this->inputSize.height;300        landmarks.col(0) = (landmarks.col(0) - this->inputSize.width / 2) * scaleFactor.at<float>(0);301        landmarks.col(1) = (landmarks.col(1) - this->inputSize.height / 2) * scaleFactor.at<float>(1);302        landmarks.col(2) = landmarks.col(2) * max(scaleFactor.at<float>(1), scaleFactor.at<float>(0));303        Mat coordsRotationMatrix;304        getRotationMatrix2D(Point(0, 0), angle, 1.0).convertTo(coordsRotationMatrix, CV_32F);305        Mat rotatedLandmarks = landmarks.colRange(0, 2) * coordsRotationMatrix.colRange(0, 2);306        hconcat(rotatedLandmarks, landmarks.colRange(2, landmarks.cols), rotatedLandmarks);307        Mat rotatedLandmarksWorld = landmarksWorld.colRange(0, 2) * coordsRotationMatrix.colRange(0, 2);308        hconcat(rotatedLandmarksWorld, landmarksWorld.col(2), rotatedLandmarksWorld);309        // invert rotation310        Mat rotationComponent  = (Mat_<double>(2, 2) <<rotationMatrix.at<double>(0,0), rotationMatrix.at<double>(1, 0), rotationMatrix.at<double>(0, 1), rotationMatrix.at<double>(1, 1));311        Mat translationComponent = rotationMatrix(Rect(2, 0, 1, 2)).clone();312        Mat invertedTranslation = -rotationComponent * translationComponent;313        Mat inverseRotationMatrix;314        hconcat(rotationComponent, invertedTranslation, inverseRotationMatrix);315        Mat center, rc;316        reduce(rotatedPersonBox, rc, 0, REDUCE_AVG, CV_64F);317        hconcat(rc, Mat(1, 1, CV_64FC1, 1) , center);318        //  get box center319        Mat originalCenter(2, 1, CV_64FC1);320        originalCenter.at<double>(0) = center.dot(inverseRotationMatrix.row(0));321        originalCenter.at<double>(1) = center.dot(inverseRotationMatrix.row(1));322        for (int idxRow = 0; idxRow < rotatedLandmarks.rows; idxRow++)323        {324            landmarks.at<float>(idxRow, 0) = float(rotatedLandmarks.at<float>(idxRow, 0) + originalCenter.at<double>(0) + padBias.width); // 325            landmarks.at<float>(idxRow, 1) = float(rotatedLandmarks.at<float>(idxRow, 1) + originalCenter.at<double>(1) + padBias.height); // 326        }327        // get bounding box from rotated_landmarks328        double vmin0, vmin1, vmax0, vmax1;329        minMaxLoc(landmarks.col(0), &vmin0, &vmax0);330        minMaxLoc(landmarks.col(1), &vmin1, &vmax1);331        Mat bbox = (Mat_<float>(2, 2) << vmin0, vmin1, vmax0, vmax1);332        Mat centerBox;333        reduce(bbox, centerBox, 0, REDUCE_AVG, CV_32F);334        Mat whBox = bbox.row(1) - bbox.row(0);335        Mat newHalfSize = whBox * this->personBoxEnlargeFactor / 2;336        vector<Mat> vmat(2);337        vmat[0] = centerBox - newHalfSize;338        vmat[1] = centerBox + newHalfSize;339        vconcat(vmat, bbox);340        // invert rotation for mask341        mask = mask.reshape(1, 256);342        Mat invertRotationMatrix = getRotationMatrix2D(Point(mask.cols / 2, mask.rows / 2), -angle, 1.0);343        Mat invertRotationMask;344        warpAffine(mask, invertRotationMask, invertRotationMatrix, Size(mask.cols, mask.rows));345        // enlarge mask346        resize(invertRotationMask, invertRotationMask, Size(int(whRotatedPersonPbox.at<float>(0)), int(whRotatedPersonPbox.at<float>(1))));347        // crop and pad mask348        int minW = -min(padBias.width, 0);349        int minH= -min(padBias.height, 0);350        int left = max(padBias.width, 0);351        int top = max(padBias.height, 0);352        Size padOver = imgSize - Size(invertRotationMask.cols, invertRotationMask.rows) - padBias;353        int maxW = min(padOver.width, 0) + invertRotationMask.cols;354        int maxH = min(padOver.height, 0) + invertRotationMask.rows;355        int right = max(padOver.width, 0);356        int bottom = max(padOver.height, 0);357        invertRotationMask = invertRotationMask(Rect(minW, minH, maxW - minW, maxH - minH)).clone();358        copyMakeBorder(invertRotationMask, invertRotationMask, top, bottom, left, right, BORDER_CONSTANT, Scalar::all(0));359        // binarize mask360        threshold(invertRotationMask, invertRotationMask, 1, 255, THRESH_BINARY);361 362        /* 2*2 person bbox: [[x1, y1], [x2, y2]]363        # 39*5 screen landmarks: 33 keypoints and 6 auxiliary points with [x, y, z, visibility, presence], z value is relative to HIP364        # Visibility is probability that a keypoint is located within the frame and not occluded by another bigger body part or another object365        # Presence is probability that a keypoint is located within the frame366        # 39*3 world landmarks: 33 keypoints and 6 auxiliary points with [x, y, z] 3D metric x, y, z coordinate367        # img_height*img_width mask: gray mask, where 255 indicates the full body of a person and 0 means background368        # 64*64*39 heatmap: currently only used for refining landmarks, requires sigmod processing before use369        # conf: confidence of prediction*/370        return tuple<Mat , Mat, Mat, Mat, Mat, float>(bbox, landmarks, rotatedLandmarksWorld, invertRotationMask, heatmap, valConf);371    }372};373 374std::string keys =375"{ help  h          |                                               | Print help message. }"376"{ model m          | pose_estimation_mediapipe_2023mar.onnx        | Usage: Path to the model, defaults to person_detection_mediapipe_2023mar.onnx  }"377"{ input i          |                                               | Path to input image or video file. Skip this argument to capture frames from a camera.}"378"{ conf_threshold   | 0.5                                           | Usage: Filter out hands of confidence < conf_threshold. }"379"{ top_k            | 1                                             | Usage: Keep top_k bounding boxes before NMS. }"380"{ save s           | true                                          | Usage: Specify to save file with results (i.e. bounding box, confidence level). Invalid in case of camera input. }"381"{ vis v            | true                                          | Usage: Specify to open a new window to show results. Invalid in case of camera input. }"382"{ backend bt       | 0                                             | Choose one of computation backends: "383"0: (default) OpenCV implementation + CPU, "384"1: CUDA + GPU (CUDA), "385"2: CUDA + GPU (CUDA FP16), "386"3: TIM-VX + NPU, "387"4: CANN + NPU}";388 389 390void drawLines(Mat image, Mat landmarks, Mat keeplandmarks, bool isDrawPoint = true, int thickness = 2)391{392    393    vector<pair<int, int>> segment = {394        make_pair(0, 1), make_pair(1, 2), make_pair(2, 3), make_pair(3, 7),395        make_pair(0, 4), make_pair(4, 5), make_pair(5, 6), make_pair(6, 8),396        make_pair(9, 10),397        make_pair(12, 14), make_pair(14, 16), make_pair(16, 22), make_pair(16, 18), make_pair(16, 20), make_pair(18, 20),398        make_pair(11, 13), make_pair(13, 15), make_pair(15, 21), make_pair(15, 19), make_pair(15, 17), make_pair(17, 19),399        make_pair(11, 12), make_pair(11, 23), make_pair(23, 24), make_pair(24, 12),400        make_pair(24, 26), make_pair(26, 28), make_pair(28, 30), make_pair(28, 32), make_pair(30, 32),401        make_pair(23, 25), make_pair(25, 27),make_pair(27, 31), make_pair(27, 29), make_pair(29, 31) };402    for (auto p : segment)403        if (keeplandmarks.at<uchar>(p.first) && keeplandmarks.at<uchar>(p.second))404            line(image, Point(landmarks.row(p.first)), Point(landmarks.row(p.second)), Scalar(255, 255, 255), thickness);405    if (isDrawPoint)406        for (int idxRow = 0; idxRow < landmarks.rows; idxRow++)407            if (keeplandmarks.at<uchar>(idxRow))408                circle(image, Point(landmarks.row(idxRow)), thickness, Scalar(0, 0, 255), -1);409}410 411 412pair<Mat, Mat> visualize(Mat image, vector<tuple<Mat, Mat, Mat, Mat, Mat, float>> poses, float fps=-1)413{414    Mat displayScreen = image.clone();415    Mat display3d(400, 400, CV_8UC3, Scalar::all(0));416    line(display3d, Point(200, 0), Point(200, 400), Scalar(255, 255, 255), 2);417    line(display3d, Point(0, 200), Point(400, 200), Scalar(255, 255, 255), 2);418    putText(display3d, "Main View", Point(0, 12), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 255));419    putText(display3d, "Top View", Point(200, 12), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 255));420    putText(display3d, "Left View", Point(0, 212), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 255));421    putText(display3d, "Right View", Point(200, 212), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 255));422    bool isDraw = false;  // ensure only one person is drawn423 424    for (auto pose : poses)425    {426        Mat bbox = get<0>(pose);427        if (!bbox.empty())428        {429            Mat landmarksScreen = get<1>(pose);430            Mat landmarksWord = get<2>(pose);431            Mat mask;432            get<3>(pose).convertTo(mask, CV_8U);433            Mat heatmap = get<4>(pose);434            float conf = get<5>(pose);435            Mat edges;436            Canny(mask, edges, 100, 200);437            Mat kernel(2, 2, CV_8UC1, Scalar::all(1)); // expansion edge to 2 pixels438            dilate(edges, edges, kernel);439            Mat edgesBGR;440            cvtColor(edges, edgesBGR, COLOR_GRAY2BGR);441            Mat idxSelec = edges == 255;442            edgesBGR.setTo(Scalar(0, 255, 0), idxSelec);443 444            add(edgesBGR, displayScreen, displayScreen);445            // draw box446            Mat box;447            bbox.convertTo(box, CV_32S);448 449            rectangle(displayScreen, Point(box.row(0)), Point(box.row(1)), Scalar(0, 255, 0), 2);450            putText(displayScreen, format("Conf = %4f", conf), Point(0, 35), FONT_HERSHEY_DUPLEX, 0.7,Scalar(0, 0, 255), 2);451            if (fps > 0)452                putText(displayScreen, format("FPS = %.2f", fps), Point(0, 55), FONT_HERSHEY_SIMPLEX, 0.7, Scalar(0, 0, 255), 2);453            // Draw line between each key points454            landmarksScreen = landmarksScreen.rowRange(0, landmarksScreen.rows - 6);455            landmarksWord = landmarksWord.rowRange(0, landmarksWord.rows - 6);456 457            Mat keepLandmarks = landmarksScreen.col(4) > 0.8; // only show visible keypoints which presence bigger than 0.8458 459            Mat landmarksXY;460            landmarksScreen.colRange(0, 2).convertTo(landmarksXY, CV_32S);461            drawLines(displayScreen, landmarksXY, keepLandmarks, false);462 463            // z value is relative to HIP, but we use constant to instead464            for (int idxRow = 0; idxRow < landmarksScreen.rows; idxRow++)465            {466                Mat landmark;// p in enumerate(landmarks_screen[:, 0 : 3].astype(np.int32))467                landmarksScreen.row(idxRow).convertTo(landmark, CV_32S);468                if (keepLandmarks.at<uchar>(idxRow))469                    circle(displayScreen, Point(landmark.at<int>(0), landmark.at<int>(1)), 2, Scalar(0, 0, 255), -1);470            }471 472            if (!isDraw)473            {474                isDraw = true;475                // Main view476                Mat landmarksXY = landmarksWord.colRange(0, 2).clone();477                Mat x = landmarksXY * 100 + 100;478                x.convertTo(landmarksXY, CV_32S);479                drawLines(display3d, landmarksXY, keepLandmarks, true, 2);480 481                // Top view482                Mat landmarksXZ;483                hconcat(landmarksWord.col(0), landmarksWord.col(2), landmarksXZ);484                landmarksXZ.col(1) = -landmarksXZ.col(1);485                x = landmarksXZ * 100;486                x.col(0) += 300;487                x.col(1) += 100;488                x.convertTo(landmarksXZ, CV_32S);489                drawLines(display3d, landmarksXZ, keepLandmarks, true, 2);490 491                // Left view492                Mat landmarksYZ;493                hconcat(landmarksWord.col(2), landmarksWord.col(1), landmarksYZ);494                landmarksYZ.col(0) = -landmarksYZ.col(0);495                x = landmarksYZ * 100;496                x.col(0) += 100;497                x.col(1) += 300;498                x.convertTo(landmarksYZ, CV_32S);499                drawLines(display3d, landmarksYZ, keepLandmarks, true, 2);500 501                // Right view502                Mat landmarksZY;503                hconcat(landmarksWord.col(2), landmarksWord.col(1), landmarksZY);504                x = landmarksZY * 100;505                x.col(0) += 300;506                x.col(1) += 300;507                x.convertTo(landmarksZY, CV_32S);508                drawLines(display3d, landmarksZY, keepLandmarks, true, 2);509            }510        }511    }512    return pair<Mat, Mat>(displayScreen, display3d);513}514 515 516 517int main(int argc, char** argv)518{519    CommandLineParser parser(argc, argv, keys);520 521    parser.about("Person Detector from MediaPipe");522    if (parser.has("help"))523    {524        parser.printMessage();525        return 0;526    }527 528    string model = parser.get<String>("model");529    float confThreshold = parser.get<float>("conf_threshold");530    float scoreThreshold = 0.5f;531    float nmsThreshold = 0.3f;532    int topK = 5000;533    bool vis = parser.get<bool>("vis");534    bool save = parser.get<bool>("save");535    int backendTargetid = parser.get<int>("backend");536 537    if (model.empty())538    {539        CV_Error(Error::StsError, "Model file " + model + " not found");540    }541    VideoCapture cap;542    if (parser.has("input"))543        cap.open(samples::findFile(parser.get<String>("input")));544    else545        cap.open(0);546    Mat frame;547    // person detector548    MPPersonDet modelNet("../person_detection_mediapipe/person_detection_mediapipe_2023mar.onnx", nmsThreshold, scoreThreshold, topK,549        backendTargetPairs[backendTargetid].first, backendTargetPairs[backendTargetid].second);550    // pose estimator551    MPPose poseEstimator(model, confThreshold, backendTargetPairs[backendTargetid].first, backendTargetPairs[backendTargetid].second);552    //! [Open a video file or an image file or a camera stream]553    if (!cap.isOpened())554        CV_Error(Error::StsError, "Cannot open video or file");555 556    static const std::string kWinName = "MPPose Demo";557    while (waitKey(1) < 0)558    {559        cap >> frame;560        if (frame.empty())561        {562            if (parser.has("input"))563            {564                cout << "Frame is empty" << endl;565                break;566            }567            else568                continue;569        }570        TickMeter tm;571        tm.start();572        Mat person = modelNet.infer(frame);573        tm.stop();574        vector<tuple<Mat, Mat, Mat, Mat, Mat, float>> pose;575        for (int idxRow = 0; idxRow < person.rows; idxRow++)576        {577            tuple<Mat, Mat, Mat, Mat, Mat, float> re = poseEstimator.infer(frame, person.row(idxRow));578            if (!get<0>(re).empty())579                pose.push_back(re);580        }581        cout << "Inference time: " << tm.getTimeMilli() << " ms\n";582        pair<Mat, Mat> duoimg = visualize(frame, pose, tm.getFPS());583        if (vis)584        {585            imshow(kWinName, get<0>(duoimg));586            imshow("3d", get<1>(duoimg));587        }588    }589    return 0;590}591 592 593Mat getMediapipeAnchor()594{595    Mat anchor= (Mat_<float>(2254,2) << 0.017857142857142856, 0.017857142857142856,596        0.017857142857142856, 0.017857142857142856,597        0.05357142857142857, 0.017857142857142856,598        0.05357142857142857, 0.017857142857142856,599        0.08928571428571429, 0.017857142857142856,600        0.08928571428571429, 0.017857142857142856,601        0.125, 0.017857142857142856,602        0.125, 0.017857142857142856,603        0.16071428571428573, 0.017857142857142856,604        0.16071428571428573, 0.017857142857142856,605        0.19642857142857142, 0.017857142857142856,606        0.19642857142857142, 0.017857142857142856,607        0.23214285714285715, 0.017857142857142856,608        0.23214285714285715, 0.017857142857142856,609        0.26785714285714285, 0.017857142857142856,610        0.26785714285714285, 0.017857142857142856,611        0.30357142857142855, 0.017857142857142856,612        0.30357142857142855, 0.017857142857142856,613        0.3392857142857143, 0.017857142857142856,614        0.3392857142857143, 0.017857142857142856,615        0.375, 0.017857142857142856,616        0.375, 0.017857142857142856,617        0.4107142857142857, 0.017857142857142856,618        0.4107142857142857, 0.017857142857142856,619        0.44642857142857145, 0.017857142857142856,620        0.44642857142857145, 0.017857142857142856,621        0.48214285714285715, 0.017857142857142856,622        0.48214285714285715, 0.017857142857142856,623        0.5178571428571429, 0.017857142857142856,624        0.5178571428571429, 0.017857142857142856,625        0.5535714285714286, 0.017857142857142856,626        0.5535714285714286, 0.017857142857142856,627        0.5892857142857143, 0.017857142857142856,628        0.5892857142857143, 0.017857142857142856,629        0.625, 0.017857142857142856,630        0.625, 0.017857142857142856,631        0.6607142857142857, 0.017857142857142856,632        0.6607142857142857, 0.017857142857142856,633        0.6964285714285714, 0.017857142857142856,634        0.6964285714285714, 0.017857142857142856,635        0.7321428571428571, 0.017857142857142856,636        0.7321428571428571, 0.017857142857142856,637        0.7678571428571429, 0.017857142857142856,638        0.7678571428571429, 0.017857142857142856,639        0.8035714285714286, 0.017857142857142856,640        0.8035714285714286, 0.017857142857142856,641        0.8392857142857143, 0.017857142857142856,642        0.8392857142857143, 0.017857142857142856,643        0.875, 0.017857142857142856,644        0.875, 0.017857142857142856,645        0.9107142857142857, 0.017857142857142856,646        0.9107142857142857, 0.017857142857142856,647        0.9464285714285714, 0.017857142857142856,648        0.9464285714285714, 0.017857142857142856,649        0.9821428571428571, 0.017857142857142856,650        0.9821428571428571, 0.017857142857142856,651        0.017857142857142856, 0.05357142857142857,652        0.017857142857142856, 0.05357142857142857,653        0.05357142857142857, 0.05357142857142857,654        0.05357142857142857, 0.05357142857142857,655        0.08928571428571429, 0.05357142857142857,656        0.08928571428571429, 0.05357142857142857,657        0.125, 0.05357142857142857,658        0.125, 0.05357142857142857,659        0.16071428571428573, 0.05357142857142857,660        0.16071428571428573, 0.05357142857142857,661        0.19642857142857142, 0.05357142857142857,662        0.19642857142857142, 0.05357142857142857,663        0.23214285714285715, 0.05357142857142857,664        0.23214285714285715, 0.05357142857142857,665        0.26785714285714285, 0.05357142857142857,666        0.26785714285714285, 0.05357142857142857,667        0.30357142857142855, 0.05357142857142857,668        0.30357142857142855, 0.05357142857142857,669        0.3392857142857143, 0.05357142857142857,670        0.3392857142857143, 0.05357142857142857,671        0.375, 0.05357142857142857,672        0.375, 0.05357142857142857,673        0.4107142857142857, 0.05357142857142857,674        0.4107142857142857, 0.05357142857142857,675        0.44642857142857145, 0.05357142857142857,676        0.44642857142857145, 0.05357142857142857,677        0.48214285714285715, 0.05357142857142857,678        0.48214285714285715, 0.05357142857142857,679        0.5178571428571429, 0.05357142857142857,680        0.5178571428571429, 0.05357142857142857,681        0.5535714285714286, 0.05357142857142857,682        0.5535714285714286, 0.05357142857142857,683        0.5892857142857143, 0.05357142857142857,684        0.5892857142857143, 0.05357142857142857,685        0.625, 0.05357142857142857,686        0.625, 0.05357142857142857,687        0.6607142857142857, 0.05357142857142857,688        0.6607142857142857, 0.05357142857142857,689        0.6964285714285714, 0.05357142857142857,690        0.6964285714285714, 0.05357142857142857,691        0.7321428571428571, 0.05357142857142857,692        0.7321428571428571, 0.05357142857142857,693        0.7678571428571429, 0.05357142857142857,694        0.7678571428571429, 0.05357142857142857,695        0.8035714285714286, 0.05357142857142857,696        0.8035714285714286, 0.05357142857142857,697        0.8392857142857143, 0.05357142857142857,698        0.8392857142857143, 0.05357142857142857,699        0.875, 0.05357142857142857,700        0.875, 0.05357142857142857,701        0.9107142857142857, 0.05357142857142857,702        0.9107142857142857, 0.05357142857142857,703        0.9464285714285714, 0.05357142857142857,704        0.9464285714285714, 0.05357142857142857,705        0.9821428571428571, 0.05357142857142857,706        0.9821428571428571, 0.05357142857142857,707        0.017857142857142856, 0.08928571428571429,708        0.017857142857142856, 0.08928571428571429,709        0.05357142857142857, 0.08928571428571429,710        0.05357142857142857, 0.08928571428571429,711        0.08928571428571429, 0.08928571428571429,712        0.08928571428571429, 0.08928571428571429,713        0.125, 0.08928571428571429,714        0.125, 0.08928571428571429,715        0.16071428571428573, 0.08928571428571429,716        0.16071428571428573, 0.08928571428571429,717        0.19642857142857142, 0.08928571428571429,718        0.19642857142857142, 0.08928571428571429,719        0.23214285714285715, 0.08928571428571429,720        0.23214285714285715, 0.08928571428571429,721        0.26785714285714285, 0.08928571428571429,722        0.26785714285714285, 0.08928571428571429,723        0.30357142857142855, 0.08928571428571429,724        0.30357142857142855, 0.08928571428571429,725        0.3392857142857143, 0.08928571428571429,726        0.3392857142857143, 0.08928571428571429,727        0.375, 0.08928571428571429,728        0.375, 0.08928571428571429,729        0.4107142857142857, 0.08928571428571429,730        0.4107142857142857, 0.08928571428571429,731        0.44642857142857145, 0.08928571428571429,732        0.44642857142857145, 0.08928571428571429,733        0.48214285714285715, 0.08928571428571429,734        0.48214285714285715, 0.08928571428571429,735        0.5178571428571429, 0.08928571428571429,736        0.5178571428571429, 0.08928571428571429,737        0.5535714285714286, 0.08928571428571429,738        0.5535714285714286, 0.08928571428571429,739        0.5892857142857143, 0.08928571428571429,740        0.5892857142857143, 0.08928571428571429,741        0.625, 0.08928571428571429,742        0.625, 0.08928571428571429,743        0.6607142857142857, 0.08928571428571429,744        0.6607142857142857, 0.08928571428571429,745        0.6964285714285714, 0.08928571428571429,746        0.6964285714285714, 0.08928571428571429,747        0.7321428571428571, 0.08928571428571429,748        0.7321428571428571, 0.08928571428571429,749        0.7678571428571429, 0.08928571428571429,750        0.7678571428571429, 0.08928571428571429,751        0.8035714285714286, 0.08928571428571429,752        0.8035714285714286, 0.08928571428571429,753        0.8392857142857143, 0.08928571428571429,754        0.8392857142857143, 0.08928571428571429,755        0.875, 0.08928571428571429,756        0.875, 0.08928571428571429,757        0.9107142857142857, 0.08928571428571429,758        0.9107142857142857, 0.08928571428571429,759        0.9464285714285714, 0.08928571428571429,760        0.9464285714285714, 0.08928571428571429,761        0.9821428571428571, 0.08928571428571429,762        0.9821428571428571, 0.08928571428571429,763        0.017857142857142856, 0.125,764        0.017857142857142856, 0.125,765        0.05357142857142857, 0.125,766        0.05357142857142857, 0.125,767        0.08928571428571429, 0.125,768        0.08928571428571429, 0.125,769        0.125, 0.125,770        0.125, 0.125,771        0.16071428571428573, 0.125,772        0.16071428571428573, 0.125,773        0.19642857142857142, 0.125,774        0.19642857142857142, 0.125,775        0.23214285714285715, 0.125,776        0.23214285714285715, 0.125,777        0.26785714285714285, 0.125,778        0.26785714285714285, 0.125,779        0.30357142857142855, 0.125,780        0.30357142857142855, 0.125,781        0.3392857142857143, 0.125,782        0.3392857142857143, 0.125,783        0.375, 0.125,784        0.375, 0.125,785        0.4107142857142857, 0.125,786        0.4107142857142857, 0.125,787        0.44642857142857145, 0.125,788        0.44642857142857145, 0.125,789        0.48214285714285715, 0.125,790        0.48214285714285715, 0.125,791        0.5178571428571429, 0.125,792        0.5178571428571429, 0.125,793        0.5535714285714286, 0.125,794        0.5535714285714286, 0.125,795        0.5892857142857143, 0.125,796        0.5892857142857143, 0.125,797        0.625, 0.125,798        0.625, 0.125,799        0.6607142857142857, 0.125,800        0.6607142857142857, 0.125,801        0.6964285714285714, 0.125,802        0.6964285714285714, 0.125,803        0.7321428571428571, 0.125,804        0.7321428571428571, 0.125,805        0.7678571428571429, 0.125,806        0.7678571428571429, 0.125,807        0.8035714285714286, 0.125,808        0.8035714285714286, 0.125,809        0.8392857142857143, 0.125,810        0.8392857142857143, 0.125,811        0.875, 0.125,812        0.875, 0.125,813        0.9107142857142857, 0.125,814        0.9107142857142857, 0.125,815        0.9464285714285714, 0.125,816        0.9464285714285714, 0.125,817        0.9821428571428571, 0.125,818        0.9821428571428571, 0.125,819        0.017857142857142856, 0.16071428571428573,820        0.017857142857142856, 0.16071428571428573,821        0.05357142857142857, 0.16071428571428573,822        0.05357142857142857, 0.16071428571428573,823        0.08928571428571429, 0.16071428571428573,824        0.08928571428571429, 0.16071428571428573,825        0.125, 0.16071428571428573,826        0.125, 0.16071428571428573,827        0.16071428571428573, 0.16071428571428573,828        0.16071428571428573, 0.16071428571428573,829        0.19642857142857142, 0.16071428571428573,830        0.19642857142857142, 0.16071428571428573,831        0.23214285714285715, 0.16071428571428573,832        0.23214285714285715, 0.16071428571428573,833        0.26785714285714285, 0.16071428571428573,834        0.26785714285714285, 0.16071428571428573,835        0.30357142857142855, 0.16071428571428573,836        0.30357142857142855, 0.16071428571428573,837        0.3392857142857143, 0.16071428571428573,838        0.3392857142857143, 0.16071428571428573,839        0.375, 0.16071428571428573,840        0.375, 0.16071428571428573,841        0.4107142857142857, 0.16071428571428573,842        0.4107142857142857, 0.16071428571428573,843        0.44642857142857145, 0.16071428571428573,844        0.44642857142857145, 0.16071428571428573,845        0.48214285714285715, 0.16071428571428573,846        0.48214285714285715, 0.16071428571428573,847        0.5178571428571429, 0.16071428571428573,848        0.5178571428571429, 0.16071428571428573,849        0.5535714285714286, 0.16071428571428573,850        0.5535714285714286, 0.16071428571428573,851        0.5892857142857143, 0.16071428571428573,852        0.5892857142857143, 0.16071428571428573,853        0.625, 0.16071428571428573,854        0.625, 0.16071428571428573,855        0.6607142857142857, 0.16071428571428573,856        0.6607142857142857, 0.16071428571428573,857        0.6964285714285714, 0.16071428571428573,858        0.6964285714285714, 0.16071428571428573,859        0.7321428571428571, 0.16071428571428573,860        0.7321428571428571, 0.16071428571428573,861        0.7678571428571429, 0.16071428571428573,862        0.7678571428571429, 0.16071428571428573,863        0.8035714285714286, 0.16071428571428573,864        0.8035714285714286, 0.16071428571428573,865        0.8392857142857143, 0.16071428571428573,866        0.8392857142857143, 0.16071428571428573,867        0.875, 0.16071428571428573,868        0.875, 0.16071428571428573,869        0.9107142857142857, 0.16071428571428573,870        0.9107142857142857, 0.16071428571428573,871        0.9464285714285714, 0.16071428571428573,872        0.9464285714285714, 0.16071428571428573,873        0.9821428571428571, 0.16071428571428573,874        0.9821428571428571, 0.16071428571428573,875        0.017857142857142856, 0.19642857142857142,876        0.017857142857142856, 0.19642857142857142,877        0.05357142857142857, 0.19642857142857142,878        0.05357142857142857, 0.19642857142857142,879        0.08928571428571429, 0.19642857142857142,880        0.08928571428571429, 0.19642857142857142,881        0.125, 0.19642857142857142,882        0.125, 0.19642857142857142,883        0.16071428571428573, 0.19642857142857142,884        0.16071428571428573, 0.19642857142857142,885        0.19642857142857142, 0.19642857142857142,886        0.19642857142857142, 0.19642857142857142,887        0.23214285714285715, 0.19642857142857142,888        0.23214285714285715, 0.19642857142857142,889        0.26785714285714285, 0.19642857142857142,890        0.26785714285714285, 0.19642857142857142,891        0.30357142857142855, 0.19642857142857142,892        0.30357142857142855, 0.19642857142857142,893        0.3392857142857143, 0.19642857142857142,894        0.3392857142857143, 0.19642857142857142,895        0.375, 0.19642857142857142,896        0.375, 0.19642857142857142,897        0.4107142857142857, 0.19642857142857142,898        0.4107142857142857, 0.19642857142857142,899        0.44642857142857145, 0.19642857142857142,900        0.44642857142857145, 0.19642857142857142,901        0.48214285714285715, 0.19642857142857142,902        0.48214285714285715, 0.19642857142857142,903        0.5178571428571429, 0.19642857142857142,904        0.5178571428571429, 0.19642857142857142,905        0.5535714285714286, 0.19642857142857142,906        0.5535714285714286, 0.19642857142857142,907        0.5892857142857143, 0.19642857142857142,908        0.5892857142857143, 0.19642857142857142,909        0.625, 0.19642857142857142,910        0.625, 0.19642857142857142,911        0.6607142857142857, 0.19642857142857142,912        0.6607142857142857, 0.19642857142857142,913        0.6964285714285714, 0.19642857142857142,914        0.6964285714285714, 0.19642857142857142,915        0.7321428571428571, 0.19642857142857142,916        0.7321428571428571, 0.19642857142857142,917        0.7678571428571429, 0.19642857142857142,918        0.7678571428571429, 0.19642857142857142,919        0.8035714285714286, 0.19642857142857142,920        0.8035714285714286, 0.19642857142857142,921        0.8392857142857143, 0.19642857142857142,922        0.8392857142857143, 0.19642857142857142,923        0.875, 0.19642857142857142,924        0.875, 0.19642857142857142,925        0.9107142857142857, 0.19642857142857142,926        0.9107142857142857, 0.19642857142857142,927        0.9464285714285714, 0.19642857142857142,928        0.9464285714285714, 0.19642857142857142,929        0.9821428571428571, 0.19642857142857142,930        0.9821428571428571, 0.19642857142857142,931        0.017857142857142856, 0.23214285714285715,932        0.017857142857142856, 0.23214285714285715,933        0.05357142857142857, 0.23214285714285715,934        0.05357142857142857, 0.23214285714285715,935        0.08928571428571429, 0.23214285714285715,936        0.08928571428571429, 0.23214285714285715,937        0.125, 0.23214285714285715,938        0.125, 0.23214285714285715,939        0.16071428571428573, 0.23214285714285715,940        0.16071428571428573, 0.23214285714285715,941        0.19642857142857142, 0.23214285714285715,942        0.19642857142857142, 0.23214285714285715,943        0.23214285714285715, 0.23214285714285715,944        0.23214285714285715, 0.23214285714285715,945        0.26785714285714285, 0.23214285714285715,946        0.26785714285714285, 0.23214285714285715,947        0.30357142857142855, 0.23214285714285715,948        0.30357142857142855, 0.23214285714285715,949        0.3392857142857143, 0.23214285714285715,950        0.3392857142857143, 0.23214285714285715,951        0.375, 0.23214285714285715,952        0.375, 0.23214285714285715,953        0.4107142857142857, 0.23214285714285715,954        0.4107142857142857, 0.23214285714285715,955        0.44642857142857145, 0.23214285714285715,956        0.44642857142857145, 0.23214285714285715,957        0.48214285714285715, 0.23214285714285715,958        0.48214285714285715, 0.23214285714285715,959        0.5178571428571429, 0.23214285714285715,960        0.5178571428571429, 0.23214285714285715,961        0.5535714285714286, 0.23214285714285715,962        0.5535714285714286, 0.23214285714285715,963        0.5892857142857143, 0.23214285714285715,964        0.5892857142857143, 0.23214285714285715,965        0.625, 0.23214285714285715,966        0.625, 0.23214285714285715,967        0.6607142857142857, 0.23214285714285715,968        0.6607142857142857, 0.23214285714285715,969        0.6964285714285714, 0.23214285714285715,970        0.6964285714285714, 0.23214285714285715,971        0.7321428571428571, 0.23214285714285715,972        0.7321428571428571, 0.23214285714285715,973        0.7678571428571429, 0.23214285714285715,974        0.7678571428571429, 0.23214285714285715,975        0.8035714285714286, 0.23214285714285715,976        0.8035714285714286, 0.23214285714285715,977        0.8392857142857143, 0.23214285714285715,978        0.8392857142857143, 0.23214285714285715,979        0.875, 0.23214285714285715,980        0.875, 0.23214285714285715,981        0.9107142857142857, 0.23214285714285715,982        0.9107142857142857, 0.23214285714285715,983        0.9464285714285714, 0.23214285714285715,984        0.9464285714285714, 0.23214285714285715,985        0.9821428571428571, 0.23214285714285715,986        0.9821428571428571, 0.23214285714285715,987        0.017857142857142856, 0.26785714285714285,988        0.017857142857142856, 0.26785714285714285,989        0.05357142857142857, 0.26785714285714285,990        0.05357142857142857, 0.26785714285714285,991        0.08928571428571429, 0.26785714285714285,992        0.08928571428571429, 0.26785714285714285,993        0.125, 0.26785714285714285,994        0.125, 0.26785714285714285,995        0.16071428571428573, 0.26785714285714285,996        0.16071428571428573, 0.26785714285714285,997        0.19642857142857142, 0.26785714285714285,998        0.19642857142857142, 0.26785714285714285,999        0.23214285714285715, 0.26785714285714285,1000        0.23214285714285715, 0.26785714285714285,1001        0.26785714285714285, 0.26785714285714285,1002        0.26785714285714285, 0.26785714285714285,1003        0.30357142857142855, 0.26785714285714285,1004        0.30357142857142855, 0.26785714285714285,1005        0.3392857142857143, 0.26785714285714285,1006        0.3392857142857143, 0.26785714285714285,1007        0.375, 0.26785714285714285,1008        0.375, 0.26785714285714285,1009        0.4107142857142857, 0.26785714285714285,1010        0.4107142857142857, 0.26785714285714285,1011        0.44642857142857145, 0.26785714285714285,1012        0.44642857142857145, 0.26785714285714285,1013        0.48214285714285715, 0.26785714285714285,1014        0.48214285714285715, 0.26785714285714285,1015        0.5178571428571429, 0.26785714285714285,1016        0.5178571428571429, 0.26785714285714285,1017        0.5535714285714286, 0.26785714285714285,1018        0.5535714285714286, 0.26785714285714285,1019        0.5892857142857143, 0.26785714285714285,1020        0.5892857142857143, 0.26785714285714285,1021        0.625, 0.26785714285714285,1022        0.625, 0.26785714285714285,1023        0.6607142857142857, 0.26785714285714285,1024        0.6607142857142857, 0.26785714285714285,1025        0.6964285714285714, 0.26785714285714285,1026        0.6964285714285714, 0.26785714285714285,1027        0.7321428571428571, 0.26785714285714285,1028        0.7321428571428571, 0.26785714285714285,1029        0.7678571428571429, 0.26785714285714285,1030        0.7678571428571429, 0.26785714285714285,1031        0.8035714285714286, 0.26785714285714285,1032        0.8035714285714286, 0.26785714285714285,1033        0.8392857142857143, 0.26785714285714285,1034        0.8392857142857143, 0.26785714285714285,1035        0.875, 0.26785714285714285,1036        0.875, 0.26785714285714285,1037        0.9107142857142857, 0.26785714285714285,1038        0.9107142857142857, 0.26785714285714285,1039        0.9464285714285714, 0.26785714285714285,1040        0.9464285714285714, 0.26785714285714285,1041        0.9821428571428571, 0.26785714285714285,1042        0.9821428571428571, 0.26785714285714285,1043        0.017857142857142856, 0.30357142857142855,1044        0.017857142857142856, 0.30357142857142855,1045        0.05357142857142857, 0.30357142857142855,1046        0.05357142857142857, 0.30357142857142855,1047        0.08928571428571429, 0.30357142857142855,1048        0.08928571428571429, 0.30357142857142855,1049        0.125, 0.30357142857142855,1050        0.125, 0.30357142857142855,1051        0.16071428571428573, 0.30357142857142855,1052        0.16071428571428573, 0.30357142857142855,1053        0.19642857142857142, 0.30357142857142855,1054        0.19642857142857142, 0.30357142857142855,1055        0.23214285714285715, 0.30357142857142855,1056        0.23214285714285715, 0.30357142857142855,1057        0.26785714285714285, 0.30357142857142855,1058        0.26785714285714285, 0.30357142857142855,1059        0.30357142857142855, 0.30357142857142855,1060        0.30357142857142855, 0.30357142857142855,1061        0.3392857142857143, 0.30357142857142855,1062        0.3392857142857143, 0.30357142857142855,1063        0.375, 0.30357142857142855,1064        0.375, 0.30357142857142855,1065        0.4107142857142857, 0.30357142857142855,1066        0.4107142857142857, 0.30357142857142855,1067        0.44642857142857145, 0.30357142857142855,1068        0.44642857142857145, 0.30357142857142855,1069        0.48214285714285715, 0.30357142857142855,1070        0.48214285714285715, 0.30357142857142855,1071        0.5178571428571429, 0.30357142857142855,1072        0.5178571428571429, 0.30357142857142855,1073        0.5535714285714286, 0.30357142857142855,1074        0.5535714285714286, 0.30357142857142855,1075        0.5892857142857143, 0.30357142857142855,1076        0.5892857142857143, 0.30357142857142855,1077        0.625, 0.30357142857142855,1078        0.625, 0.30357142857142855,1079        0.6607142857142857, 0.30357142857142855,1080        0.6607142857142857, 0.30357142857142855,1081        0.6964285714285714, 0.30357142857142855,1082        0.6964285714285714, 0.30357142857142855,1083        0.7321428571428571, 0.30357142857142855,1084        0.7321428571428571, 0.30357142857142855,1085        0.7678571428571429, 0.30357142857142855,1086        0.7678571428571429, 0.30357142857142855,1087        0.8035714285714286, 0.30357142857142855,1088        0.8035714285714286, 0.30357142857142855,1089        0.8392857142857143, 0.30357142857142855,1090        0.8392857142857143, 0.30357142857142855,1091        0.875, 0.30357142857142855,1092        0.875, 0.30357142857142855,1093        0.9107142857142857, 0.30357142857142855,1094        0.9107142857142857, 0.30357142857142855,1095        0.9464285714285714, 0.30357142857142855,1096        0.9464285714285714, 0.30357142857142855,1097        0.9821428571428571, 0.30357142857142855,1098        0.9821428571428571, 0.30357142857142855,1099        0.017857142857142856, 0.3392857142857143,1100        0.017857142857142856, 0.3392857142857143,1101        0.05357142857142857, 0.3392857142857143,1102        0.05357142857142857, 0.3392857142857143,1103        0.08928571428571429, 0.3392857142857143,1104        0.08928571428571429, 0.3392857142857143,1105        0.125, 0.3392857142857143,1106        0.125, 0.3392857142857143,1107        0.16071428571428573, 0.3392857142857143,1108        0.16071428571428573, 0.3392857142857143,1109        0.19642857142857142, 0.3392857142857143,1110        0.19642857142857142, 0.3392857142857143,1111        0.23214285714285715, 0.3392857142857143,1112        0.23214285714285715, 0.3392857142857143,1113        0.26785714285714285, 0.3392857142857143,1114        0.26785714285714285, 0.3392857142857143,1115        0.30357142857142855, 0.3392857142857143,1116        0.30357142857142855, 0.3392857142857143,1117        0.3392857142857143, 0.3392857142857143,1118        0.3392857142857143, 0.3392857142857143,1119        0.375, 0.3392857142857143,1120        0.375, 0.3392857142857143,1121        0.4107142857142857, 0.3392857142857143,1122        0.4107142857142857, 0.3392857142857143,1123        0.44642857142857145, 0.3392857142857143,1124        0.44642857142857145, 0.3392857142857143,1125        0.48214285714285715, 0.3392857142857143,1126        0.48214285714285715, 0.3392857142857143,1127        0.5178571428571429, 0.3392857142857143,1128        0.5178571428571429, 0.3392857142857143,1129        0.5535714285714286, 0.3392857142857143,1130        0.5535714285714286, 0.3392857142857143,1131        0.5892857142857143, 0.3392857142857143,1132        0.5892857142857143, 0.3392857142857143,1133        0.625, 0.3392857142857143,1134        0.625, 0.3392857142857143,1135        0.6607142857142857, 0.3392857142857143,1136        0.6607142857142857, 0.3392857142857143,1137        0.6964285714285714, 0.3392857142857143,1138        0.6964285714285714, 0.3392857142857143,1139        0.7321428571428571, 0.3392857142857143,1140        0.7321428571428571, 0.3392857142857143,1141        0.7678571428571429, 0.3392857142857143,1142        0.7678571428571429, 0.3392857142857143,1143        0.8035714285714286, 0.3392857142857143,1144        0.8035714285714286, 0.3392857142857143,1145        0.8392857142857143, 0.3392857142857143,1146        0.8392857142857143, 0.3392857142857143,1147        0.875, 0.3392857142857143,1148        0.875, 0.3392857142857143,1149        0.9107142857142857, 0.3392857142857143,1150        0.9107142857142857, 0.3392857142857143,1151        0.9464285714285714, 0.3392857142857143,1152        0.9464285714285714, 0.3392857142857143,1153        0.9821428571428571, 0.3392857142857143,1154        0.9821428571428571, 0.3392857142857143,1155        0.017857142857142856, 0.375,1156        0.017857142857142856, 0.375,1157        0.05357142857142857, 0.375,1158        0.05357142857142857, 0.375,1159        0.08928571428571429, 0.375,1160        0.08928571428571429, 0.375,1161        0.125, 0.375,1162        0.125, 0.375,1163        0.16071428571428573, 0.375,1164        0.16071428571428573, 0.375,1165        0.19642857142857142, 0.375,1166        0.19642857142857142, 0.375,1167        0.23214285714285715, 0.375,1168        0.23214285714285715, 0.375,1169        0.26785714285714285, 0.375,1170        0.26785714285714285, 0.375,1171        0.30357142857142855, 0.375,1172        0.30357142857142855, 0.375,1173        0.3392857142857143, 0.375,1174        0.3392857142857143, 0.375,1175        0.375, 0.375,1176        0.375, 0.375,1177        0.4107142857142857, 0.375,1178        0.4107142857142857, 0.375,1179        0.44642857142857145, 0.375,1180        0.44642857142857145, 0.375,1181        0.48214285714285715, 0.375,1182        0.48214285714285715, 0.375,1183        0.5178571428571429, 0.375,1184        0.5178571428571429, 0.375,1185        0.5535714285714286, 0.375,1186        0.5535714285714286, 0.375,1187        0.5892857142857143, 0.375,1188        0.5892857142857143, 0.375,1189        0.625, 0.375,1190        0.625, 0.375,1191        0.6607142857142857, 0.375,1192        0.6607142857142857, 0.375,1193        0.6964285714285714, 0.375,1194        0.6964285714285714, 0.375,1195        0.7321428571428571, 0.375,1196        0.7321428571428571, 0.375,1197        0.7678571428571429, 0.375,1198        0.7678571428571429, 0.375,1199        0.8035714285714286, 0.375,1200        0.8035714285714286, 0.375,

Showing the first 1,200 of 2851 lines. Download the file for the rest.