mmPose HRnetv2 pytorch—>onnx—>opencv推理

HRnetv2 pytorch—>onnx—>opencv推理

一蚯姆、下載模型、克隆項(xiàng)目

在mmpose官方下載https://mmpose.readthedocs.io/zh_CN/latest/topics/hand%282d%29.html


項(xiàng)目克掳中稀:

git cloen https://github.com/open-mmlab/mmpose

需要的庫支持:
onnx
onnxruntime
mmpose
mmcv

二、模型轉(zhuǎn)換pytorch—>onnx

在mmpose根目錄下:

python tools/deployment/pytorch2onnx.py configs/hand/2d_kpt_sview_rgb_img/topdown_heatmap/coco_wholebody_hand/hrnetv2_w18_coco_wholebody_hand_256x256.py /workspace/downloads/hrnetv2_w18_coco_wholebody_hand_256x256-1c028db7_20210908.pth --output-file hrnetv2_w18_coco_wholebody_hand_256x256.onnx
```![](https://upload-images.jianshu.io/upload_images/15646173-aa569e812f81c8f6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![![![![Untitled.png](https://upload-images.jianshu.io/upload_images/15646173-c57edce8ca3d85d2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
](https://upload-images.jianshu.io/upload_images/15646173-eab84a4374502725.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
](https://upload-images.jianshu.io/upload_images/15646173-7461750f4f57fdf2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
](https://upload-images.jianshu.io/upload_images/15646173-df22f88d988833fa.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

會有警告庶香,為了避免出現(xiàn)其他問題甲棍,這里參照網(wǎng)上:

```bash
python remove_initializer_from_input.py --input your_old_model.onnx --output your_new_model.onnx

remove_initializer_from_input.py代碼如下:

import onnx
import argparse

def get_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--input", required=True, help="input model")
    parser.add_argument("--output", required=True, help="output model")
    args = parser.parse_args()
    return args

def remove_initializer_from_input():
    args = get_args()

    model = onnx.load(args.input)
    if model.ir_version < 4:
        print(
            'Model with ir_version below 4 requires to include initilizer in graph input'
        )
        return

    inputs = model.graph.input
    name_to_input = {}
    for input in inputs:
        name_to_input[input.name] = input

    for initializer in model.graph.initializer:
        if initializer.name in name_to_input:
            inputs.remove(name_to_input[initializer.name])

    onnx.save(model, args.output)

if __name__ == '__main__':
    remove_initializer_from_input()

三、opencv推理代碼

#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

