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

KivyMD中WebCamScreen无法显示OpenCV摄像头实时画面求助

问题:摄像头启动但画面未在WebCamScreen显示

我创建了WebCamScreen,通过OpenCV编写了启动摄像头和读取实时画面的两个函数,运行代码时摄像头已启动,但画面未在应用屏幕显示。

以下是main.py文件的代码:

class WebCamScreen(Screen):

    def do_start(self):
        self.capture = cv2.VideoCapture(0)
        Clock.schedule_interval(self.load_video, 1.0 / 24.0)

    def load_video(self, *args):
        ret, frame = self.capture.read()
        # self.image_frame = frame
        buffer = cv2.flip(frame, 0).tostring()
        image_texture = Texture.create(size=(frame.shape[1], frame.shape[0]), colorfmt="bgr")
        image_texture.blit_buffer(buffer, colorfmt="bgr", bufferfmt="ubyte")
        self.texture = image_texture


class MainApp(MDApp):

def build(self):
    screen_manger = ScreenManager()
    screen_manger.add_widget(LoginScreen(name="login"))
    screen_manger.add_widget(RegistrationScreen(name="registration"))
    screen_manger.add_widget(HomeScreen(name="home"))
    screen_manger.add_widget(WebCamScreen(name="camera"))

    return screen_manger
if __name__ == "__main__":
    MainApp().run()

以及.kv文件的代码:

<WebCamScreen>
MDBoxLayout:
    MDRaisedButton:
        text: "Start Camera"
        size_hint_x: None
        size_hint_y: None
        md_bg_color: "orange"
        pos_hint: {"center_x": 0.2, "center_y": 0.5}
        on_press:
            root.do_start()

请问如何在该WebCamScreen上显示摄像头的实时画面?


解决方案

问题核心在于缺少显示画面的UI控件,以及未处理帧读取失败的情况,按以下修改即可实现实时画面显示:

1. 补充KV布局的显示控件

在WebCamScreen的布局中添加Image控件,用来绑定OpenCV生成的纹理,同时调整布局结构让按钮和画面共存:

修改后的.kv代码:

<WebCamScreen>
    MDBoxLayout:
        orientation: "vertical"
        padding: 20
        spacing: 20

        # 新增的摄像头画面显示控件
        Image:
            id: camera_image
            size_hint_y: 0.8
            allow_stretch: True  # 允许画面拉伸适配控件尺寸

        MDRaisedButton:
            text: "Start Camera"
            size_hint_x: None
            size_hint_y: None
            md_bg_color: "orange"
            pos_hint: {"center_x": 0.5}
            on_press:
                root.do_start()

2. 优化Python代码逻辑

  • 添加帧读取成功的判断,避免读取失败报错
  • 只在启动时创建一次Texture,后续仅更新缓冲区,提升性能
  • 将生成的纹理绑定到KV中定义的Image控件

修改后的main.py代码:

from kivy.clock import Clock
from kivy.graphics.texture import Texture
from kivy.uix.screenmanager import Screen
from kivymd.app import MDApp
import cv2

class WebCamScreen(Screen):

    def do_start(self):
        self.capture = cv2.VideoCapture(0)
        # 先读取一帧确认尺寸,仅创建一次Texture
        ret, frame = self.capture.read()
        if ret:
            self.image_texture = Texture.create(size=(frame.shape[1], frame.shape[0]), colorfmt="bgr")
            Clock.schedule_interval(self.load_video, 1.0 / 24.0)

    def load_video(self, *args):
        ret, frame = self.capture.read()
        if not ret:
            return  # 读取失败直接返回,避免报错
        buffer = cv2.flip(frame, 0).tostring()
        self.image_texture.blit_buffer(buffer, colorfmt="bgr", bufferfmt="ubyte")
        # 将纹理绑定到KV中的Image控件
        self.ids.camera_image.texture = self.image_texture

class MainApp(MDApp):
    def build(self):
        from kivy.uix.screenmanager import ScreenManager
        # 确保LoginScreen、RegistrationScreen、HomeScreen已正确定义
        screen_manger = ScreenManager()
        screen_manger.add_widget(LoginScreen(name="login"))
        screen_manger.add_widget(RegistrationScreen(name="registration"))
        screen_manger.add_widget(HomeScreen(name="home"))
        screen_manger.add_widget(WebCamScreen(name="camera"))
        return screen_manger

if __name__ == "__main__":
    MainApp().run()

修改完成后,点击"Start Camera"按钮,摄像头启动后会实时在Image控件中显示画面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 07:01:54