Detectron .pkl模型轉(zhuǎn)成Caffe2 .pb模型

Detectron訓(xùn)練出來的目標(biāo)檢測模型后綴為.pkl饲宿,在使用的時候必須要有圖(graph)以及Detectron代碼的支持,轉(zhuǎn)為caffe2標(biāo)準(zhǔn)的pb模型后刺彩,就可以脫離detectron的代碼單獨運行亥啦。

轉(zhuǎn)換用到的 tools/convert_pkl_to_pb.py
1.png

2.png

3.png

生成三個文件

并在對應(yīng)的yaml文件中加入
4.png
測試代碼.pb模型代碼,根據(jù)自己情況進(jìn)行修改
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName  :pb_infer.py
# @Time      :2020/6/2 15:42
# @Author    :wanlin


import cv2
import numpy as np
from caffe2.python import core, workspace
from caffe2.proto import caffe2_pb2
import time
from caffe2.python import dyndep
import os

# 需要detectron中一個庫的支持,因此必須導(dǎo)入辉阶,該庫位于caffe2的路徑中
detectron_ops_lib = '/home/wl/anaconda3/envs/wl_torch14/lib/python3.6/site-packages/torch/lib/libcaffe2_detectron_ops_gpu.so'
dyndep.InitOpsLibrary(detectron_ops_lib)


def get_device_option_cpu():
    device_option = core.DeviceOption(caffe2_pb2.CPU)
    return device_option


def get_device_option_cuda(gpu_id=0):
    device_option = caffe2_pb2.DeviceOption()
    device_option.device_type = caffe2_pb2.CUDA
    device_option.device_id = gpu_id
    return device_option


def _sort_results(boxes, segms, keypoints, classes):
    indices = np.argsort(boxes[:, -1])[::-1]
    if boxes is not None:
        boxes = boxes[indices, :]
    if segms is not None:
        segms = [segms[x] for x in indices]
    if keypoints is not None:
        keypoints = [keypoints[x] for x in indices]
    if classes is not None:
        if isinstance(classes, list):
            classes = [classes[x] for x in indices]
        else:
            classes = classes[indices]

    return boxes, segms, keypoints, classes


FPN_COARSEST_STRIDE = 32


def im_list_to_blob(ims):
    """Convert a list of images into a network input. Assumes images were
    prepared using prep_im_for_blob or equivalent: i.e.
      - BGR channel order
      - pixel means subtracted
      - resized to the desired input size
      - float32 numpy ndarray format
    Output is a 4D HCHW tensor of the images concatenated along axis 0 with
    shape.
    """
    if not isinstance(ims, list):
        ims = [ims]
    max_shape = np.array([im.shape for im in ims]).max(axis=0)
    # Pad the image so they can be divisible by a stride
    if FPN_ON:
        # stride = float(FPN_COARSEST_STRIDE)
        stride = float(FPN_COARSEST_STRIDE)
        max_shape[0] = int(np.ceil(max_shape[0] / stride) * stride)
        max_shape[1] = int(np.ceil(max_shape[1] / stride) * stride)

    num_images = len(ims)
    blob = np.zeros(
        (num_images, max_shape[0], max_shape[1], 3), dtype=np.float32
    )
    for i in range(num_images):
        im = ims[i]
        blob[i, 0:im.shape[0], 0:im.shape[1], :] = im
    # Move channels (axis 3) to axis 1
    # Axis order will become: (batch elem, channel, height, width)
    channel_swap = (0, 3, 1, 2)
    blob = blob.transpose(channel_swap)
    return blob


def _prepare_blobs(
        im,
        target_size,
        max_size,
):
    ''' Reference: blob.prep_im_for_blob() '''

    im = im.astype(np.float32, copy=False)
    # im -= pixel_means
    im_shape = im.shape

    im_size_min = np.min(im_shape[0:2])
    im_size_max = np.max(im_shape[0:2])
    im_scale = float(target_size) / float(im_size_min)
    if np.round(im_scale * im_size_max) > max_size:
        im_scale = float(max_size) / float(im_size_max)
    im = cv2.resize(im, None, None, fx=im_scale, fy=im_scale,
                    interpolation=cv2.INTER_LINEAR)

    # Reuse code in blob_utils and fit FPN
    blob = im_list_to_blob([im])

    blobs = {}
    blobs['data'] = blob
    blobs['im_info'] = np.array(
        [[blob.shape[2], blob.shape[3], im_scale]],
        dtype=np.float32
    )
    return blobs


def create_input_blobs_for_net(net_def):
    for op in net_def.op:
        for blob_in in op.input:
            if not workspace.HasBlob(blob_in):
                workspace.CreateBlob(blob_in)
    print("Current blobs in the workspace: {}".format(workspace.Blobs()))