using namespace cv;
using namespace cv::dnn;
#include <iostream>
using namespace std;
// connection table, in the format [model_id][pair_id][from/to]
// please look at the nice explanation at the bottom of:
// https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/doc/output.md
//
const int POSE_PAIRS[3][20][2] = {
{   // COCO body
    {1,2}, {1,5}, {2,3},
    {3,4}, {5,6}, {6,7},
    {1,8}, {8,9}, {9,10},
    {1,11}, {11,12}, {12,13},
    {1,0}, {0,14},
    {14,16}, {0,15}, {15,17}
},
{   // MPI body
    {0,1}, {1,2}, {2,3},
    {3,4}, {1,5}, {5,6},
    {6,7}, {1,14}, {14,8}, {8,9},
    {9,10}, {14,11}, {11,12}, {12,13}
},
{   // hand
    {0,1}, {1,2}, {2,3}, {3,4},         // thumb
    {0,5}, {5,6}, {6,7}, {7,8},         // pinkie
    {0,9}, {9,10}, {10,11}, {11,12},    // middle
    {0,13}, {13,14}, {14,15}, {15,16},  // ring
    {0,17}, {17,18}, {18,19}, {19,20}   // small
} };
int main(int argc, char **argv)
{
    CommandLineParser parser(argc, argv,
        "{ h help           | false     | print this help message }"
        "{ p proto          |           | (required) model configuration, e.g. hand/pose.prototxt }"
        "{ m model          |           | (required) model weights, e.g. hand/pose_iter_102000.caffemodel }"
        "{ i image          |           | (required) path to image file (containing a single person, or hand) }"
        "{ d dataset        |           | specify what kind of model was trained. It could be (COCO, MPI, HAND) depends on dataset. }"
        "{ width            |  368      | Preprocess input image by resizing to a specific width. }"
        "{ height           |  368      | Preprocess input image by resizing to a specific height. }"
        "{ t threshold      |  0.1      | threshold or confidence value for the heatmap }"
        "{ s scale          |  0.003922 | scale for blob }"
    );
    //    cv::String modelTxt = samples::findFile(parser.get<string>("proto"));
    //    cv::String modelBin = samples::findFile(parser.get<string>("model"));
    //    cv::String imageFile = samples::findFile(parser.get<String>("image"));
    //    cv::String dataset = parser.get<cv::String>("dataset");
    //    int W_in = parser.get<int>("width");
    //    int H_in = parser.get<int>("height");
    //    float thresh = parser.get<float>("threshold");
    //    float scale  = parser.get<float>("scale");

    cv::String modelOnnx = "C:\\Users\\haihan\\Desktop\\new_hrnetv2_w18_coco_wholebody_hand_256x256.onnx";
    cv::String modelTxt = "E:\\openpose_pose_coco.prototxt";
    cv::String modelBin = "E:\\code\\openpose-1.7.0\\models\\pose\\coco\\pose_iter_440000.caffemodel";
    cv::String imageFile = "E:\\code\\openpose-1.7.0\\examples\\media\\1.png";
    cv::String dataset = "COCO";
    int W_in = 256;
    int H_in = 256;
    float thresh = 0.1f;
    float scale = 0.003922f;

    if (parser.get<bool>("help") || modelTxt.empty() || modelBin.empty() || imageFile.empty())
    {
        cout << "A sample app to demonstrate human or hand pose detection with a pretrained OpenPose dnn." << endl;
        parser.printMessage();
        return 0;
    }
    int midx, npairs, nparts;
    if (!dataset.compare("COCO")) { midx = 0; npairs = 17; nparts = 18; }
    else if (!dataset.compare("MPI")) { midx = 1; npairs = 14; nparts = 16; }
    else if (!dataset.compare("HAND")) { midx = 2; npairs = 20; nparts = 22; }
    else
    {
        std::cerr << "Can't interpret dataset parameter: " << dataset << std::endl;
        exit(-1);
    }
    // read the network model
    Net net = readNetFromONNX(modelOnnx);
    
    // and the image
    Mat img = imread(imageFile);
    if (img.empty())
    {
        std::cerr << "Can't read image from the file: " << imageFile << std::endl;
        exit(-1);
    }
    Mat img_rgb;
    cvtColor(img, img_rgb, COLOR_BGR2RGB);
    // send it through the network
    Mat inputBlob = blobFromImage(img_rgb, scale, Size(W_in, H_in), Scalar(0, 0, 0), false, false);
    net.setInput(inputBlob);
    Mat result = net.forward();
    // the result is an array of "heatmaps", the probability of a body part being in location x,y
    int H = result.size[2];
    int W = result.size[3];
    // find the position of the body parts
    vector<Point> points(22);
    for (int n = 0; n < nparts; n++)
    {
        // Slice heatmap of corresponding body's part.
        Mat heatMap(H, W, CV_32F, result.ptr(0, n));
        // 1 maximum per heatmap
        Point p(-1, -1), pm;
        double conf;
        minMaxLoc(heatMap, 0, &conf, 0, &pm);
        if (conf > thresh)
            p = pm;
        points[n] = p;
    }
    // connect body parts and draw it !
    float SX = float(img.cols) / W;
    float SY = float(img.rows) / H;
    for (int n = 0; n < npairs; n++)
    {
        // lookup 2 connected body/hand parts
        Point2f a = points[POSE_PAIRS[midx][n][0]];
        Point2f b = points[POSE_PAIRS[midx][n][1]];
        // we did not find enough confidence before
        if (a.x <= 0 || a.y <= 0 || b.x <= 0 || b.y <= 0)
            continue;
        // scale to image size
        a.x *= SX; a.y *= SY;
        b.x *= SX; b.y *= SY;
        line(img, a, b, Scalar(0, 200, 0), 2);
        circle(img, a, 3, Scalar(0, 0, 200), -1);
        circle(img, b, 3, Scalar(0, 0, 200), -1);
    }
    imshow("OpenPose", img);
    waitKey();
    return 0;
}

代碼為網(wǎng)上的代碼赶掖,連線部分有問題,需要改進(jìn)

TO-DO

  • HRnetv2 pytorch轉(zhuǎn)onnx
  • opencv onnx推理
  • opencv dnn cuda加速
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末七扰,一起剝皮案震驚了整個濱河市奢赂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌颈走,老刑警劉巖膳灶,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡轧钓,警方通過查閱死者的電腦和手機(jī)序厉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來毕箍,“玉大人弛房,你說我怎么就攤上這事《蹋” “怎么了文捶?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長媒咳。 經(jīng)常有香客問我粹排,道長,這世上最難降的妖魔是什么涩澡? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任顽耳,我火速辦了婚禮,結(jié)果婚禮上妙同,老公的妹妹穿的比我還像新娘射富。我一直安慰自己,他們只是感情好渐溶,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布辉浦。 她就那樣靜靜地躺著,像睡著了一般茎辐。 火紅的嫁衣襯著肌膚如雪宪郊。 梳的紋絲不亂的頭發(fā)上拖陆,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天弛槐,我揣著相機(jī)與錄音,去河邊找鬼依啰。 笑死乎串,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的速警。 我是一名探鬼主播叹誉,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼闷旧!你這毒婦竟也來了长豁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤忙灼,失蹤者是張志新(化名)和其女友劉穎匠襟,沒想到半個月后钝侠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡酸舍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年帅韧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片啃勉。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡忽舟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出璧亮,到底是詐尸還是另有隱情萧诫,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布枝嘶,位于F島的核電站帘饶,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏群扶。R本人自食惡果不足惜及刻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望竞阐。 院中可真熱鬧缴饭,春花似錦、人聲如沸骆莹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽幕垦。三九已至丢氢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間先改,已是汗流浹背疚察。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留仇奶,地道東北人貌嫡。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像该溯,于是被迫代替她去往敵國和親岛抄。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345