提问人:Kacper Masny 提问时间:11/17/2023 最后编辑:Christoph RackwitzKacper Masny 更新时间:11/19/2023 访问量:26
如何在 Kivy 中将相机小部件添加到屏幕?
How to add a Camera widget to a Screen in Kivy?
问:
我想构建一个具有人脸识别验证功能的密码管理器应用程序。我使用 Kivy 作为 GUI。 我想创建一个带有摄像头的屏幕,我可以在其中捕获某人的脸部以保存它,并创建另一个用于验证。我希望能够从其他屏幕呼叫他们。
class CameraWindow(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = BoxLayout(orientation='vertical')
self.camera = Camera(play=False)
layout.add_widget(self.camera)
layout.add_widget(ToggleButton(text='Play', on_press=self.play))
layout.add_widget(Button(text='Capture', on_release=self.capture))
self.add_widget(layout)
每次运行程序时,我都会收到错误。
[ WARN:[email protected]] global cap_v4l.cpp:982 open VIDEOIO(V4L2:/dev/video0): can't open camera by index
[ERROR:[email protected]] global obsensor_uvc_stream_channel.cpp:156 getStreamChannelGroup Camera index out of range
Traceback (most recent call last):
File "/home/kacper/Documents/password_manager/password_manager/main.py", line 114, in <module>
PasswordApp().run()
File "/home/kacper/Documents/password_manager/.venv/lib/python3.10/site-packages/kivy/app.py", line 955, in run
self._run_prepare()
File "/home/kacper/Documents/password_manager/.venv/lib/python3.10/site-packages/kivy/app.py", line 925, in _run_prepare
root = self.build()
File "/home/kacper/Documents/password_manager/password_manager/main.py", line 105, in build
sm.add_widget(CameraWindow(name='camerawindow'))
File "/home/kacper/Documents/password_manager/password_manager/main.py", line 60, in __init__
self.camera = Camera(play=False)
File "/home/kacper/Documents/password_manager/.venv/lib/python3.10/site-packages/kivy/uix/camera.py", line 91, in __init__
on_index()
File "/home/kacper/Documents/password_manager/.venv/lib/python3.10/site-packages/kivy/uix/camera.py", line 103, in _on_index
self._camera = CoreCamera(index=self.index, stopped=True)
File "/home/kacper/Documents/password_manager/.venv/lib/python3.10/site-packages/kivy/core/camera/camera_opencv.py", line 70, in __init__
super(CameraOpenCV, self).__init__(**kwargs)
File "/home/kacper/Documents/password_manager/.venv/lib/python3.10/site-packages/kivy/core/camera/__init__.py", line 70, in __init__
self.init_camera()
File "/home/kacper/Documents/password_manager/.venv/lib/python3.10/site-packages/kivy/core/camera/camera_opencv.py", line 120, in init_camera
self._resolution = (int(frame.shape[1]), int(frame.shape[0]))
AttributeError: 'NoneType' object has no attribute 'shape'
不知道我是否应该发布错误消息的中间,对不起,如果它是错误的,我会在需要时发布它。
我的整个代码:
main.py
import time
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.camera import Camera
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.textinput import TextInput
# kv = Builder.load_file('my.kv')
class LogInWindow(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = BoxLayout(orientation='vertical')
self.username_input = TextInput(text='Username')
self.password_input = TextInput(text='Password', password=True)
layout.add_widget(self.username_input)
layout.add_widget(self.password_input)
layout.add_widget(Button(text='Login', on_release=self.login))
layout.add_widget(Button(text='Register', on_release=self.go_to_register))
layout.add_widget(Button(text='Exit', on_release=App.get_running_app().stop))
self.add_widget(layout)
def login(self, instance):
username = self.username_input.text
password = self.password_input.text
if username == 'admin' and password == 'admin':
self.go_to_camera(instance)
def go_to_camera(self, instance):
self.manager.current = 'camerawindow'
def go_to_register(self, instance):
self.manager.current = 'register'
class RegisterWindow(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = BoxLayout(orientation='vertical')
layout.add_widget(Button(text='Scan your face', on_release=self.go_to_camera))
layout.add_widget(Button(text='Back', on_release=self.go_to_login))
self.add_widget(layout)
def go_to_camera(self, instance):
self.manager.current = 'camerawindow'
def go_to_login(self, instance):
self.manager.current = 'login'
class CameraWindow(Screen):
pass
# def __init__(self, **kwargs):
# super().__init__(**kwargs)
# layout = BoxLayout(orientation='vertical')
# self.camera = Camera(play=False)
# layout.add_widget(self.camera)
# layout.add_widget(ToggleButton(text='Play', on_press=self.play))
# layout.add_widget(Button(text='Capture', on_release=self.capture))
# layout.add_widget(Button(text='Recognize Face', on_release=self.recognize_face))
# self.add_widget(layout)
class PasswordListWindow(Screen):
pass
class PasswordEntryWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
class PasswordApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(LogInWindow(name='login'))
sm.add_widget(RegisterWindow(name='register'))
sm.add_widget(CameraWindow(name='camerawindow'))
sm.add_widget(PasswordListWindow(name='list'))
sm.add_widget(PasswordEntryWindow(name='entry'))
return sm
if __name__ == '__main__':
PasswordApp().run()
密码.kv
WindowManager:
LogInWindow:
RegisterWindow:
CameraWindow:
PasswordListWindow:
PasswordEntryWindow:
<LogInWindow>:
name: 'login'
BoxLayout:
orientation: 'vertical'
size: root.width, root.height
Label:
text: 'Login'
font_site: 32
Button:
text: 'Login'
on_press: root.manager.current = 'list'
Button:
text: 'Register'
on_press: root.manager.current = 'register'
Button:
text: 'Quit'
<RegisterWindow>:
name: 'register'
BoxLayout:
Button:
text: 'Goto settings'
on_press: root.manager.current = 'settings'
Button:
text: 'Quit'
<<CameraWindow>:
name: 'camerawindow'
BoxLayout:
orientation: 'vertical'
Camera:
id: camera
Button:
text: 'Back'
on_release: root.manager.current = 'login'
<PasswordListWindow>:
name: 'list'
BoxLayout:
Button:
text: 'Goto settings'
on_press: root.manager.current = 'login'
Button:
text: 'Quit'
<PasswordEntryWindow>:
name: 'entry'
BoxLayout:
Button:
text: 'Goto settings'
on_press: root.manager.current = 'list'
Button:
text: 'Quit'
我尝试了来自 opencv 的简单相机调用,它按预期工作。我看到我的相机弹出。
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
cv2.imshow('frame', frame)
if cv2.waitKey(1) == ord('q'):
break
cap.release()
cv2.destroyAllWindows
我尝试了文档 https://kivy.org/doc/stable/examples/gen__camera__main__py.html 中的相机示例,它工作得很好,但它是由应用程序直接调用的类,这不是我想要的。我尝试将其重新加工成屏幕,但它停止工作:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
import time
class Screen1(Screen):
def capture(self):
'''
Function to capture the images and give them the names
according to their captured time and date.
'''
camera = self.ids['camera']
timestr = time.strftime("%Y%m%d_%H%M%S")
camera.export_to_png("IMG_{}.png".format(timestr))
print("Captured")
class WindowManager(ScreenManager):
pass
Builder.load_string('''
ScreenManager:
Screen1:
<Screen1>:
name: 'screen1'
BoxLayout:
orientation: 'vertical'
Camera:
id: camera
resolution: (640, 480)
play: False
ToggleButton:
text: 'Play'
on_press: camera.play = not camera.play
size_hint_y: None
height: '48dp'
Button:
text: 'Capture'
size_hint_y: None
height: '48dp'
on_press: root.capture()
''')
class TestCamera(App):
def build(self):
sm=ScreenManager()
sm.add_widget(Screen1(name='screen1'))
return sm
if __name__ == '__main__':
TestCamera().run()
在上面的示例中,我尝试在创建 Screen1 之前和之后调用它,但根本没有调用它。在 Screen1 之后使用 builder,我收到与上面相同的错误,在 Screen1 之前使用 builder,我收到“未知类错误”,没有构建器,我得到黑屏。Builder
我尝试过的其他事情。
我试着在课外打电话,程序运行了,但我显然没有在屏幕上看到摄像头。cam = Camera()
我尝试了一个空白的 CameraWindow 类和
<<CameraWindow>:
name: 'camerawindow'
BoxLayout:
orientation: 'vertical'
Camera:
id: camera
Button:
text: 'Back'
on_release: root.manager.current = 'login'
在 .kv 文件中,如上面文档中的示例所示。程序启动,但当我导航到 CameraWindow 时,出现黑屏。
我尝试在我的 .kv 中只留下名称:指定。- AttributeError:“NoneType”对象没有属性“shape”<CameraWindow>
我试过两者兼而有之。- AttributeError:“NoneType”对象没有属性“shape”
答: 暂无答案
评论