python调用yolov3模型_深度学习之目标检测系列(7) -使用python调用运行 YOLO V3模型并在原图绘制预览...

使用python调用yolo v3模型我们已经成功进行检测,但是如何将结果绘制到原图上呢?我们先分析一下返回的数据结构。

使用python调用yolo v3模型返回结果如下:

[(b'dog', 0.999338686466217, (224.18377685546875, 378.4237060546875, 178.60214233398438, 328.1665954589844)), (b'bicycle', 0.9933530688285828, (344.39508056640625, 286.08282470703125, 489.40667724609375, 323.8568420410156)), (b'truck', 0.9153000116348267, (580.7305908203125, 125.11731719970703, 208.38641357421875, 87.00074768066406))]

结果含义为返回检测结果的数组,取出其中一个检测对象如下:

(b'dog', 0.999338686466217, (224.18377685546875, 378.4237060546875, 178.60214233398438, 328.1665954589844))

第一个元素dog,表示检测的分类为dog;

第二个元素0.999338686466217,表示检测的概率;

第三个元素(224.18377685546875, 378.4237060546875, 178.60214233398438, 328.1665954589844),分表表示了中心的x坐标、y坐标以及检测对象的宽和高。

坐标怎么计算呢?实际就是根据C点坐标以及目标对象宽和高,计算L和R点坐标,如看下图:

可以看出,计算公式如下:

L(x) = C(x) - width / 2

L(y) = C(y) - height / 2

R(x) = C(x) + width / 2

R(y) = C(y) + height / 2

根据公式,解析结果的代码大致如下:

def draw_boxes_and_label(img, result):

# 加载图像

d_img = cv.imread(img)

for i in range(len(result)):

# 解析检测单个对象

obj = result[i]

# 分类名称

class_name = str(obj[0], encoding="utf8")

# 预测概率

prob = obj[1]

# 中心点坐标

pos = obj[2]

# 中心点x和y坐标以及检测对象点宽高

c_pos_x = pos[0]

c_pos_y = pos[1]

width = pos[2]

height = pos[3]

# 计算检测对象左上角和右下角x和y坐标

l_t_pos_x = int(c_pos_x - width / 2)

l_t_pos_y = int(c_pos_y - height / 2)

r_b_pos_x = int(c_pos_x + width / 2)

r_b_pos_y = int(c_pos_y + height / 2)

# 绘制检测目标框

target_img = cv.rectangle(d_img, (l_t_pos_x, l_t_pos_y), (r_b_pos_x, r_b_pos_y), (0, 255, 0), 2)

# 绘制分类对象和预测概率

target_img = cv.putText(target_img, "%s%f" % (class_name, prob), (l_t_pos_x, l_t_pos_y - 8)

, cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

return target_img

完整代码如下:

from ctypes import *

import cv2 as cv

class BOX(Structure):

_fields_ = [("x", c_float),

("y", c_float),

("w", c_float),

("h", c_float)]

class DETECTION(Structure):

_fields_ = [("bbox", BOX),

("classes", c_int),

("prob", POINTER(c_float)),

("mask", POINTER(c_float)),

("objectness", c_float),

("sort_class", c_int)]

class IMAGE(Structure):

_fields_ = [("w", c_int),

("h", c_int),

("c", c_int),

("data", POINTER(c_float))]

class METADATA(Structure):

_fields_ = [("classes", c_int),

("names", POINTER(c_char_p))]

lib = CDLL("./../libdarknet.so", RTLD_GLOBAL)

lib.network_width.argtypes = [c_void_p]

lib.network_width.restype = c_int

lib.network_height.argtypes = [c_void_p]

lib.network_height.restype = c_int

predict = lib.network_predict

predict.argtypes = [c_void_p, POINTER(c_float)]

predict.restype = POINTER(c_float)

set_gpu = lib.cuda_set_device

set_gpu.argtypes = [c_int]

make_image = lib.make_image

make_image.argtypes = [c_int, c_int, c_int]

make_image.restype = IMAGE

get_network_boxes = lib.get_network_boxes

get_network_boxes.argtypes = [c_void_p, c_int, c_int, c_float, c_float, POINTER(c_int), c_int, POINTER(c_int)]

get_network_boxes.restype = POINTER(DETECTION)

make_network_boxes = lib.make_network_boxes

make_network_boxes.argtypes = [c_void_p]

make_network_boxes.restype = POINTER(DETECTION)

free_detections = lib.free_detections

free_detections.argtypes = [POINTER(DETECTION), c_int]

free_ptrs = lib.free_ptrs

free_ptrs.argtypes = [POINTER(c_void_p), c_int]

network_predict = lib.network_predict

network_predict.argtypes = [c_void_p, POINTER(c_float)]

reset_rnn = lib.reset_rnn

reset_rnn.argtypes = [c_void_p]

load_net = lib.load_network

load_net.argtypes = [c_char_p, c_char_p, c_int]

load_net.restype = c_void_p

do_nms_obj = lib.do_nms_obj

do_nms_obj.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]

