How Can I Access A Separate Camera Class Dynamically In Python With Kivy (without Pre-initialising Camera)
I have written a camera access class using python+kivy (kivycamera.py) and it is working. kivycamera.py # from kivymd.app import MDApp from kivy.uix.image import Image from kivy.gr
Solution 1:
Your KivyCamera
extends Image
, but you are using the KivyCamera
as a widget container. Also, in your build()
method, you are creating a layout
, but not doing anything with it. I suggest modifying KivyCamera
definition to change its base class to some Layout
(I chose RelativeLayout
) and to add the layout
as a child. Here is a modified version of your code that does this:
from kivymd.app import MDApp
from kivycamera import KivyCamera
class DemoApp(MDApp):
def build(self):
self.camera = KivyCamera()
self.camera.build()
print(self.camera)
return self.camera
if __name__ == '__main__':
DemoApp().run()
and kivycamera.py:
# from kivymd.app import MDApp
from kivy.uix.image import Image
from kivy.graphics.texture import Texture
from kivy.clock import Clock
import cv2
from kivy.uix.relativelayout import RelativeLayout
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.button import MDFillRoundFlatButton
import time
# class KivyCamera(MDApp):
class KivyCamera(RelativeLayout): # make this a container
def build(self):
layout = MDBoxLayout(orientation='vertical', spacing=10)
self.image = Image()
layout.add_widget(self.image)
self.start_camera_button = MDFillRoundFlatButton(
text="START CAMERA",
pos_hint={'center_x': 0.5, 'center_y': 0.5},
size_hint=(0.4, None),
# size=("100dp", "100dp")
)
self.start_camera_button.bind(on_press=self.start_camera)
layout.add_widget(self.start_camera_button)
self.save_img_button = MDFillRoundFlatButton(
text="TAKE PICTURE",
pos_hint={'center_x': 0.5, 'center_y': 0.5},
size_hint=(0.4, None),
# size=("100dp", "100dp")
)
self.save_img_button.bind(on_press=self.take_picture)
layout.add_widget(self.save_img_button)
self.add_widget(layout) # add the layout to the GUI
# self.video = cv2.VideoCapture(0)
# Clock.schedule_interval(self.load_video, 1.0 / 30.0)
# return layout
# return self.image
def start_camera(self, *args):
self.video = cv2.VideoCapture(0)
Clock.schedule_interval(self.load_video, 1.0 / 30.0)
pass
def load_video(self, *args):
check, frame = self.video.read()
if check:
x, y, w, h = 200, 200, 250, 250
p, q, r, s = 220, 220, 210, 210
frame = cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3)
frame = cv2.rectangle(frame, (p, q), (p + r, q + s), (255, 0, 0), 3)
self.image_frame = frame
buffer = cv2.flip(frame, 0).tobytes()
image_texture = Texture.create(size=(frame.shape[1], frame.shape[0]), colorfmt="bgr")
image_texture.blit_buffer(buffer, colorfmt="bgr", bufferfmt="ubyte")
self.image.texture = image_texture
def take_picture(self, *args):
timestr = time.strftime("%Y%m%d_%H%M%S")
cv2.imwrite("IMG_{}.png".format(timestr), self.image_frame)
cv2.imshow("Hi", self.image_frame)
# KivyCamera().run()
There are several other simplifications that you could make. For example, you could eliminate the build()
method by changing it to an __init__()
method (must add a super(KivyCamera, self).__init__()
call), and eliminate the layout
variable by making KivyCamera
extend MDBoxLayout
.
Post a Comment for "How Can I Access A Separate Camera Class Dynamically In Python With Kivy (without Pre-initialising Camera)"