我的目标是使用
drawBorderboxes()
通过摄像头直播(在 Pycharm 中)来检测对象。我的第 1 部分工作得很好。这是为了确保使用 pylon 进行视频直播。第 2 部分是我遇到的问题,关于通过传入图像对象而不是文件夹路径来调用模型。
我哪里出错了(虽然这段代码运行顺利)?
这是我当前的代码:
# Part 1:
logger = logging.getLogger()
tl_factory = pylon.TlFactory.GetInstance()
devices = tl_factory.EnumerateDevices()
if len(devices) == 0:
logger.info("No cameras found!")
exit()
top_camera = pylon.InstantCamera(tl_factory.CreateDevice(devices[0]))
top_camera.Open()
converter = pylon.ImageFormatConverter()
converter.OutputPixelFormat = pylon.PixelType_BGR8packed
converter.OutputBitAlignment = pylon.OutputBitAlignment_MsbAligned
top_camera.OutputQueueSize = 2
top_camera.StartGrabbing(pylon.GrabStrategy_LatestImages)
try:
counter = 0
while (True):
top_grabResult = top_camera.RetrieveResult(5000, pylon.TimeoutHandling_Return)
while not top_grabResult.GrabSucceeded():
logger.info("top grab failed, trying again")
top_grabResult = top_camera.RetrieveResult(5000, pylon.TimeoutHandling_Return)
if top_grabResult.GrabSucceeded():
image = converter.Convert(top_grabResult)
img = image.Array
img = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE)
original_h = img.shape[0]
original_w = img.shape[1]
new_h = (1088 / 720) * (original_w) # x/2160 = 1088/720 solve for x
offset = int(original_h - new_h)
img = img[offset:original_h, 0:original_w]
top_img = cv2.resize(img, (720, 1088))
# img = cv2.resize(img, (0, 0), fx=0.25, fy=0.25)
# cv2.namedWindow('esc_to_quit', cv2.WINDOW_AUTOSIZE)
# cv2.imshow('esc_to_quit', img)
# cv2.waitKey()
else:
logger.info(f"Top camera failed to grab an image")
top_img = np.zeros((1088, 720, 3))
top_img = cv2.resize(top_img, (0, 0), fx=0.5, fy=0.5)
concat_img = np.concatenate((top_img), axis=1)
cv2.namedWindow('esc_to_quit', cv2.WINDOW_AUTOSIZE)
cv2.imshow('esc_to_quit', top_img)
cv2.waitKey(1)
print(counter)
counter += 1
finally:
top_camera.Close()
####### Part 2: call the model by passing in an image object rather than a path to a folder ####
# Function to draw bounding boxes on the image
def drawBorderBoxes(classifiedItems, image):
for classifiedItem in classifiedItems:
xyxy = classifiedItem[0]
label = classifiedItem[1]
color = classifiedItem[2]
plot_one_box(xyxy, image, label=label, color=color)
# Function for live stream object detection
def detect_objects_live_stream(model, cam_feed):
obj_detect = ObjectDetection()
obj_detect.setModelTypeAsYOLOv5()
obj_detect.setModelPath(model)
obj_detect.loadModel()
while True:
ret, img = cam_feed.read()
if not ret:
print("Camera feed not available. Exiting...")
break
# Convert the OpenCV image to PIL Image
pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# Perform object detection
annotated_image, preds = obj_detect.detectObjectsFromImage(input_image=pil_image,
input_type="array",
output_type="array",
display_percentage_probability=False,
display_object_name=True)
# Draw bounding boxes on the image
drawBorderBoxes(preds, img)
# Display the annotated image
cv2.imshow("", img)
if (cv2.waitKey(1) & 0xFF == ord("q")) or (cv2.waitKey(1) == 27):
break
cam_feed.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--weights', nargs='+', type=str, default='weights/yolov5s.pt', help='model.pt path(s)')
parser.add_argument('--source', type=str, default='0', help='source') # file/folder, 0 for webcam
parser.add_argument('--output', type=str, default='inference/output', help='output folder') # output folder
parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
parser.add_argument('--conf-thres', type=float, default=0.5, help='object confidence threshold')
parser.add_argument('--iou-thres', type=float, default=0.5, help='IOU threshold for NMS')
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
parser.add_argument('--view-img', action='store_true', help='display results')
parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
parser.add_argument('--augment', action='store_true', help='augmented inference')
parser.add_argument('--update', action='store_true', help='update all models')
opt = parser.parse_args()
if not os.path.exists(opt.output):
os.mkdir(opt.output)
else:
shutil.rmtree(opt.output)
os.mkdir(opt.output)
with torch.no_grad():
if opt.update: # update all models (to fix SourceChangeWarning)
for opt.weights in ['yolov5s.pt', 'yolov5m.pt', 'yolov5l.pt', 'yolov5x.pt']:
detect(opt=opt)
strip_optimizer(opt.weights)
else:
detect(opt=opt)
# Create the YOLOv5 model
model = attempt_load(opt.weights, map_location=opt.device)
model.half() if opt.device != 'cpu' else None
# Start live stream object detection
cam_feed = cv2.VideoCapture(0) # Modify the source here for a different camera feed
detect_objects_live_stream(model, cam_feed)