You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派环境下Python OpenCV如何点击窗口“X”按钮关闭窗口?

解决树莓派OpenCV摄像头流窗口点击关闭按钮退出问题

核心原理

OpenCV默认不会监听窗口右上角关闭按钮的点击事件,需要主动获取窗口的可见性属性判断用户是否点击了关闭按钮。树莓派环境下需要提前创建命名窗口,才能正确读取窗口属性。

所需修改的代码点

  • 初始化摄像头后,提前创建命名窗口,和后续imshow的窗口名称保持一致
  • 每次循环渲染后,同时监听键盘按下事件和窗口可见性属性,任意一个满足条件就退出循环
  • 如果你使用的是OpenCV 3.x版本(树莓派官方源默认安装的版本通常为3.x),如果cv2.WND_PROP_VISIBLE报错,可以替换为cv2.CV_WND_PROP_VISIBLE

修改后的完整代码

import cv2
import numpy as np
import matplotlib.pyplot as plt

net = cv2.dnn.readNetFromDarknet("custom-yolov4-tiny-detector.cfg","custom-yolov4-tiny-detector_best.weights")

classes = ['apple','orange','yogurt']

cap = cv2.VideoCapture(0)
# 提前创建命名窗口
cv2.namedWindow('Cuisine Vision')

while 1:
    _, img = cap.read()
    img = cv2.resize(img,(790,450))
    hight,width,_ = img.shape
    blob = cv2.dnn.blobFromImage(img, 1/255,(416,416),(0,0,0),swapRB = True,crop= False)

    net.setInput(blob)

    output_layers_name = net.getUnconnectedOutLayersNames()

    layerOutputs = net.forward(output_layers_name)

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

    for output in layerOutputs:
        for detection in output:
            score = detection[5:]
            class_id = np.argmax(score)
            confidence = score[class_id]
            if confidence > 0.7:
                center_x = int(detection[0] * width)
                center_y = int(detection[1] * hight)
                w = int(detection[2] * width)
                h = int(detection[3]* hight)
                x = int(center_x - w/2)
                y = int(center_y - h/2)
                boxes.append([x,y,w,h])
                confidences.append((float(confidence)))
                class_ids.append(class_id)


    indexes = cv2.dnn.NMSBoxes(boxes,confidences,.5,.4)

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

    for output in layerOutputs:
        for detection in output:
            score = detection[5:]
            class_id = np.argmax(score)
            confidence = score[class_id]
            if confidence > 0.5:
                center_x = int(detection[0] * width)
                center_y = int(detection[1] * hight)
                w = int(detection[2] * width)
                h = int(detection[3]* hight)

                x = int(center_x - w/2)
                y = int(center_y - h/2)



                boxes.append([x,y,w,h])
                confidences.append((float(confidence)))
                class_ids.append(class_id)

    indexes = cv2.dnn.NMSBoxes(boxes,confidences,.8,.4)
    font = cv2.FONT_HERSHEY_PLAIN
    colors = np.random.uniform(0,255,size =(len(boxes),3))
    if  len(indexes)>0:
        for i in indexes.flatten():
            x,y,w,h = boxes[i]
            label = str(classes[class_ids[i]])
            color = colors[i]
            cv2.rectangle(img,(x,y),(x+w,y+h),color,2)
            cv2.putText(img,label + " " + "", (x,y+200),font,2,color,2)

    cv2.imshow('Cuisine Vision',img)
    # 同时监听q键按下和窗口关闭事件
    key = cv2.waitKey(1)
    if key == ord('q') or cv2.getWindowProperty('Cuisine Vision', cv2.WND_PROP_VISIBLE) < 1:
        break
    
cap.release()
cv2.destroyAllWindows()

注意事项

  • 必须保证namedWindow的窗口名称和imshow的窗口名称完全一致,否则无法正确读取窗口属性
  • 如果出现属性未定义的报错,将cv2.WND_PROP_VISIBLE替换为cv2.CV_WND_PROP_VISIBLE即可适配低版本OpenCV

内容的提问来源于stack exchange,提问作者Div

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 13:54:03