這是我第一次在這里提問,所以請耐心等待。我正在嘗試使用 opencv 和 kivy 制作相機應用程式。我設法做到了,但我的問題是即使它不在正確的螢屏上,也會立即呼叫相機。我懷疑這是因為我在 KivyCamera 中的init類,但我不知道任何其他方法可以做到這一點。我想要的是相機只會在按下按鈕后初始化。
這是我的主要應用程式
from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.list import OneLineIconListItem, IconLeftWidget
from kivymd.uix.list import OneLineListItem, MDList
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.scrollview import ScrollView
from kivy.uix.image import Image
from kivy.clock import Clock
from kivy.graphics.texture import Texture
import cv2
import random
import string
class OneLine(OneLineListItem):
pass
class Scr(ScrollView):
pass
class list(MDList):
pass
class MenuScreen(Screen):
pass
class CamScreen(Screen):
# def show_cam(self):
# self.capture = cv2.VideoCapture(0)
def on_stop(self):
self.capture.release()
class SecondScreen(Screen):
# def mama(self):
# for i in range(20):
# self.parent.parent.ids.container.add_widget(
# OneLineListItem(text=f"Single-line item {i}")
# )
def on_released(self):
# items=
# self.add_widget()
for i in range(20):
list = OneLine(text=f"dsafsd {i}", on_release= lambda list: print(list.text))
list.text = f"dsafsd {i}"
# list.bind(on_release=lambda btn: self.dropdown.select(list.text))
self.ids['container'].add_widget(list)
# pass
class KivyCamera(Image):
def __init__(self, capture = cv2.VideoCapture(0), fps=30, **kwargs):
super(KivyCamera, self).__init__(**kwargs)
self.capture = capture
Clock.schedule_interval(self.update, 1.0/fps)
def update(self, dt):
ret, frame = self.capture.read()
if ret:
buf1 = cv2.flip(frame, 0)
buf = buf1.tostring()
image_texture =Texture.create(
size = (frame.shape[1], frame.shape[0]), colorfmt='bgr'
)
image_texture.blit_buffer(buf, colorfmt='bgr', bufferfmt='ubyte')
self.texture = image_texture
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(SecondScreen(name='second'))
sm.add_widget(CamScreen(name='cam'))
class Test(MDApp):
def on_start(self):
size= 0.5,0.5
# self.help.get_screen('cam').ids['cam'].add_widget(KivyCamera(size_hint = size, pos_hint = {"x":0.1,"top":1}))
for i in range(20):
self.help.get_screen('second').ids['container'].add_widget(
OneLineListItem(text=f"Single-line item {i}")
)
letters = string.ascii_lowercase
random = random.choice(letters)
def build(self):
screen = Screen()
self.help = Builder.load_file('tes.kv')
screen.add_widget(self.help)
return screen
Test().run()
這是 kv 檔案
ScreenManager:
MenuScreen:
SecondScreen:
CamScreen:
<MenuScreen>:
name: 'menu'
MDRectangleFlatButton:
text: 'to second'
pos_hint: {'center_x':0.1,'center_y':0.2}
on_press:
root.manager.current = 'second'
MDRectangleFlatButton:
text: 'to cam'
pos_hint: {'center_x':0.1,'center_y':0.9}
on_press:
root.manager.current = 'cam'
MDLabel:
id:our_label
text: " "
pos_hint: {'center_x':0.5,'center_y':0.2}
# on_parent:
# app.samie()
<SecondScreen>:
name: 'second'
MDBoxLayout:
orientaion: 'vertical'
MDRectangleFlatButton:
text: 'to menu'
pos_hint: {'center_x':0.1,'center_y':0.95}
on_press:
root.manager.current = 'menu'
# on_press:
# app.please()
# ScrollView:
# root.on_released()
# list.text = list.text "bobo"
# root.manager.current = 'menu'
# for i in range(4): print(f"bobo {i}")
ScrollView:
MDList:
id:container
# on_parent:
# app.please()
<CamScreen>:
name: 'cam'
BoxLayout:
orientation: 'vertical'
KivyCamera:
id: cam
size_hint: 0.5,0.5
pos_hint: {"x":0.1,"top":1}
MDRectangleFlatButton:
text: 'show camera'
pos_hint: {'center_x':0.1,'center_y':0.9}
# on_parent:
# app.show_cam()
謝謝!我真的認為我只需要擺脫init但我不知道任何替代方法
uj5u.com熱心網友回復:
您可以使用 的on_enter()方法觸發相機更新Screen。嘗試將__init__()方法更改KivyCamera為:
class KivyCamera(Image):
def __init__(self, capture=cv2.VideoCapture(0), fps=30, **kwargs):
super(KivyCamera, self).__init__(**kwargs)
self.capture = capture
self.fps = fps
# Clock.schedule_interval(self.update, 1.0 / fps)
并添加on_enter()和on_leave()方法到CamScreen:
class CamScreen(Screen):
# def show_cam(self):
# self.capture = cv2.VideoCapture(0)
def on_stop(self):
self.capture.release()
def on_enter(self, *args):
cam = self.ids.cam
self.clock_event = Clock.schedule_interval(cam.update, 1.0 / cam.fps)
def on_leave(self, *args):
self.clock_event.cancel()
在一個不相關的注釋中,這些行:
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(SecondScreen(name='second'))
sm.add_widget(CamScreen(name='cam'))
正在構建您的根App,但從未使用過。這些線可以消除。
線路:
self.help = Builder.load_file('tes.kv')
也在構建相同的根,除非有某種理由創建另一個Screen包含該根,否則您可以將build()方法簡化為:
def build(self):
self.help = Builder.load_file('tes.kv')
return self.help
uj5u.com熱心網友回復:
def __init__(self, capture = cv2.VideoCapture(0), fps=30, **kwargs):
那條線導致了這個問題。
VideoCapture 物件是在定義類及其方法時構造的。
你可能不想那樣。
使用capture=None在引數串列中,并在身體的__init__,你應該檢查if capture is None: capture = cv2.VideoCapture...
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/382336.html
上一篇:使用函式作為卷積核
