我正试图在Google上使用Yolov4微小和黑暗的框架来处理图像。代码在我的本地MAC (2021年,M1)上工作得很好,但是在Colab,我得到了一个错误。
非常感谢您的帮助!
!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
---------------------------------------------------------------------------
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发布于 2022-07-19 09:02:35
tl;dr:请将您的get_output_layers_name()函数替换为一个简单的:
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。
再次,请避免所有的混乱,并使用上述简化的代码!
https://stackoverflow.com/questions/73031507
复制相似问题