KivyMD运行OpenCV摄像头代码报ctypes.ArgumentError类型错误如何解决
问题根因
触发ctypes.ArgumentError: argument 3: <class 'TypeError'>: wrong type报错的核心原因是代码存在参数拼写错误,附带存在一处API兼容问题:
- 核心拼写错误:调用
Texture.create()创建纹理时,误将参数名colorfmt错写为colorfat,导致Kivy纹理初始化时无法正确解析色彩格式参数,传入底层ctypes层的参数类型不匹配,直接抛出类型错误。 - 兼容问题:高版本OpenCV与NumPy中,数组的
tostring()方法已被标记为废弃,部分环境下该方法返回的缓冲区对象类型不符合Kivy纹理渲染的参数要求,也会触发同类报错。 - 潜在隐患:原代码未判断摄像头帧读取状态,摄像头初始化失败、被占用时读取到空帧会触发二次报错。
修复后完整可运行代码
from kivy.graphics.texture import Texture from kivymd.app import MDApp from kivymd.uix.boxlayout import MDBoxLayout from kivymd.uix.button import MDRaisedButton from kivy.uix.image import Image from kivy.clock import Clock import cv2 class MainApp(MDApp): def build(self): layout = MDBoxLayout(orientation='vertical') self.image = Image() layout.add_widget(self.image) layout.add_widget(MDRaisedButton( text='CLICK HERE', pos_hint={'center_x': .5, 'center_y': .5}, size_hint=(None, None)) ) self.capture = cv2.VideoCapture(0) Clock.schedule_interval(self.load_video, 1.0/30.0) return layout def load_video(self, *args): ret, frame = self.capture.read() # 空帧直接返回,避免无效渲染报错 if not ret: return self.image_frame = frame # 替换废弃API,获取正确格式的帧缓冲区 buffer = cv2.flip(frame, 0).tobytes() # 修正参数拼写错误,指定正确的色彩格式 texture = Texture.create(size=(frame.shape[1], frame.shape[0]), colorfmt='bgr') texture.blit_buffer(buffer, colorfmt='bgr', bufferfmt='ubyte') self.image.texture = texture if __name__ == '__main__': MainApp().run()
运行注意事项
- 运行前确认当前程序已获取设备摄像头权限,摄像头未被其他应用占用
- 若运行后画面出现红蓝通道错位的色彩异常,可将两处
colorfmt的参数值从bgr调整为rgb,适配当前环境下OpenCV输出的帧通道顺序 - 建议补充程序退出时的摄像头资源释放逻辑,调用
self.capture.release()避免摄像头被长期占用
内容的提问来源于stack exchange,提问作者rookie
相关产品推荐
相关产品推荐

