无法在 Android 手机中使用 cv2.VideoCapture(0) 打开相机
Posted
技术标签:
【中文标题】无法在 Android 手机中使用 cv2.VideoCapture(0) 打开相机【英文标题】:Cannot open camera using cv2.VideoCapture(0) in android phones 【发布时间】:2021-11-08 10:39:14 【问题描述】:我需要使用 OpenCV VideoCapture() 方法和 python kivy 框架创建一个 android 应用程序。请注意,我不会使用 Kivy 上可用的 KivyCamera,因为我需要在视频帧的顶部绘制一些形状。我从 (Is there a way to integrate the imshow() function of OpenCV into kivy or kv file in python) 中找到了一个示例。感谢您的回答。 但是在 android 手机中安装 APK 后仍然无法正常工作,应用程序启动但相机部分显示白色背景屏幕。这在 Windows PC 中运行良好。我试过 videocapture(-1)、videocapture(0)、videocapture(1) 都没有用。
如果有人知道答案,请帮助我。
main.py
import threading
from functools import partial
import cv2
from kivy.app import App
from kivy.clock import Clock
from kivy.graphics.texture import Texture
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
class MainScreen(Screen):
pass
class Manager(ScreenManager):
pass
Builder.load_string('''
<MainScreen>:
name: "Test"
FloatLayout:
Label:
text: "Webcam from OpenCV?"
pos_hint: "x":0.0, "y":0.8
size_hint: 1.0, 0.2
Image:
# this is where the video will show
# the id allows easy access
id: vid
size_hint: 1, 0.6
allow_stretch: True # allow the video image to be scaled
keep_ratio: True # keep the aspect ratio so people don't look squashed
pos_hint: 'center_x':0.5, 'top':0.8
Button:
text: 'Stop Video'
pos_hint: "x":0.0, "y":0.0
size_hint: 1.0, 0.2
font_size: 50
on_release: app.stop_vid()
''')
class Main(App):
def build(self):
# start the camera access code on a separate thread
# if this was done on the main thread, GUI would stop
# daemon=True means kill this thread when app stops
threading.Thread(target=self.doit, daemon=True).start()
sm = ScreenManager()
self.main_screen = MainScreen()
sm.add_widget(self.main_screen)
return sm
def doit(self):
# this code is run in a separate thread
self.do_vid = True # flag to stop loop
# make a window for use by cv2
# flags allow resizing without regard to aspect ratio
cv2.namedWindow('Hidden', cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO)
# resize the window to (0,0) to make it invisible
cv2.resizeWindow('Hidden', 0, 0)
# cv2.resizeWindow('Hidden', 200, 200)
cam = cv2.VideoCapture(0)
# start processing loop
while (self.do_vid):
ret, frame = cam.read()
# ...
# more code
# ...
# send this frame to the kivy Image Widget
# Must use Clock.schedule_once to get this bit of code
# to run back on the main thread (required for GUI operations)
# the partial function just says to call the specified method with the provided argument (Clock adds a time argument)
Clock.schedule_once(partial(self.display_frame, frame))
cv2.imshow('Hidden', frame)
cv2.waitKey(1)
cam.release()
cv2.destroyAllWindows()
def stop_vid(self):
# stop the video capture loop
self.do_vid = False
def display_frame(self, frame, dt):
# display the current video frame in the kivy Image widget
# create a Texture the correct size and format for the frame
texture = Texture.create(size=(frame.shape[1], frame.shape[0]), colorfmt='bgr')
# copy the frame data into the texture
texture.blit_buffer(frame.tobytes(order=None), colorfmt='bgr', bufferfmt='ubyte')
# flip the texture (otherwise the video is upside down
texture.flip_vertical()
texture.flip_horizontal()
# actually put the texture in the kivy Image widget
self.main_screen.ids.vid.texture = texture
if __name__ == '__main__':
Main().run()
buildozer.spec
[app]
title = OpenCVCam
package.name = opencvcam
package.domain = org.test
source.dir = .
source.include_exts = py,png,jpg,kv,atlas,xml
version = 0.1
requirements = python3,kivy,opencv,numpy,pyjnius,plyer,requests,urllib3,chardet,idna,pip,Image,PIL
orientation = portrait
# Android specific
fullscreen = 0
android.permissions = INTERNET, ACCESS_FINE_LOCATION, WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE, CAMERA
android.arch = armeabi-v7a
[buildozer]
log_level = 2
warn_on_root = 1
【问题讨论】:
可能相关:kivy camera application with opencv in android shows black screen 如果已经看到,请edit 您的帖子,其中包含无效的内容和相关的错误日志消息。 kivy-camera-application-with-opencv-in-android-shows-black-screen 不是我正在寻找的解决方案,因为它不使用 cv2.videoCapture 方法。我只想使用 cv2.VideoCaptute(0) 方法。 Android不支持吗? 您能解释一下为什么需要使用 cv2.VideoCaptute() 方法吗? 我需要在视频流的顶部添加一些覆盖(形状),并且我正在尝试在视频流顶部使用 opencv 进行一些边缘检测。 ANDROID中使用的cv2.videoCapture方法有什么问题吗?因为它在 Windows 10 上完美运行。我只需要为 windows 和 android 维护一个代码库,而不是编写特定于平台的实现 不需要使用 cv2.videoCapture() 。在解决方案 1 中,您可以在 frame_to_screen() 函数下看到 cv2.putText() 方法。只需用您想要的任何内容替换它,它应该可以工作。链接:***.com/questions/61122285/… 【参考方案1】:如果您想将 OpenCV 与 android 相机一起使用,您必须将 kivy 配方中的 OpenCV 更新到 4.5.2 版本,并在 Bulldozer.spec 中指定 NDK API 级别为 24 或更高。 https://github.com/opencv/opencv/pull/19597
【讨论】:
【参考方案2】:尝试使用
视频捕捉(0,cv2.CAP_ANDROID) 要么 VideoCapture(1,cv2.CAP_ANDROID)
【讨论】:
我尝试了这两种方法,但都没有成功。无论如何感谢您的回答。以上是关于无法在 Android 手机中使用 cv2.VideoCapture(0) 打开相机的主要内容,如果未能解决你的问题,请参考以下文章
红米停在android,红米手机在Android开发中无法获取data/data中数据的问题