首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Yolov4 Yolov4和Darknet及Colab导致错误

Yolov4 Yolov4和Darknet及Colab导致错误
EN

Stack Overflow用户
提问于 2022-07-19 05:24:07
回答 1查看 208关注 0票数 0

我正试图在Google上使用Yolov4微小和黑暗的框架来处理图像。代码在我的本地MAC (2021年,M1)上工作得很好,但是在Colab,我得到了一个错误。

非常感谢您的帮助!

代码语言:javascript
复制
!rm darknet
# clone darknet repo
!git clone https://github.com/AlexeyAB/darknet
# change makefile to have GPU and OPENCV enabled
%cd darknet
!wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-tiny.weights
!sed -i 's/OPENCV=0/OPENCV=1/' Makefile
!sed -i 's/GPU=0/GPU=1/' Makefile
!sed -i 's/CUDNN=0/CUDNN=1/' Makefile
!sed -i 's/CUDNN_HALF=0/CUDNN_HALF=1/' Makefile

!make


model_config='/content/darknet/cfg/yolov4-tiny.cfg'
model_names='/content/darknet/cfg/coco.names'
model_weights='/content/darknet/yolov4-tiny.weights'

import cv2
import numpy as np
    
class YoloDetection():
    def __init__(self, model_path: str, config: str, classes: str, width: int, height: int,
             scale=0.00392, thr=0.4, nms=0.4, backend=0,
             framework=3,
             target=0, mean=[0, 0, 0]):
    
        super(YoloDetection,self).__init__()
        choices = ['caffe', 'tensorflow', 'torch', 'darknet']
        backends = (
        cv2.dnn.DNN_BACKEND_DEFAULT, cv2.dnn.DNN_BACKEND_HALIDE, cv2.dnn.DNN_BACKEND_INFERENCE_ENGINE,
        cv2.dnn.DNN_BACKEND_OPENCV)
        targets = (
        cv2.dnn.DNN_TARGET_CPU, cv2.dnn.DNN_TARGET_OPENCL, cv2.dnn.DNN_TARGET_OPENCL_FP16, cv2.dnn.DNN_TARGET_MYRIAD)

        self.__confThreshold = thr
        self.__nmsThreshold = nms
        self.__mean = mean
        self.__scale = scale
        self.__width = width
        self.__height = height

        # Load a network
        self.__net = cv2.dnn.readNet(model_path, config, choices[framework])
        self.__net.setPreferableBackend(backends[backend])
        self.__net.setPreferableTarget(targets[target])
        self.__classes = None

        if classes:
            with open(classes, 'rt') as f:
                self.__classes = f.read().rstrip('\n').split('\n')


    def get_output_layers_name(self, net):
        all_layers_names = net.getLayerNames()
        return [all_layers_names[i-1] for i in net.getUnconnectedOutLayers()]

    def post_process_output(self, frame, outs):
        frame_height = frame.shape[0]
        frame_width = frame.shape[1]

        class_ids = []
        confidences = []
        boxes = []

        class_ids = []
        confidences = []
        boxes = []
        for out in outs:
            for detection in out:
                scores = detection[5:]
                class_id = np.argmax(scores)
                confidence = scores[class_id]
                if confidence > self.__confThreshold:
                    center_x = int(detection[0] * frame_width)
                    center_y = int(detection[1] * frame_height)
                    width = int(detection[2] * frame_width)
                    height = int(detection[3] * frame_height)
                    left = center_x - width / 2
                    top = center_y - height / 2
                    class_ids.append(class_id)
                    confidences.append(float(confidence))
                    boxes.append([left, top, width, height])

    
        indices = cv2.dnn.NMSBoxes(boxes, confidences, self.__confThreshold, self.__nmsThreshold)
        return (indices, boxes, confidences, class_ids)

    def process_frame(self, frame: np.ndarray):
        frame_height = frame.shape[0]
        frame_width = frame.shape[1]

        blob = cv2.dnn.blobFromImage(frame, self.__scale, (self.__width, self.__height), self.__mean, True, crop=False)

        # Run a model
        self.__net.setInput(blob)
        outs = self.__net.forward(self.get_output_layers_name(self.__net))
        (indices, boxes, confidences, class_ids) = self.post_process_output(frame, outs)
        detected_objects = []

        for i in indices:
        
            box = boxes[i]
            left = box[0]
            top = box[1]
            width = box[2]
            height = box[3]
            x = int(left)
            y = int(top)
            nw = int(width)
            nh = int(height)
            if x < 0:
                x = 0
            if y < 0:
                y = 0
            if x + nw > frame_width:
                nw = frame_width - x
            if y + nh > frame_height:
                nh = frame_height - y
            detected_objects.append([self.__classes[class_ids[i]], x, y, nw, nh, confidences[i]])
        return detected_objects


model = YoloDetection(model_weights,
                  model_config,
                  model_names,
                  416,
                  416)

!wget https://image.stern.de/8424922/t/8I/v2/w1440/r0/-/30--artikel22517bild01jpg---b5e7066e38d38876.jpg
pic = cv2.imread('/content/darknet/30--artikel22517bild01jpg---b5e7066e38d38876.jpg', 0) 
model.process_frame(pic)

此代码的结果是:“TypeError:只能将整数标量数组转换为标量索引”

https://colab.research.google.com/drive/1ozyHkg3CVyzDqmO7gHYsNZ6TdWmlYMUQ?usp=sharing

代码语言:javascript
复制
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-d75e91783e3e> in <module>()
    130 get_ipython().system('wget https://image.stern.de/8424922/t/8I/v2/w1440/r0/-/30--artikel22517bild01jpg---b5e7066e38d38876.jpg')
    131 pic = cv2.imread('/content/darknet/30--artikel22517bild01jpg---b5e7066e38d38876.jpg', 0)
--> 132 model.process_frame(pic)

2 frames
<ipython-input-1-d75e91783e3e> in process_frame(self, frame)
 95         # Run a model
 96         self.__net.setInput(blob)
---> 97         outs = self.__net.forward(self.get_output_layers_name(self.__net))
 98         (indices, boxes, confidences, class_ids) = self.post_process_output(frame, outs)
 99         detected_objects = []

<ipython-input-1-d75e91783e3e> in get_output_layers_name(self, net)
 54     def get_output_layers_name(self, net):
 55         all_layers_names = net.getLayerNames()
---> 56         return [all_layers_names[i-1] for i in net.getUnconnectedOutLayers()]
 57 
 58     def post_process_output(self, frame, outs):

<ipython-input-1-d75e91783e3e> in <listcomp>(.0)
 54     def get_output_layers_name(self, net):
 55         all_layers_names = net.getLayerNames()
---> 56         return [all_layers_names[i-1] for i in net.getUnconnectedOutLayers()]
 57 
 58     def post_process_output(self, frame, outs):

TypeError: only integer scalar arrays can be converted to a scalar index
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-19 09:02:35

tl;dr:请将您的get_output_layers_name()函数替换为一个简单的:

代码语言:javascript
复制
def get_output_layers_name(self, net):
    return net.getUnconnectedOutLayersNames()

opencv的用于std::vector的python最近发生了变化,过去增加了一个人工维度,但现在没有了,所以

---> 56 return [all_layers_names[i-1] for i in net.getUnconnectedOutLayers()]

适用于4.5之后的版本,而

---> 56 return [all_layers_names[0][i-1] for i in net.getUnconnectedOutLayers()]

在此之前。(您似乎是在colab上运行它,默认情况下,colab已经过时了4.1.0。

再次,请避免所有的混乱,并使用上述简化的代码!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73031507

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档