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

Tkinter窗口无法显示OpenCV摄像头画面,热插拔摄像头未被检测

解决摄像头热插拔检测问题

Hey there, let's break down why your code isn't picking up the camera after plugging it in post-launch, and fix it step by step.

What's Going Wrong

Your current code initializes cv2.VideoCapture(0) right at the start. If there's no camera connected then, this capture object becomes permanently invalid. Even when you plug in the camera later, cap.read() just keeps trying to pull frames from that dead object—so it never detects the new camera connection.

The Fix

We need to retry initializing the VideoCapture object every time we fail to read a frame, instead of sticking with the first (invalid) instance. Here's how to implement that:

Modified Full Code

from tkinter import *
import cv2
from PIL import Image, ImageTk

print("[INFO] Imports done")
width, height = 800, 600
RootGeometry = f"{width}x{height}"
print("[INFO] Geometries made")

# Don't initialize cap upfront—we'll create it on demand
cap = None

root = Tk()
print("[INFO] Window made")
root.title("Main Window")
root.configure(background="white")
root.geometry(RootGeometry)
root.bind('<Escape>', lambda e: root.quit())
lmain = Label(root)
lmain.pack()
print("[INFO] Configuration done.")

def ShowFrame(frame):
    cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
    img = Image.fromarray(cv2image)
    imgtk = ImageTk.PhotoImage(image=img)
    lmain.imgtk = imgtk
    lmain.configure(image=imgtk)
    lmain.after(10, CheckSource)

def CheckSource():
    global cap
    print("[INFO] CheckSource Triggered.")
    
    # If cap isn't initialized or isn't open, try to connect to camera
    if cap is None or not cap.isOpened():
        print("[INFO] Attempting to connect to camera...")
        cap = cv2.VideoCapture(0)
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
    
    ok, frame = cap.read()
    if ok:
        print("[INFO] Camera detected! Showing feed.")
        ShowFrame(frame)
    else:
        print("[WARNING] No camera found. Retrying in 1 second...")
        # Release the dead capture object and reset it for next attempt
        if cap is not None:
            cap.release()
        cap = None
        lmain.after(1000, CheckSource)  # Slow down retries to reduce log spam

CheckSource()
root.mainloop()

# Cleanup when exiting
if cap is not None:
    cap.release()

Key Changes Explained

  • Lazy Camera Initialization: We no longer create the cap object at launch—we only create it when we need to check for a camera.
  • Status Check Before Reading: Every time CheckSource runs, it verifies if cap is actually open and usable. If not, it creates a new capture instance.
  • Reset On Failure: When reading fails, we release the invalid cap and set it to None, so the next loop will try connecting again. I also bumped the retry delay to 1 second to stop log output from flooding your console.
  • Remove Redundant cv2 Event Handling: Tkinter's mainloop already handles window events, so cv2.waitKey was unnecessary and could cause lag.

With these changes, your program will automatically detect the camera when you plug it in after launching, and start displaying the feed right away.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:07:14