opencv调用ssd模型来用于物体检测

之前对ssd的整个原理已经了解了,对于整个网络走动的流程,loss的计算这些,已经心里有数了,那么接下来,要么去训练ssd模型,要么就去利用ssd去测试模型,这不,我们现在就学习一下利用opencv来使用ssd,在这之前,感谢一只稚嫩的小金毛提供的代码和模型,这位作者写的挺好的,但是我个人觉得还是有些地方没有讲清楚,比如模型预测后输出的每个值的含义,而且在筛选预测的边框的时候,我觉得还能再优化,所以,才有了这篇文章。

上面作者模型链接,大家可以拿去练手:链接:https://pan.baidu.com/s/1zvIw1rkRvYqk33xwyAMjhg
提取码:n90t

下面直接上代码,代码中,注释已经很清楚了。

'''author:nike hu'''
# 这是使用的模型中所对应的类型
objName = ["background",
"aeroplane", "bicycle", "bird", "boat",
"bottle", "bus", "car", "cat", "chair",
"cow", "diningtable", "dog", "horse",
"motorbike", "person", "pottedplant",
"sheep", "sofa", "train", "tvmonitor"]

def test(image, model, model_layer, thred=0.7):
    imageH = image.shape[0] # 输入照片的高
    imageW = image.shape[1] # 宽
    show_image = image # 这个用来显示图片
    model = cv2.dnn.readNetFromCaffe(model_layer, model)
    # 加载模型,第一个参数是网络的每一层的信息,第二个参数是训练好的模型,我们现在使用的是caffe训练的模型
    image = cv2.dnn.blobFromImage(image, 0.007843, (300, 300), (127.5, 127.5, 127.5), True, False)
    '''
    函数cv2.dnn.blobFromImage(image[, scalefactor[, size[, mean[, swapRB[, crop[, ddepth]]]]]])
作用:对图像进行预处理,包括减均值,比例缩放,裁剪,交换通道等,返回一个4通道的blob(blob可以简单理解为一个N维的数组,用于神经网络的输入)
参数:image:输入图像(1、3或者4通道)
    可选参数
    scalefactor:图像各通道数值的缩放比例
    size:输出图像的空间尺寸,如size=(200,300)表示高h=300,宽w=200
    mean:用于各通道减去的值,以降低光照的影响(e.g. image为bgr3通道的图像,mean=[104.0, 177.0, 123.0],表示b通道的值-104,g-177,r-123)
    swapRB:交换RB通道,默认为False.(cv2.imread读取的是彩图是bgr通道)
    crop:图像裁剪,默认为False.当值为True时,先按比例缩放,然后从中心裁剪成size尺寸
    ddepth:输出的图像深度,可选CV_32F 或者 CV_8U.
    总之,这个函数就是用来处理图片的,将图片的维度转化为神经网络需要的维度。
    '''
    model.setInput(image) # 感觉这一步就是将数据放到神经网络的输入层
    out = model.forward()
    # 神经网络向前推进,最后输出结果类似[1, 1, 100, 7],其中的100代表的是ssd中的预测框,7代表含义分别对应
    # 照片编号(这是是猜测,因为ssd预测的时候,如果输入多张图片,得标记一下),类别下标,类别预测可能性,x1,y1, x2, y2
    out = torch.from_numpy(out) # 转化为torch类型,方便后面筛选box
    score_id = out[:, :, :, 2] > thred # 将预测可能性大于阈值的标记为true
    pred_box = out[score_id].view(-1, 7) # 将预测的box找出来
    pred_num = pred_box.numpy() # 转化为numpy类型
    for box in pred_num:
        score = round(box[2], 2) # 保留小数点后两位
        class_id = int(box[1]) # 这里预测的类别数据为浮点型,转化一下
        x1 = int(box[3] * imageW) # 左上角的x坐标,注意转化为整形
        y1 = int(box[4] * imageH) # 左上角的y坐标
        x2 = int(box[5] * imageW) # 右下角的x坐标
        y2 = int(box[6] * imageH) # 右下角的y坐标
        cv2.rectangle(show_image, (x1, y1), (x2, y2), (0, 255, 255), 2) # 画边框
        str_show = str(score) + '  ' + objName[class_id]
        # 要做图像上写的字符,注意,opencv只能写上英文,输入中文,要迂回一下,有兴趣者看我相关文章,类别下标是从0开始的
        cv2.putText(show_image, str_show, (x1 + 15, y1 + 15), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2, 8)
        # 将英文字符串画在图上
    cv2.imshow('detect_image', show_image)
    cv2.waitKey()


if __name__ == '__main__':
    image = cv2.imread('images/1.jpg')
    if image.shape[1] > 1600:
        image = cv2.resize(image, None, fx=0.3, fy=0.3)
    model_path = 'ssd/MobileNetSSD_deploy.caffemodel'
    model_layer = 'ssd/MobileNetSSD_deploy.prototxt'
    test(image, model_path, model_layer)

最后输出效果如下:
在这里插入图片描述
总结一下,opencv提供的这个接口,还是很方便,至于准确率这些,就跟模型的训练程度有关了,也还跟ssd本身有关,毕竟现在ssd的优化版本也很多。我们如果要训练自己的数据,那么我们输入的模型就得变成我们自己训练的模型了,目前我没有发现opencv能训练ssd模型这些,只能使用ssd模型。所以我们还得学习怎么去训练自己的模型,而在训练自己模型的过程中,如何进行数据预处理,这一块我个人觉得是最麻烦的,后面我学了之后有空会写一篇。

2020 4.22

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用OpenCV调用YOLOv模型的步骤如下: 1. 下载并安装Darknet。在Darknet官网(https://github.com/pjreddie/darknet)上下载源代码,并进行编译和安装。 2. 下载YOLOv模型权重文件。在Darknet官网上下载YOLOv模型的权重文件,例如yolov3.weights。 3. 使用OpenCV读取图像文件或视频文件。使用OpenCV的cv::imread()函数读取图像文件,或使用cv::VideoCapture类读取视频文件。 4. 加载YOLOv模型和权重文件。使用OpenCV的dnn::readNetFromDarknet()函数加载YOLOv模型的配置文件和权重文件。 ```python model_cfg = "path/to/yolov3.cfg" model_weights = "path/to/yolov3.weights" net = cv2.dnn.readNetFromDarknet(model_cfg, model_weights) ``` 5. 预处理图像。将图像缩放到模型需要的大小,并对图像进行归一化处理。 ```python blob = cv2.dnn.blobFromImage(image, 1/255.0, (416, 416), swapRB=True, crop=False) ``` 6. 将图像输入到模型中进行推理。使用OpenCV的dnn::Net类的forward()函数进行推理,并获取模型输出。 ```python net.setInput(blob) outputs = net.forward() ``` 7. 处理模型输出。对模型输出进行解析和后处理,获取目标检测结果。 ```python for output in outputs: for detection in output: scores = detection[5:] class_id = np.argmax(scores) confidence = scores[class_id] if confidence > 0.5: center_x = int(detection[0] * width) center_y = int(detection[1] * height) w = int(detection[2] * width) h = int(detection[3] * height) x = int(center_x - w/2) y = int(center_y - h/2) cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2) ``` 8. 显示图像。使用OpenCV的cv::imshow()函数显示图像,并使用cv::waitKey()函数等待键盘输入。 ```python cv2.imshow("Output", image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 以上就是使用OpenCV调用YOLOv模型的基本步骤,希望对你有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值