Chaquopy集成OpenCV无法通过cv2.VideoCapture打开URL链接
问题说明
本地运行正常的目标识别Python代码,通过Chaquopy集成到Android应用后无法运行,故障触发点是Python代码中打开摄像头流的语句 cap = cv2.VideoCapture(url) 在Android设备上执行失效。
相关代码
MainActivity.java
import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; import com.chaquo.python.PyObject; import com.chaquo.python.Python; import com.chaquo.python.android.AndroidPlatform; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView = findViewById(R.id.textview); if(!Python.isStarted()) Python.start(new AndroidPlatform(this)); Python py = Python.getInstance(); PyObject pyobj = py.getModule("main"); textView.setText(pyobj.callAttr("main").toString()); } }
main.py
import cv2 import numpy as np def main(): thres = 0.50 nms_threshold = 0.20 cap = cv2.VideoCapture('http://192.168.137.10:8081/') classNames= [] classFile = 'coco.names' with open(classFile,'rt') as f: classNames=[line.rstrip() for line in f] configPath = 'ssd_mobilenet_v3_large_coco_2020_01_14.pbtxt' weightsPath = 'frozen_inference_graph.pb' net = cv2.dnn_DetectionModel(weightsPath,configPath) net.setInputSize(300,300) net.setInputScale(1.0/ 127.5) net.setInputMean((127.5, 127.5, 127.5)) net.setInputSwapRB(True) success,img = cap.read() classIds, confs, bbox = net.detect(img,confThreshold=thres) bbox = list(bbox) confs = list(np.array(confs).reshape(1, -1)[0]) confs = list(map(float, confs)) indices = cv2.dnn.NMSBoxes(bbox,confs,thres,nms_threshold) for i in indices: i=i[0] return (classNames[classIds[i][0] - 1])
Logcat报错日志
2022-06-07 22:19:43.083 26043-26043/com.example.thirdeye E/cv::error(): OpenCV(4.5.1) Error: Bad argument (CAP_IMAGES: can't find starting number (in the name of file): http://192.168.137.10:8081/) in icvExtractPattern, file /home/smith/git/chaquo/python/server/pypi/packages/opencv-contrib-python/build/4.5.1.48/cp38-cp38-android_16_armeabi_v7a/src/opencv/modules/videoio/src/cap_images.cpp, line 253 2022-06-07 22:19:43.088 26043-26043/com.example.thirdeye E/OpenCV/4.5.1: [ERROR:0] global /home/smith/git/chaquo/python/server/pypi/packages/opencv-contrib-python/build/4.5.1.48/cp38-cp38-android_16_armeabi_v7a/src/opencv/modules/videoio/src/cap.cpp (142) open VIDEOIO(CV_IMAGES): raised OpenCV exception: OpenCV(4.5.1) /home/smith/git/chaquo/python/server/pypi/packages/opencv-contrib-python/build/4.5.1.48/cp38-cp38-android_16_armeabi_v7a/src/opencv/modules/videoio/src/cap_images.cpp:253: error: (-5:Bad argument) CAP_IMAGES: can't find starting number (in the name of file): http://192.168.137.10:8081/ in function 'icvExtractPattern' 2022-06-07 22:19:43.089 26043-26043/com.example.thirdeye A/libc: Fatal signal 7 (SIGBUS), code 1 (BUS_ADRALN), fault addr 0xdc40d601 in tid 26043 (xample.thirdeye), pid 26043 (xample.thirdeye)
故障原因
从报错日志可以直接定位根因:Chaquopy源内置的OpenCV预编译包没有集成FFmpeg依赖,不支持HTTP、RTSP这类网络视频流的解析读取。OpenCV找不到匹配网络流的处理后端时,会自动回退到本地图片序列读取模式(CAP_IMAGES),尝试把传入的URL当成本地带数字序号的图片文件名解析,自然抛出“找不到文件名起始数字”的参数错误,后续空帧传入检测逻辑还触发了内存对齐异常,直接导致应用崩溃。
解决方法
- 优先选实现成本最低的方案:不在Python层直接调用OpenCV拉取网络流,改用Android原生的网络请求/摄像头API获取视频帧,将帧数据通过Chaquopy的接口传给Python层,只保留Python里的目标检测推理逻辑,绕开OpenCV在Android端的视频流读取能力缺陷。
- 如果必须在Python层直接读流:自行交叉编译开启FFmpeg支持的对应CPU架构OpenCV Android二进制包,替换Chaquopy默认安装的无FFmpeg版本的opencv-python包,注意需要匹配Chaquopy使用的Python版本和目标设备的ABI架构。
- 补全容错逻辑:现有代码在
cap.read()后没有判断success返回值,一旦帧读取失败,img为None时传入检测接口必然触发崩溃,无论选哪种方案都要加状态判断,读取失败直接返回错误,不要继续执行后续检测逻辑。
内容的提问来源于stack exchange,提问作者Sakthi Vinnavan
相关产品推荐
相关产品推荐

