'How can i speed up camera frame rate on display window in python/kivy?
I am trying to make an inventory app (qr/data matrix) where equipment can be added and organized using a QR/data matrix code. When i run the camera the frame rate seems fine but the moment i add any code to decode and extract qr/data matrix information, the frame rate drops badly. Also it seem like it takes more time to load the camera page too. is there a way that this can be solved? Please i am new to python and kivy and this is my first question here too. thank you.
This is the .kv file code
#: import NoTransition kivy.uix.screenmanager.NoTransition
MDFloatLayout:
md_bg_color: rgba(1, 1, 1, 1)
ScreenManager:
id: screen_manager
transition: NoTransition()
MDScreen:
name: "homepage"
MDFloatingActionButton:
icon: 'data-matrix-scan'
md_bg_color: rgba(206, 206, 209, 255)
pos_hint: {"right": .96,"center_y": .17}
user_font_size: "27sp"
on_release:
screen_manager.current = "scan"
app.scan()
MDScreen:
name: "scan"
on_enter:
app.scan_code()
#app.read_code()
MDFloatLayout:
orientation: 'vertical'
md_bg_color: rgba(241, 241, 243, 255)
MDIconButton:
icon: 'chevron-left'
pos_hint: {"center_y": .95}
on_release:
app.release_cam()
screen_manager.current = "homepage"
MDLabel:
text: 'Add Item'
pos_hint: {"center_x": .9, "center_y": .95}
MDBoxLayout:
orientation: 'vertical'
md_bg_color: rgba(241, 241, 243, 255)
pos_hint: {"center_x": .5,"center_y": .4}
spacing: 15
# Camera Widget
MDBoxLayout:
id: cam_box
md_bg_color: rgba(206, 206, 209, 255)
#size_hint: .77, .41
size_hint: 1, None
height: '230dp'
#width: '240dp'
pos_hint: {"center_x": .5}
# Space for ListView
MDBoxLayout:
pos_hint: {"center_x": .5}
md_bg_color: rgba(106, 206, 209, 255)
size_hint: 1, .4
Button:
text: "ADD ITEMS"
size_hint: .77, .08
pos_hint: {"center_x": .5,"center_y": .07}
background_color: 0, 0, 0, 0
font_name: "MPoppins"
font_size: "18sp"
color: 1, 1, 1, 1
canvas.before:
Color:
rgb: rgba(255, 170, 23, 255)
RoundedRectangle:
size: self.size
pos: self.pos
radius: [12]
MDScreen:
name: "saved"
MDLabel:
text: "Saved"
halign: "center"
font_name: "BPoppins"
MDScreen:
name: "create"
MDLabel:
text: "Create"
halign: "center"
font_name: "BPoppins"
MDScreen:
name: "account"
MDLabel:
text: "Account"
halign: "center"
font_name: "BPoppins"
MDScreen:
name: "settings"
MDLabel:
text: "Settings"
halign: "center"
font_name: "BPoppins"
NavBar:
size_hint: 1, .1
pos_hint: {"center_x": .5, "y": 0}
elevation: 10
md_bg_color: 1, 1, 1, 1
MDGridLayout
cols: 5
size_hint_x: 1
spacing: 10
pos_hint: {"center_x": .5 , "center_y": .5}
#md_bg_color: rgba(71,92,119,255)
MDBoxLayout:
orientation: 'vertical'
spacing: 1
padding: 0, 0, 0, 10
pos_hint: {"center_x": .5 , "center_y": .5}
#md_bg_color: rgba(105, 222, 222, 255)
MDIconButton:
id: nav_icon1
icon: "home"
ripple_scale: 0
user_font_size: "30sp"
theme_text_color: "Custom"
text_color: rgba(71,92,119,255)
pos_hint: {"center_x": .5 , "center_y": .5}
on_release:
screen_manager.current = "homepage"
app.change_color(self)
MDLabel:
text: "Home"
font_name: "MPoppins"
font_size: 10
halign: 'center'
Widget:
height: 4
MDBoxLayout:
orientation: 'vertical'
spacing: 1
padding: 0, 0, 0, 10
pos_hint: {"center_x": .5 , "center_y": .5}
MDIconButton:
id: nav_icon2
icon: "download"
ripple_scale: 0
user_font_size: "30sp"
theme_text_color: "Custom"
text_color: rgba(222, 222, 222, 255)
pos_hint: {"center_x": .5 , "center_y": .5}
on_release:
screen_manager.current = "saved"
app.change_color(self)
MDLabel:
text: "Download"
font_name: "MPoppins"
font_size: 10
halign: 'center'
Widget:
height: 4
MDBoxLayout:
orientation: 'vertical'
spacing: 1
padding: 0, 0, 0, 10
pos_hint: {"center_x": .5 , "center_y": .5}
MDIconButton:
id: nav_icon3
icon: "plus-circle-outline"
ripple_scale: 0
user_font_size: "30sp"
theme_text_color: "Custom"
text_color: rgba(222, 222, 222, 255)
pos_hint: {"center_x": .5 , "center_y": .5}
on_release:
screen_manager.current = "create"
app.change_color(self)
MDLabel:
text: "Create"
font_name: "MPoppins"
font_size: 10
halign: 'center'
Widget:
height: 4
MDBoxLayout:
orientation: 'vertical'
spacing: 1
padding: 0, 0, 0, 10
pos_hint: {"center_x": .5 , "center_y": .5}
MDIconButton:
id: nav_icon4
icon: "account"
ripple_scale: 0
user_font_size: "30sp"
theme_text_color: "Custom"
text_color: rgba(222, 222, 222, 255)
pos_hint: {"center_x": .5 , "center_y": .5}
on_release:
screen_manager.current = "account"
app.change_color(self)
MDLabel:
text: "Account"
font_name: "MPoppins"
font_size: 10
halign: 'center'
Widget:
height: 4
MDBoxLayout:
orientation: 'vertical'
spacing: 1
padding: 0, 0, 0, 10
pos_hint: {"center_x": .5 , "center_y": .5}
MDIconButton:
id: nav_icon5
icon: "cog"
ripple_scale: 0
user_font_size: "27sp"
theme_text_color: "Custom"
text_color: rgba(222, 222, 222, 255)
pos_hint: {"center_x": .5 , "center_y": .5}
on_release:
screen_manager.current = "settings"
app.change_color(self)
MDLabel:
text: "Settings"
font_name: "MPoppins"
font_size: 10
halign: 'center'
Widget:
height: 4
This is the .py file with the decoding code (under load_video())
from kivy.core.image import Texture
from kivy.utils import rgba
from kivymd.app import MDApp
from kivy.core.text import LabelBase
from kivy.core.window import Window
from kivymd.uix.behaviors import FakeRectangularElevationBehavior
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.floatlayout import MDFloatLayout
from kivy.uix.image import Image
from kivy.clock import Clock
import cv2
from pylibdmtx.pylibdmtx import decode
import time
import winsound
from datetime import datetime
Window.size = (310, 580)
class CamBox(FakeRectangularElevationBehavior, MDFloatLayout):
pass
class NavBar(FakeRectangularElevationBehavior, MDFloatLayout):
pass
class Camera(MDApp):
def scan(self):
self.image = Image()
self.root.ids.cam_box.add_widget(self.image)
self.capture = cv2.VideoCapture(0)
Clock.schedule_interval(self.load_video, 1.0 / 30.0)
def load_video(self, *args):
ret, frame = self.capture.read()
self.image_frame = frame
# Data Matrix Decoding Part
dm_code = decode(self.image_frame)
for code in dm_code:
serial = str(code.data.decode('utf-8'))
print(serial)
#while dm_code:
# print(dm_code)
# Frame Initialize
buffer = cv2.flip(frame, 0).tobytes()
texture = Texture.create(size=(frame.shape[1], frame.shape[0]), colorfmt='bgr')
texture.blit_buffer(buffer, colorfmt='bgr', bufferfmt='ubyte')
self.image.texture = texture
#def read_code(self, *args):
def release_cam(self):
#self.capture.release()
self.root.ids.cam_box.remove_widget(self.image)
def scan_code(self):
pass
def change_color(self, instance):
if instance in self.root.ids.values():
current_id = list(self.root.ids.keys())[list(self.root.ids.values()).index(instance)]
for i in range(5):
if f"nav_icon{i + 1}" == current_id:
self.root.ids[f"nav_icon{i + 1}"].text_color = rgba(71, 92, 119, 255)
else:
self.root.ids[f"nav_icon{i + 1}"].text_color = rgba(222, 222, 222, 255)
LabelBase.register(name='BPoppins', fn_regular="C:\\Users\dogig\\PycharmProjects\\Wallpaper App\\Poppins-Bold.otf")
LabelBase.register(name='MPoppins', fn_regular="C:\\Users\dogig\\PycharmProjects\\Wallpaper App\\Poppins-Medium.otf")
LabelBase.register(name='LPoppins', fn_regular="C:\\Users\dogig\\PycharmProjects\\Wallpaper App\\Poppins-Light.otf")
LabelBase.register(name='TPoppins', fn_regular="C:\\Users\dogig\\PycharmProjects\\Wallpaper App\\Poppins-Thin.otf")
Camera().run()
This is the .py file without the decoding code
from kivy.core.image import Texture
from kivy.utils import rgba
from kivymd.app import MDApp
from kivy.core.text import LabelBase
from kivy.core.window import Window
from kivymd.uix.behaviors import FakeRectangularElevationBehavior
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.floatlayout import MDFloatLayout
from kivy.uix.image import Image
from kivy.clock import Clock
import cv2
from pylibdmtx.pylibdmtx import decode
import time
import winsound
from datetime import datetime
Window.size = (310, 580)
class CamBox(FakeRectangularElevationBehavior, MDFloatLayout):
pass
class NavBar(FakeRectangularElevationBehavior, MDFloatLayout):
pass
class Camera(MDApp):
def scan(self):
self.image = Image()
self.root.ids.cam_box.add_widget(self.image)
self.capture = cv2.VideoCapture(0)
Clock.schedule_interval(self.load_video, 1.0 / 30.0)
def load_video(self, *args):
ret, frame = self.capture.read()
self.image_frame = frame
# Frame Initialize
buffer = cv2.flip(frame, 0).tobytes()
texture = Texture.create(size=(frame.shape[1], frame.shape[0]), colorfmt='bgr')
texture.blit_buffer(buffer, colorfmt='bgr', bufferfmt='ubyte')
self.image.texture = texture
#def read_code(self, *args):
def release_cam(self):
#self.capture.release()
self.root.ids.cam_box.remove_widget(self.image)
def scan_code(self):
pass
def change_color(self, instance):
if instance in self.root.ids.values():
current_id = list(self.root.ids.keys())[list(self.root.ids.values()).index(instance)]
for i in range(5):
if f"nav_icon{i + 1}" == current_id:
self.root.ids[f"nav_icon{i + 1}"].text_color = rgba(71, 92, 119, 255)
else:
self.root.ids[f"nav_icon{i + 1}"].text_color = rgba(222, 222, 222, 255)
LabelBase.register(name='BPoppins', fn_regular="C:\\Users\dogig\\PycharmProjects\\Wallpaper App\\Poppins-Bold.otf")
LabelBase.register(name='MPoppins', fn_regular="C:\\Users\dogig\\PycharmProjects\\Wallpaper App\\Poppins-Medium.otf")
LabelBase.register(name='LPoppins', fn_regular="C:\\Users\dogig\\PycharmProjects\\Wallpaper App\\Poppins-Light.otf")
LabelBase.register(name='TPoppins', fn_regular="C:\\Users\dogig\\PycharmProjects\\Wallpaper App\\Poppins-Thin.otf")
Camera().run()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|