do_nms_sort = lib.do_nms_sort

do_nms_sort.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]

free_image = lib.free_image

free_image.argtypes = [IMAGE]

letterbox_image = lib.letterbox_image

letterbox_image.argtypes = [IMAGE, c_int, c_int]

letterbox_image.restype = IMAGE

load_meta = lib.get_metadata

lib.get_metadata.argtypes = [c_char_p]

lib.get_metadata.restype = METADATA

load_image = lib.load_image_color

load_image.argtypes = [c_char_p, c_int, c_int]

load_image.restype = IMAGE

rgbgr_image = lib.rgbgr_image

rgbgr_image.argtypes = [IMAGE]

predict_image = lib.network_predict_image

predict_image.argtypes = [c_void_p, IMAGE]

predict_image.restype = POINTER(c_float)

def detect(net, meta, image, thresh=.5, hier_thresh=.5, nms=.45):

im = load_image(image, 0, 0)

num = c_int(0)

pnum = pointer(num)

predict_image(net, im)

dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, None, 0, pnum)

num = pnum[0]

if nms:

do_nms_obj(dets, num, meta.classes, nms)

res = []

for j in range(num):

for i in range(meta.classes):

if dets[j].prob[i] > 0:

b = dets[j].bbox

res.append((meta.names[i], dets[j].prob[i], (b.x, b.y, b.w, b.h)))

res = sorted(res, key=lambda x: -x[1])

free_image(im)

free_detections(dets, num)

return res

def draw_boxes_and_label(img, result):

# 加载图像

d_img = cv.imread(img)

for i in range(len(result)):

# 解析检测单个对象

obj = result[i]

# 分类名称

class_name = str(obj[0], encoding="utf8")

# 预测概率

prob = obj[1]

# 中心点坐标

pos = obj[2]

# 中心点x和y坐标以及检测对象点宽高

c_pos_x = pos[0]

c_pos_y = pos[1]

width = pos[2]

height = pos[3]

# 计算检测对象左上角和右下角x和y坐标

l_t_pos_x = int(c_pos_x - width / 2)

l_t_pos_y = int(c_pos_y - height / 2)

r_b_pos_x = int(c_pos_x + width / 2)

r_b_pos_y = int(c_pos_y + height / 2)

# 绘制检测目标框

target_img = cv.rectangle(d_img, (l_t_pos_x, l_t_pos_y), (r_b_pos_x, r_b_pos_y), (0, 255, 0), 2)

# 绘制分类对象和预测概率

target_img = cv.putText(target_img, "%s%f" % (class_name, prob), (l_t_pos_x, l_t_pos_y - 8)

, cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

return target_img

if __name__ == "__main__":

# 指定文件

cfg_file = "../cfg/yolov3.cfg".encode("utf-8")

weights_file = "../weights/yolov3.weights".encode("utf-8")

meta_file = "../cfg/coco.data".encode("utf-8")

origin_img = "../data/dog.jpg"

# 加载模型进行检测

net = load_net(cfg_file, weights_file, 0)

meta = load_meta(meta_file)

r = detect(net, meta, origin_img.encode("utf-8"))

print(r)

# 绘制结果并显示

img_final = draw_boxes_and_label(origin_img, r)

cv.imshow("result", img_final)

cv.waitKey(0)

最终结果如下图:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值