Kivy でアプリを作成-カメラ映像の表示【Python】

Kivy
スポンサーリンク
スポンサーリンク

はじめに

前回はファイルダイアログの作成方法について説明しました。

今回は、カメラ映像を表示する方法について説明します。

前提条件

前提条件は以下の通りです。

  • Python がインストールされている
  • Windows11 (Ubuntuでも可?)
  • Kivy[full] がインストールされている

カメラ映像を表示するプログラム

カメラ映像を表示するには、Image.texture クラス を使用します。
そして、カメラ映像を更新する際には Clock クラスを使用します。

Image クラスの説明はこちら
Texture クラスの説明はこちら
Clock クラスの説明はこちら

こちらにすべてが書いてあります。
Python KivyでWebカメラの映像を表示・撮影する【GUI】

画面に描画

まずは Image にグレースケールの描画を行います。

kv ファイル

<MainWidget>:
    orientation: 'vertical'
    padding: [20, 20]
    Image:
        id: camera_preview
    Button:
        text: 'setup'
        on_release: root.setup()
        size_hint: 1.0, 0.1
        font_size: 25

py ファイル

from kivy.app import App
from kivy.lang.builder import Builder
Builder.load_file('test_6.kv')

from kivy.core.window import Window
Window.size = (960, 540)

from kivy.uix.boxlayout import BoxLayout

from kivy.graphics.texture import Texture
from kivy.clock import Clock

import cv2

class MainWidget(BoxLayout):
    def setup(self):
        self.w, self.h = 640, 480
        size = self.h * self.w * 3
        buf = [int(x * 255 / size) for x in range(size)]
        buf = bytes(buf)
        texture = Texture.create(size=(self.w, self.h), colorfmt="bgr")
        texture.blit_buffer(buf, colorfmt="bgr", bufferfmt="ubyte")
        self.capture_image = self.ids.camera_preview
        self.capture_image.texture = texture

class MyApp(App):
    def build(self):
        return MainWidget()

if __name__ == '__main__':
    MyApp().run()

上記を実行すると、以下のように画像が表示されます。

setup ボタンをクリックすると、グレースケールの画像が表示されます。

重要な部分は、以下の4行です。

texture = Texture.create(size=(self.w, self.h), colorfmt="bgr")
texture.blit_buffer(buf, colorfmt="bgr", bufferfmt="ubyte")
self.capture_image = self.ids.camera_preview
self.capture_image.texture = texture

まずは空の Texture を指定サイズで作成します。その後、グレースケール画像を texture へ貼付します。
完成した texture を image クラスの texture へ挿入します。

ここまでできれば、あとは opencv で読み込んだ画像を byte 変換するだけです。

カメラ映像の描画

続いて、カメラ映像を描画していきます。
先ほどの setup 関数は、__init__ として扱います。

kv ファイル

<MainWidget>:
    orientation: 'vertical'
    padding: [20, 20]
    Image:
        id: camera_preview
    Button:
        text: 'start capture'
        on_release: root.start_capture()
        size_hint: 1.0, 0.1
        font_size: 25

py ファイル

from kivy.app import App
from kivy.lang.builder import Builder
Builder.load_file('test_6.kv')

from kivy.core.window import Window
Window.size = (960, 540)

from kivy.uix.boxlayout import BoxLayout

from kivy.graphics.texture import Texture
from kivy.clock import Clock

import cv2

class MainWidget(BoxLayout):
    def __init__(self, **kwargs):
        super(BoxLayout, self).__init__(**kwargs)
        self.w, self.h = 640, 480
        size = self.h * self.w * 3
        buf = [int(x * 255 / size) for x in range(size)]
        buf = bytes(buf)
        texture = Texture.create(size=(self.w, self.h), colorfmt="bgr")
        texture.blit_buffer(buf, colorfmt="bgr", bufferfmt="ubyte")
        self.capture_image = self.ids.camera_preview
        self.capture_image.texture = texture

    def start_capture(self):
        self.capture_image = self.ids.camera_preview
        self.cap = cv2.VideoCapture(1, cv2.CAP_DSHOW)
        self.clock_event1 = Clock.schedule_interval(self.update, 1.0/30.0)

    # Normal Capture Event
    def update(self, _):
        _, self.frame = self.cap.read()
        buf = cv2.flip(self.frame, 0).tobytes()
        texture = Texture.create(size=(self.frame.shape[1], self.frame.shape[0]), colorfmt="bgr")
        texture.blit_buffer(buf, colorfmt="bgr", bufferfmt="ubyte")
        self.capture_image.texture = texture

class MyApp(App):
    def build(self):
        return MainWidget()

if __name__ == '__main__':
    MyApp().run()

__init__ 実行する際には、super を使用して継承する必要があります。

上記を実行すると、以下のような動作になります。

start capture ボタンをクリックしてください。

映像が表示されました。

おわりに

今回はカメラ映像を Kivy で表示する方法について説明しました。

次回は、マウスイベントをまとめていきます。

コメント

タイトルとURLをコピーしました