Skip to content Skip to sidebar Skip to footer

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)"