admin管理员组文章数量:1332339
I’m building an Android APK using Buildozer on Ubuntu (running in a virtual machine) for a personal project, using Python and Kivy for both the backend and frontend. However, my app crashes immediately upon launch when OpenCV is included. The crash logs show an ImportError related to a missing configuration file (config.py) in OpenCV. This issue occurs regardless of whether I use the opencv-contrib-python-headless or the regular opencv package.
requirements.txt:
appdirs==1.4.4
build==1.2.2.post1
buildozer==1.5.0
certifi==2024.8.30
charset-normalizer==3.4.0
colorama==0.4.6
Cython==0.29.33
distlib==0.3.9
docutils==0.21.2
filelock==3.16.1
idna==3.10
Jinja2==3.1.4
Kivy==2.3.0
Kivy-Garden==0.1.5
MarkupSafe==3.0.2
numpy==2.1.3
opencv-contrib-python-headless==4.10.0.84
packaging==24.2
pexpect==4.9.0
pillow==10.4.0
platformdirs==4.3.6
plyer==2.1.0
ptyprocess==0.7.0
Pygments==2.18.0
pyproject_hooks==1.2.0
requests==2.32.3
sh==1.14.3
toml==0.10.2
urllib3==2.2.3
virtualenv==20.27.1
LogCat:
2024-11-20 13:46:01.530 6584-6606 python .test.myapp I ImportError: OpenCV loader: missing configuration file:` \['config.py'\].` Check OpenCV installation.
2024-11-20 13:46:01.530 6584-6606 python .test.myapp I Python for android ended.
2024-11-20 13:46:01.578 6584-6608 libc .test.myapp A FORTIFY: pthread_mutex_lock called on a destroyed mutex (0x7cf271402ab8)
2024-11-20 13:46:01.578 6584-6609 libc .test.myapp A FORTIFY: pthread_mutex_lock called on a destroyed mutex (0x7cf271402ab8)
2024-11-20 13:46:01.578 6584-6608 libc .test.myapp A Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 6608 (hwuiTask0), pid 6584 (SDLActivity)
2024-11-20 13:46:01.698 597-970 WindowManager system_server I WIN DEATH: Window{c44b65 u0 .test.myapp/.kivy.android.PythonActivity}
2024-11-20 13:46:01.699 597-1113 ActivityManager system_server I Process .test.myapp (pid 6584) has died: fg TOP
python file imports and relevant code:
import os #Python module for operating system interactions
import numpy as np #Used for handling image data from OpenCV's numpy arrays
import cv2
from kivy.config import Config
Config.set('kivy', 'camera', 'opencv')
from kivy.app import App
from kivy.lang import Builder #building files correctly
from kivy.uix.button import Button #for the buttons
from kivy.uix.boxlayout import BoxLayout # for the layout (there are different types of layouts in kivy this is just the most basic one)
from kivy.uix.floatlayout import FloatLayout # for non dynamic layout so the buttons dont move for camera page
from kivy.uix.screenmanager import ScreenManager, Screen #for the screen manager to track which screen is being shown
from kivy.uix.label import Label # for the label like headers
from kivy.uix.widget import Widget # adds widget for each of the classes
from kivy.uix.dropdown import DropDown # adds dropdown widgets
from kivy.graphics import Color, Ellipse, Rectangle # adds color to the circle
from kivy.graphics.texture import Texture #used for OpenCV image data
from kivy.core.window import Window # Sets the background color for app
from kivy.uix.popup import Popup #For dialog window for popups when needed
from kivy.uix.image import Image #Widgets for displaying selected images
from kivy.properties import NumericProperty, StringProperty # control text values
from kivy.utils import get_color_from_hex # color translating from hex to rgba
from plyer import filechooser #From plyer library for image selection
from PIL import Image as PILImage #Python Image Library
from PIL import ImageDraw, ImageFont #Python Image Library
from kivy.clock import Clock #Used to capture frames form OpenCV Camera
class CameraPage(Screen):`
def __init__(self, **kwargs):
super(CameraPage, self).__init__(**kwargs)
self.cap = None # OpenCV VideoCapture
self.image_cache = None
self.frame_event = None
self.current_frame = None # Captures the current frame
# Start OpenCV camera when user is in the camera page
def on_enter(self, *args):
self.start_opencv_camera()
# Stop OpenCV camera when user exits the camera page
def on_leave(self, *args):
if self.cap:
self.cap.release() # Release the camera
cv2.destroyAllWindows()
print("Camera has been released.")
if self.frame_event:
self.frame_event.cancel() # Cancel frame update
# Start OpenCV camera
def start_opencv_camera(self):
self.cap = cv2.VideoCapture(0) # Useing camera index 0 for default camera
if not self.cap.isOpened():
print("Error: Could not open OpenCV camera")
else:
print("OpenCV camera started.")
# Schedule the update of camera frames by 30 FPS
self.frame_event = Clock.schedule_interval(self.update_camera_feed, 1.0 / 30.0)
# Update the Image widget with the camera feed
def update_camera_feed(self, dt):
if self.cap:
ret, frame = self.cap.read()
if ret:
self.current_frame = frame # Store the current frame
# Convert BGR frame to RGB
buf = cv2.flip(frame, 0).tostring()
texture = Texture.create(size=(frame.shape[1], frame.shape[0]), colorfmt='bgr')
texture.blit_buffer(buf, colorfmt='bgr', bufferfmt='ubyte')
self.ids.camera_feed.texture = texture
# Capture image using the current frame from OpenCV
def capture_opencv_image(self):
if self.current_frame is not None:
# Convert OpenCV frame (BGR) to PIL Image (RGB)
pil_image = PILImage.fromarray(cv2.cvtColor(self.current_frame, cv2.COLOR_BGR2RGB))
# Save to cache directory
cache_dir = './image_cache'
if not os.path.exists(cache_dir):
os.mkdir(cache_dir)
cached_image_path = os.path.join(cache_dir, 'captured_image.png')
pil_image.save(cached_image_path)
self.image_cache = cached_image_path
print(f"Image captured and cached at: {cached_image_path}")
else:
print("Error: No frame available to capture")
# Function that opens gallery works for windows and should work for android
def open_gallery(self, *args):
# Opens the file chooser to select images
filechooser.open_file(on_selection=self.display_image)
# Display the selected image in a popup
def display_image(self, selection):
if selection:
# Cache for the selected image
self.image_cache = selection[0]
# Create/open popup
image_popup = ImagePopup()
image_popup.ids.img.source = self.image_cache
image_popup.open()
# Cache the selected image
def cache_image(self, instance):
# Checks if cache location exists
if self.image_cache:
cache_dir = './image_cache' # Cache directory
if not os.path.exists(cache_dir):
os.mkdir(cache_dir) # Create cache location if does not existing
# Select a location/path for the cached image
cached_image_path = os.path.join(cache_dir, 'cached_image.png')
try:
with open(self.image_cache, 'rb') as source_file:
with open(cached_image_path, 'wb') as dest_file:
dest_file.write(source_file.read())
print(f"Image cached at: {cached_image_path}")
except Exception as e:
print(f"Error caching the image: {e}")
else:
print("Error: No image selected for caching")
buildozer.spec:
`\[app\]`
# (str) Title of your application
title = My Application
# (str) Package name
package.name = myapp
# (str) Package domain (needed for android/ios packaging)
package.domain = .test
# (str) Source code where the main.py live
source.dir = .
# (list) Source files to include (let empty to include all the files)
source.include_exts = py,png,jpg,kv,atlas
# (list) List of inclusions using pattern matching
#source.include_patterns = assets/*,images/*.png
# (list) Source files to exclude (let empty to not exclude anything)
#source.exclude_exts = spec
# (list) List of directory to exclude (let empty to not exclude anything)
#source.exclude_dirs = tests, bin, venv
# (list) List of exclusions using pattern matching
# Do not prefix with './'
# If you have videos or other assets in a directory like "assets" or "videos", add them here
source.include_patterns = assets/*,videos/*.mp4
# (str) Application versioning (method 1)
version = 0.1
# (str) Application versioning (method 2)
# version.regex = __version__ = \['"\](.\*)\['"\]
# version.filename = %(source.dir)s/main.py
# (list) Application requirements
# comma separated e.g. requirements = sqlite3,kivy
requirements = kivy, plyer, numpy, pillow, opencv-contrib-python-headless, requests
# (str) Custom source folders for requirements
# Sets custom source for any requirements with recipes
# requirements.source.kivy = ../../kivy
# (str) Presplash of the application
#presplash.filename = %(source.dir)s/data/presplash.png
# (str) Icon of the application
#icon.filename = %(source.dir)s/data/icon.png
# (list) Supported orientations
# Valid options are: landscape, portrait, portrait-reverse or landscape-reverse
orientation = portrait
# (list) List of service to declare
#services = NAME:ENTRYPOINT_TO_PY,NAME2:ENTRYPOINT2_TO_PY
#
# OSX Specific
#
#
# author = © Copyright Info
# change the major version of python used by the app
osx.python_version = 3
# Kivy version to use
osx.kivy_version = 1.9.1
#
# Android specific
#
# (bool) Indicate if the application should be fullscreen or not
fullscreen = 0
# (string) Presplash background color (for android toolchain)
# Supported formats are: #RRGGBB #AARRGGBB or one of the following names:
# red, blue, green, black, white, gray, cyan, magenta, yellow, lightgray,
# darkgray, grey, lightgrey, darkgrey, aqua, fuchsia, lime, maroon, navy,
# olive, purple, silver, teal.
#android.presplash_color = #FFFFFF
# (string) Presplash animation using Lottie format.
# see / for examples and /lottie/
# for general documentation.
# Lottie files can be created using various tools, like Adobe After Effect or Synfig.
#android.presplash_lottie = "path/to/lottie/file.json"
# (str) Adaptive icon of the application (used if Android API level is 26+ at runtime)
#icon.adaptive_foreground.filename = %(source.dir)s/data/icon_fg.png
#icon.adaptive_background.filename = %(source.dir)s/data/icon_bg.png
# (list) Permissions
# (See for all the supported syntaxes and properties)
android.permissions = CAMERA, READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE #(name=android.permission.WRITE_EXTERNAL_STORAGE;maxSdkVersion=18)
# (list) features (adds uses-feature -tags to manifest)
I’ve experimented with different OpenCV packages, such as opencv-python, opencv-headless, and opencv-contrib-python-headless. My goal is to eventually implement live photo capture functionality, similar to a barcode scanner, in my app. However, no matter which OpenCV package I use, the app crashes on launch with the same error related to missing configuration files for OpenCV.
The only thing that allows the app to run without crashing is commenting out the camera and image cache functions in my code, and removing the opencv dependencies from the buildozer.spec file. After doing this, the app launches and works as expected, except for the camera-related features.
版权声明:本文标题:python - APK built with Buildozer crashes on launch due to OpenCV loader error - How to resolve? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742329869a2454474.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论