def run_model_pb(net, init_net, im):
    workspace.ResetWorkspace()
    workspace.RunNetOnce(init_net)
    create_input_blobs_for_net(net)
    workspace.CreateNet(net)

    # PIXEL_MEANS = np.array([[[102.9801, 115.9465, 122.7717]]])
    # PIXEL_MEANS = np.array([[[0, 0, 0]]])
    # input_blobs, _ = core_test._get_blobs(im, None)
    input_blobs = _prepare_blobs(
        im,
        TEST_SCALE, TEST_MAX_SIZE
    )

    # gpu_blobs = []
    gpu_blobs = ['data']
    # GPU
    t1 = time.time()

    for k, v in input_blobs.items():
        workspace.FeedBlob(
            core.ScopedName(k),
            v,
            get_device_option_cuda() if k in gpu_blobs else
            get_device_option_cpu()
        )
    # CPU
    # for k, v in input_blobs.items():
    #    workspace.FeedBlob(
    #    core.ScopedName(k),
    #    v,
    #    device_option = core.DeviceOption(caffe2_pb2.CPU)
    # )
    try:
        workspace.RunNet(net.name)
        scores = workspace.FetchBlob('score_nms')
        classids = workspace.FetchBlob('class_nms')
        boxes = workspace.FetchBlob('bbox_nms')
    except Exception as e:
        print('Running pb model failed.\n{}'.format(e))
        # may not detect anything at all
        R = 0
        scores = np.zeros((R,), dtype=np.float32)
        boxes = np.zeros((R, 4), dtype=np.float32)
        classids = np.zeros((R,), dtype=np.float32)

    t2 = time.time()
    print('spend time: ', t2-t1)
    boxes = np.column_stack((boxes, scores))

    # sort the results based on score for comparision
    boxes, _, _, classids = _sort_results(
        boxes, None, None, classids)

    return boxes, classids


if __name__ == '__main__':
    model_path = './pb_file'
    FPN_ON = True
    # FPN_COARSEST_STRIDE = 32
    TEST_SCALE, TEST_MAX_SIZE = 800, 1024

    test_img_file = './test_image.jpg'
    print('Loading test file {}...'.format(test_img_file))
    test_img = cv2.imread(test_img_file)
    assert test_img is not None

    predict_net = caffe2_pb2.NetDef()
    init_net = caffe2_pb2.NetDef()
    with open(os.path.join(model_path,"model.pb"),'rb') as f:
        predict_net.ParseFromString(f.read())
    with open(os.path.join(model_path,"model_init.pb"), 'rb') as f:
        init_net.ParseFromString(f.read())

    label_color = {1:(255,0,0),2:(0,0,255),3:(0,255,0)}
    start = time.time()
    boxes, classids = run_model_pb(predict_net, init_net, test_img)
    end = time.time()
    print(end - start)
    for box, classid in zip(boxes, classids):
        if box[4] >= 0.7:
            cv2.rectangle(test_img, (box[0],box[1]),(box[2],box[3]),label_color[int(classid)],3)
    cv2.imwrite('./test_image_result.jpg', test_img)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末先壕,一起剝皮案震驚了整個濱河市瘩扼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌垃僚,老刑警劉巖集绰,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異谆棺,居然都是意外死亡栽燕,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進(jìn)店門改淑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碍岔,“玉大人,你說我怎么就攤上這事朵夏“玻” “怎么了?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵仰猖,是天一觀的道長捏肢。 經(jīng)常有香客問我,道長饥侵,這世上最難降的妖魔是什么鸵赫? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮躏升,結(jié)果婚禮上辩棒,老公的妹妹穿的比我還像新娘。我一直安慰自己煮甥,他們只是感情好盗温,可當(dāng)我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著成肘,像睡著了一般卖局。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上双霍,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天砚偶,我揣著相機與錄音,去河邊找鬼洒闸。 笑死染坯,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丘逸。 我是一名探鬼主播单鹿,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼深纲!你這毒婦竟也來了仲锄?” 一聲冷哼從身側(cè)響起劲妙,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎儒喊,沒想到半個月后镣奋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡怀愧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年侨颈,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芯义。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡哈垢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出毕贼,到底是詐尸還是另有隱情温赔,我是刑警寧澤蛤奢,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布鬼癣,位于F島的核電站,受9級特大地震影響啤贩,放射性物質(zhì)發(fā)生泄漏待秃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一痹屹、第九天 我趴在偏房一處隱蔽的房頂上張望章郁。 院中可真熱鬧,春花似錦志衍、人聲如沸暖庄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽培廓。三九已至,卻和暖如春春叫,著一層夾襖步出監(jiān)牢的瞬間肩钠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工暂殖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留价匠,地道東北人。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓呛每,卻偏偏與公主長得像踩窖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子晨横,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,781評論 2 361